Skip to content
Snippets Groups Projects
Commit 24ecc20e authored by Ben Couturier's avatar Ben Couturier
Browse files

Merge branch 'LBCORE-1078' into 'master'

add option --path-to-project to lb-run

When invoked with `--path-to-project`, `lb-run` interprets the first argument
as a path to the top-level directory of a project, thus skipping the lookup.

Fixes LBCORE-1078

This is needed to make use of the new feature in merge request !31

See merge request !33
parents 0e27b99d 858d37c9
No related branches found
No related tags found
No related merge requests found
...@@ -24,6 +24,8 @@ class NotFoundError(Error): ...@@ -24,6 +24,8 @@ class NotFoundError(Error):
''' '''
Generic error for configuration elements that are not found. Generic error for configuration elements that are not found.
''' '''
def __str__(self):
return 'cannot find {0}'.format(self.args[0])
class MissingManifestError(NotFoundError): class MissingManifestError(NotFoundError):
''' '''
...@@ -61,11 +63,14 @@ def findProject(name, version, platform, allow_empty_version=False): ...@@ -61,11 +63,14 @@ def findProject(name, version, platform, allow_empty_version=False):
@param allow_empty_version: if True, we allow also the plain project name (without version) @param allow_empty_version: if True, we allow also the plain project name (without version)
@return path to the project binary directory @return path to the project binary directory
If name is None, version should be the path to the top directory of the project.
''' '''
log.debug('findProject(name=%r, version=%r, platform=%r, ' log.debug('findProject(name=%r, version=%r, platform=%r, '
'allow_empty_version=%r)', 'allow_empty_version=%r)',
name, version, platform, allow_empty_version) name, version, platform, allow_empty_version)
if name:
# standard project suffixes # standard project suffixes
suffixes = ['{0}_{1}'.format(name, version), suffixes = ['{0}_{1}'.format(name, version),
os.path.join(name.upper(), '{0}_{1}'.format(name.upper(), version)), os.path.join(name.upper(), '{0}_{1}'.format(name.upper(), version)),
...@@ -73,9 +78,14 @@ def findProject(name, version, platform, allow_empty_version=False): ...@@ -73,9 +78,14 @@ def findProject(name, version, platform, allow_empty_version=False):
# special case: for the 'latest' version we allow the plain name # special case: for the 'latest' version we allow the plain name
if allow_empty_version: if allow_empty_version:
suffixes.insert(0, name) suffixes.insert(0, name)
else:
# path to project used, no need for suffixes
suffixes = [os.curdir]
for d in [os.path.join(b, s, bindir) # if project name is None, version is the path to the top level directory
for b in path # of the project
for d in [os.path.normpath(os.path.join(b, s, bindir))
for b in (path if name else [version])
for s in suffixes for s in suffixes
for bindir in (os.path.join('InstallArea', platform), for bindir in (os.path.join('InstallArea', platform),
os.curdir)]: os.curdir)]:
...@@ -290,3 +300,20 @@ def getLCGRelocation(manifest): ...@@ -290,3 +300,20 @@ def getLCGRelocation(manifest):
'LCG_releases_base': dirname(lcg_path) 'LCG_releases_base': dirname(lcg_path)
if lcg_path.endswith('LCG_%s' % version) if lcg_path.endswith('LCG_%s' % version)
else lcg_path} else lcg_path}
def getProjectNameVersion(manifest):
'''
Get project name and version from a manifest.xml.
'''
from xml.dom.minidom import parse
log.debug('extracting project name from %s', manifest)
name, version = None, None
try:
m = parse(manifest)
project = m.getElementsByTagName('project')[0]
name = project.getAttribute('name')
version = project.getAttribute('version')
except (IndexError, AttributeError), exc:
log.debug('cannot extract project name or version: %s', exc)
return name, version
...@@ -16,7 +16,8 @@ import logging ...@@ -16,7 +16,8 @@ import logging
import EnvConfig import EnvConfig
from LbConfiguration.SP2.lookup import (getEnvXmlPath, findProject, from LbConfiguration.SP2.lookup import (getEnvXmlPath, findProject,
findDataPackage, getLCGRelocation) findDataPackage, getLCGRelocation,
getProjectNameVersion)
from LbConfiguration.SP2.version import (isValidVersion, expandVersionAlias, from LbConfiguration.SP2.version import (isValidVersion, expandVersionAlias,
DEFAULT_VERSION) DEFAULT_VERSION)
from LbConfiguration.SetupProject import FixProjectCase from LbConfiguration.SetupProject import FixProjectCase
...@@ -194,6 +195,11 @@ class SP2(EnvConfig.Script): ...@@ -194,6 +195,11 @@ class SP2(EnvConfig.Script):
parser.add_option("--profile", action="store_true", parser.add_option("--profile", action="store_true",
help="Print some profile informations about the execution.") help="Print some profile informations about the execution.")
parser.add_option('--path-to-project', action='store_true',
help='Interpret the first argument as path to a '
'project top-level directory instead of as a '
'project name')
parser.set_defaults(use = [], parser.set_defaults(use = [],
runtime_projects = [], runtime_projects = [],
overriding_projects = [], overriding_projects = [],
...@@ -205,8 +211,12 @@ class SP2(EnvConfig.Script): ...@@ -205,8 +211,12 @@ class SP2(EnvConfig.Script):
def _parse_args(self, args=None): def _parse_args(self, args=None):
super(SP2, self)._parse_args(args) super(SP2, self)._parse_args(args)
if len(self.cmd) < 1: if len(self.cmd) < 1:
self.parser.error("missing project name") self.parser.error("missing project " +
if '/' in self.cmd[0]: ('path' if self.opts.path_to_project else 'name'))
if self.opts.path_to_project:
self.project = None
self.version = os.path.abspath(self.cmd.pop(0))
elif '/' in self.cmd[0]:
self.project, self.version = self.cmd.pop(0).split('/') self.project, self.version = self.cmd.pop(0).split('/')
self.project = FixProjectCase(self.project) self.project = FixProjectCase(self.project)
else: else:
...@@ -228,6 +238,12 @@ class SP2(EnvConfig.Script): ...@@ -228,6 +238,12 @@ class SP2(EnvConfig.Script):
if self.opts.user_area and not self.opts.no_user_area: if self.opts.user_area and not self.opts.no_user_area:
path.insert(0, SearchPathEntry(self.opts.user_area)) path.insert(0, SearchPathEntry(self.opts.user_area))
if self.opts.path_to_project:
if self.opts.list:
self.parser.error('options --list and --path-to-project are incompatible')
elif self.opts.use_setupproject:
self.parser.error('options --use-sp and --path-to-project are incompatible')
# FIXME: we need to handle common options like --list in a single place # FIXME: we need to handle common options like --list in a single place
if self.opts.list: if self.opts.list:
from lookup import listVersions from lookup import listVersions
...@@ -268,6 +284,7 @@ class SP2(EnvConfig.Script): ...@@ -268,6 +284,7 @@ class SP2(EnvConfig.Script):
# set the environment XML search path # set the environment XML search path
env_path = [] env_path = []
for p, v in projects: for p, v in projects:
if p:
v = expandVersionAlias(p, v, self.opts.platform) v = expandVersionAlias(p, v, self.opts.platform)
env_path.extend(getEnvXmlPath(p, v, self.opts.platform, env_path.extend(getEnvXmlPath(p, v, self.opts.platform,
self.allow_empty_version and self.allow_empty_version and
...@@ -282,6 +299,13 @@ class SP2(EnvConfig.Script): ...@@ -282,6 +299,13 @@ class SP2(EnvConfig.Script):
self.opts.actions.extend(('set', (k, v)) self.opts.actions.extend(('set', (k, v))
for k, v in lcg_relocation.items()) for k, v in lcg_relocation.items())
# now we can expand project name end version if --path-to-project
if self.opts.path_to_project:
self.project, self.version = getProjectNameVersion(os.path.join(project_path,
'manifest.xml'))
# FIXME: EnvConfig has got problems with unicode in the search path
self.project, self.version = map(str, (self.project, self.version))
# extend the prompt variable (bash, sh) # extend the prompt variable (bash, sh)
if self.cmd and os.path.basename(self.cmd[0]) in ('bash', 'sh'): if self.cmd and os.path.basename(self.cmd[0]) in ('bash', 'sh'):
prompt = os.environ.get('PS1', r'\W \$ ') prompt = os.environ.get('PS1', r'\W \$ ')
...@@ -293,6 +317,8 @@ class SP2(EnvConfig.Script): ...@@ -293,6 +317,8 @@ class SP2(EnvConfig.Script):
# instruct the script to load the projects environment XML # instruct the script to load the projects environment XML
for p, _ in projects[::-1]: for p, _ in projects[::-1]:
if not p: # this flags the main project (when --path-to-project)
p = self.project
self.opts.actions.append(('loadXML', (p + '.xenv',))) self.opts.actions.append(('loadXML', (p + '.xenv',)))
# handle the extra data packages # handle the extra data packages
...@@ -336,4 +362,8 @@ class SP2(EnvConfig.Script): ...@@ -336,4 +362,8 @@ class SP2(EnvConfig.Script):
else: else:
self.compatMain() self.compatMain()
except (NotFoundError, IOError, OSError), x: except (NotFoundError, IOError, OSError), x:
if self.opts.path_to_project:
# SetupProject does not support --path-to-project
self.log.error('%s', x)
sys.exit(1)
self.compatMain(x) self.compatMain(x)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment