コード例 #1
0
    def do_run(self, args, user_args):
        # manifest.path is not supposed to be set during init, thus clear it
        # for the session and update it to correct location when complete.
        if config.get('manifest', 'path', fallback=None) is not None:
            config.remove_option('manifest', 'path')

        manifest_file = os.path.join(args.local or args.cache, 'west.yml')

        projects = Manifest.from_file(manifest_file).projects
        manifest_project = projects[MANIFEST_PROJECT_INDEX]

        if args.local is not None:
            rel_manifest = os.path.relpath(args.local, util.west_topdir())
            update_config('manifest', 'path', rel_manifest)
        else:
            if manifest_project.path == '':
                url_path = urlparse(args.manifest_url).path
                manifest_project.path = posixpath.basename(url_path)
                manifest_project.abspath = os.path.realpath(
                    os.path.join(util.west_topdir(), manifest_project.path))
                manifest_project.name = manifest_project.path

            shutil.move(args.cache, manifest_project.abspath)
            update_config('manifest', 'path', manifest_project.path)

        for project in projects:
            if project.path == 'zephyr':
                update_config('zephyr', 'base', project.path)
コード例 #2
0
    def run(self, argv):
        # Run the command-line application with argument list 'argv'.

        # See if we're in a workspace. It's fine if we're not.
        # Note that this falls back on searching from ZEPHYR_BASE
        # if the current directory isn't inside a west workspace.
        try:
            self.topdir = west_topdir()
        except WestNotFound:
            pass

        # Read the configuration files. We need this to get
        # manifest.path to parse the manifest, etc.
        #
        # TODO: re-work to avoid global state (#149).
        config.read_config(topdir=self.topdir)

        # Set self.manifest and self.extensions.
        self.load_manifest()
        self.load_extension_specs()

        # Set up initial argument parsers. This requires knowing
        # self.extensions, so it can't happen before now.
        self.setup_parsers()

        # OK, we are all set. Run the command.
        self.run_command(argv)
コード例 #3
0
ファイル: manifest.py プロジェクト: marc-hb/west
    def __init__(self,
                 name,
                 defaults=None,
                 path=None,
                 clone_depth=None,
                 revision=None,
                 west_commands=None,
                 remote=None,
                 url=None):
        '''Specify a Project by name, Remote, and optional information.

        :param name: Project's user-defined name in the manifest.
        :param defaults: If the revision parameter is not given, the project's
                         revision is set to defaults.revision if defaults is
                         not None, or the west-wide default otherwise.
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If not given,
                     the project's ``name`` is used.
        :param clone_depth: Nonnegative integer clone depth if present in
                            the manifest.
        :param revision: Project revision as given in the manifest, if present.
                         If not given, defaults.revision is used instead.
        :param west_commands: path to a YAML file in the project containing
                              a description of west extension commands provided
                              by the project, if given.
        :param remote: Remote instance corresponding to this Project as
                       specified in the manifest. This is used to build
                       the project's URL, and is also stored as an attribute.
        :param url: The project's fetch URL. This cannot be given with `remote`
                    as well: choose one.
        '''
        if remote and url:
            raise ValueError('got remote={} and url={}'.format(remote, url))
        if not (remote or url):
            raise ValueError('got neither a remote nor a URL')

        if defaults is None:
            defaults = _DEFAULTS

        self.name = name
        '''Project name as it appears in the manifest.'''
        self.url = url or (remote.url_base + '/' + name)
        '''Complete fetch URL for the project, either as given by the url kwarg
        or computed from the remote URL base and the project name.'''
        self.path = os.path.normpath(path or name)
        '''Relative path to the project in the installation.'''
        self.abspath = os.path.realpath(
            os.path.join(util.west_topdir(), self.path))
        '''Absolute path to the project.'''
        self.posixpath = PurePath(self.abspath).as_posix()
        '''Absolute path to the project, POSIX style (with forward slashes).'''
        self.clone_depth = clone_depth
        '''Project's clone depth, or None'''
        self.revision = revision or defaults.revision
        '''Revision to check out for this project, as given in the manifest,
        from manifest defaults, or from the default supplied by west.'''
        self.west_commands = west_commands
        '''Path to project's "west-commands", or None.'''
        self.remote = remote
        '''`Remote` instance corresponding to the project's remote, or None.'''
コード例 #4
0
    def __init__(self,
                 name,
                 path=None,
                 revision='(not set)',
                 url='(not set)',
                 west_commands=None):
        '''Specify a Special Project by name, and url, and optional information.

        :param name: Special Project's user-defined name in the manifest
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If None,
                     the project's ``name`` is used.
        :param revision: Project revision as given in the manifest, if present.
        :param url: Complete URL for special project.
        :param west_commands: path to a YAML file in the project containing
                              a description of external west commands provided
                              by the project, if given. This obviously only
                              makes sense for the manifest project, not west.
        '''
        if name == 'west' and west_commands:
            raise ValueError('setting west_commands on west is forbidden')

        self.name = name
        self.url = url
        self.path = path or name
        self.abspath = os.path.realpath(
            os.path.join(util.west_topdir(), self.path))
        self.posixpath = PurePath(self.abspath).as_posix()
        self.revision = revision
        self.remote = None
        self.clone_depth = None
        self.west_commands = west_commands
コード例 #5
0
ファイル: project.py プロジェクト: mbolivar/west
def _clone(project):
    log.small_banner(f'{project.name}: cloning and initializing')
    project.git(f'init {project.abspath}', cwd=util.west_topdir())
    # This remote is added as a convenience for the user.
    # However, west always fetches project data by URL, not remote name.
    # The user is therefore free to change the URL of this remote.
    project.git(f'remote add -- {project.remote_name} {project.url}')
コード例 #6
0
    def __init__(self,
                 name,
                 remote,
                 defaults,
                 path=None,
                 clone_depth=None,
                 revision=None):
        '''Specify a Project by name, Remote, and optional information.

        :param name: Project's user-defined name in the manifest
        :param remote: Remote instance corresponding to this Project's remote.
                       This may not be None.
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If None,
                     the project's ``name`` is used.
        :param revision: Project revision as given in the manifest, if present.
        '''
        if remote is None:
            raise ValueError('remote may not be None')
        _wrn_if_not_remote(remote)

        self.name = name
        self.remote = remote
        self.url = remote.url + '/' + name
        self.path = path or name
        self.abspath = os.path.normpath(
            os.path.join(util.west_topdir(), self.path))
        self.clone_depth = clone_depth
        self.revision = revision or defaults.revision
コード例 #7
0
    def __init__(self, name, remote, defaults, path=None, clone_depth=None,
                 revision=None):
        '''Specify a Project by name, Remote, and optional information.

        :param name: Project's user-defined name in the manifest.
        :param remote: Remote instance corresponding to this Project as
                       specified in the manifest. This is used to build
                       the project's URL, and is also stored as an attribute.
        :param defaults: If the revision parameter is not given, the project's
                         revision is set to defaults.revision.
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If not given,
                     the project's ``name`` is used.
        :param clone_depth: Nonnegative integer clone depth if present in
                            the manifest.
        :param revision: Project revision as given in the manifest, if present.
                         If not given, defaults.revision is used instead.
        '''
        _wrn_if_not_remote(remote)

        self.name = name
        self.remote = remote
        self.url = remote.url_base + '/' + name
        self.path = os.path.normpath(path or name)
        self.abspath = os.path.realpath(os.path.join(util.west_topdir(),
                                                     self.path))
        self.clone_depth = clone_depth
        self.revision = revision or defaults.revision
コード例 #8
0
ファイル: file_input.py プロジェクト: nrfconnect/sdk-nrf
def generate_input(data: Data):
    '''Generate input files from list of files/globs from command line and/or a text file.'''
    full_set = set()

    if args.input_files is not None:
        cwd = Path('.').resolve()
        for globs in args.input_files:
            joiner = '", "'
            data.inputs.append(f'Files: "{joiner.join(globs)}" (relative to "{cwd}")')
            r = resolve_globs(cwd, globs)
            full_set.update(r)

    if args.input_list_file is not None:
        for file in args.input_list_file:
            file_path = Path(file).resolve()
            data.inputs.append(f'A list of files read from: "{file_path}"')
            globs = list()
            try:
                with open(file_path, 'r') as fd:
                    for line in fd:
                        line = line.strip()
                        if line == '' or line[0] == '#':
                            continue
                        globs.append(line)
            except Exception as e:
                raise SbomException(f'Cannot read from file "{file_path}": {e}') from e
            r = resolve_globs(file_path.parent, globs)
            full_set.update(r)

    for file_path in full_set:
        file = FileInfo()
        file.file_path = file_path
        file.file_rel_path = os.path.relpath(file_path, util.west_topdir())
        data.files.append(file)
コード例 #9
0
ファイル: project.py プロジェクト: tliqit/west
def _clone(project):
    log.small_banner(project.format('{name}: cloning and initializing'))
    project.git('init {abspath}', cwd=util.west_topdir())
    # The "origin" remote is only added for the user's convenience. We
    # always fetch directly from the URL specified in the manifest.
    # Later changes to the manifest won't change this remote,
    # unfortunately -- the user will have to fix that themselves.
    project.git('remote add -- origin {url}')
コード例 #10
0
    def bootstrap(self, args):
        manifest_url = args.manifest_url or MANIFEST_URL_DEFAULT
        manifest_rev = args.manifest_rev or MANIFEST_REV_DEFAULT
        topdir = util.canon_path(args.directory or os.getcwd())
        west_dir = join(topdir, WEST_DIR)

        try:
            already = util.west_topdir(topdir, fall_back=False)
            self.die_already(already)
        except util.WestNotFound:
            pass

        log.banner('Initializing in', topdir)
        if not isdir(topdir):
            self.create(topdir, exist_ok=False)

        # Clone the manifest repository into a temporary directory.
        tempdir = join(west_dir, 'manifest-tmp')
        if exists(tempdir):
            log.dbg('removing existing temporary manifest directory', tempdir)
            shutil.rmtree(tempdir)
        try:
            self.clone_manifest(manifest_url, manifest_rev, tempdir)
        except subprocess.CalledProcessError:
            shutil.rmtree(tempdir, ignore_errors=True)
            raise

        # Verify the manifest file exists.
        temp_manifest = join(tempdir, 'west.yml')
        if not exists(temp_manifest):
            log.die(f'can\'t init: no "west.yml" found in {tempdir}\n'
                    f'  Hint: check --manifest-url={manifest_url} and '
                    '--manifest-rev={manifest_rev}\n'
                    f'  You may need to remove {west_dir} before retrying.')

        # Parse the manifest to get the manifest path, if it declares one.
        # Otherwise, use the URL. Ignore imports -- all we really
        # want to know is if there's a "self: path:" or not.
        projects = Manifest.from_file(temp_manifest,
                                      import_flags=ImportFlag.IGNORE,
                                      topdir=topdir).projects
        manifest_project = projects[MANIFEST_PROJECT_INDEX]
        if manifest_project.path:
            manifest_path = manifest_project.path
        else:
            manifest_path = posixpath.basename(urlparse(manifest_url).path)
        manifest_abspath = join(topdir, manifest_path)

        log.dbg('moving', tempdir, 'to', manifest_abspath,
                level=log.VERBOSE_EXTREME)
        try:
            shutil.move(tempdir, manifest_abspath)
        except shutil.Error as e:
            log.die(e)
        log.small_banner('setting manifest.path to', manifest_path)
        update_config('manifest', 'path', manifest_path, topdir=topdir)

        return topdir
コード例 #11
0
def main(argv=None):
    # Makes ANSI color escapes work on Windows, and strips them when
    # stdout/stderr isn't a terminal
    colorama.init()

    # See if we're in an installation.
    try:
        topdir = west_topdir()
    except WestNotFound:
        topdir = None

    # Read the configuration files before looking for extensions.
    # We need this to find the manifest path in order to load extensions.
    config.read_config()

    # Load any extension command specs if we're in an installation.
    if topdir:
        try:
            extensions = get_extension_commands()
        except (MalformedConfig, FileNotFoundError):
            extensions = {}
    else:
        extensions = {}

    if argv is None:
        argv = sys.argv[1:]
    args, unknown = parse_args(argv, extensions, topdir)

    for_stack_trace = 'run as "west -v {}" for a stack trace'.format(
        quote_sh_list(argv))
    try:
        args.handler(args, unknown)
    except KeyboardInterrupt:
        sys.exit(0)
    except CalledProcessError as cpe:
        log.err('command exited with status {}: {}'.format(
            cpe.args[0], quote_sh_list(cpe.args[1])))
        if args.verbose:
            traceback.print_exc()
        else:
            log.inf(for_stack_trace)
        sys.exit(cpe.returncode)
    except ExtensionCommandError as ece:
        log.err(
            'extension command', args.command,
            'was improperly defined and could not be run{}'.format(
                ': ' + ece.hint if ece.hint else ''))
        if args.verbose:
            traceback.print_exc()
        else:
            log.inf(for_stack_trace)
        sys.exit(ece.returncode)
    except CommandContextError as cce:
        log.err('command', args.command, 'cannot be run in this context:',
                *cce.args)
        sys.exit(cce.returncode)
    except CommandError as ce:
        sys.exit(ce.returncode)
コード例 #12
0
ファイル: usfs.py プロジェクト: ridephysics/usfs
    def __init__(self):
        super().__init__(
            'usfs',
            'build usfs tools',
            None)

        self.top_dir = util.west_topdir()
        self.build_dir = os.path.join(self.top_dir, 'build/usfs')
        self.source_dir = Path(os.path.dirname(os.path.realpath(__file__))).parent.parent
コード例 #13
0
ファイル: project.py プロジェクト: rgundi/west
def _git_base(project, cmd, *, extra_args=(), capture_stdout=False,
              check=True):
    # Runs a git command in the West top directory. See _git_helper() for
    # parameter documentation.
    #
    # Returns a CompletedProcess instance (see below).

    return _git_helper(project, cmd, extra_args, util.west_topdir(),
                       capture_stdout, check)
コード例 #14
0
ファイル: main.py プロジェクト: XIZHAOJUN/west
def main(argv=None):
    # Makes ANSI color escapes work on Windows, and strips them when
    # stdout/stderr isn't a terminal
    colorama.init()

    # See if we're in an installation.
    try:
        topdir = west_topdir()
    except WestNotFound:
        topdir = None

    # Read the configuration files before looking for extensions.
    # We need this to find the manifest path in order to load extensions.
    config.read_config()

    # Load any extension command specs if we're in an installation.
    if topdir:
        try:
            extensions = get_extension_commands()
        except (MalformedConfig, FileNotFoundError):
            extensions = {}
    else:
        extensions = {}

    if argv is None:
        argv = sys.argv[1:]
    args, unknown = parse_args(argv, extensions, topdir)

    try:
        args.handler(args, unknown)
    except KeyboardInterrupt:
        sys.exit(0)
    except CalledProcessError as cpe:
        log.err('command exited with status {}: {}'.format(
            cpe.returncode, quote_sh_list(cpe.cmd)))
        if args.verbose:
            traceback.print_exc()
        sys.exit(cpe.returncode)
    except ExtensionCommandError as ece:
        msg = 'extension command "{}" could not be run{}.'.format(
            args.command, ': ' + ece.hint if ece.hint else '')
        if args.verbose:
            log.err(msg)
            traceback.print_exc()
        else:
            log.err(msg, 'See {} for a traceback.'.format(dump_traceback()))
        sys.exit(ece.returncode)
    except CommandContextError as cce:
        log.err('command', args.command, 'cannot be run in this context:',
                *cce.args)
        log.err('see {} for a traceback.'.format(dump_traceback()))
        sys.exit(cce.returncode)
    except CommandError as ce:
        # No need to dump_traceback() here. The command is responsible
        # for logging its own errors.
        sys.exit(ce.returncode)
コード例 #15
0
def manifest_path():
    '''Return the path to the manifest file.

    Raises WestNotFound if called from outside of a west working directory.'''
    try:
        return os.path.join(util.west_topdir(), config.get('manifest', 'path'),
                            'west.yml')
    except (configparser.NoOptionError, configparser.NoSectionError) as e:
        raise MalformedConfig('missing key: \'{}\' in west config file'.format(
            e.args[0])) from e
コード例 #16
0
def _clone(project):
    log.small_banner(f'{project.name}: cloning and initializing')
    project.git(f'init {project.abspath}', cwd=util.west_topdir())
    # The "origin" remote is added to follow the practice that 'origin'
    # is the remote a Git repository was always cloned from.
    #
    # However, west doesn't fetch from this remote: it always forms
    # a fetch URL from the manifest file and fetches that directly.
    #
    # The URL of this remote can thus be changed by the user at will.
    project.git(f'remote add -- origin {project.url}')
コード例 #17
0
ファイル: manifest.py プロジェクト: skelliam/west
def manifest_path():
    '''Return the path to the manifest file.

    Raises: WestNotFound if called from outside of a west installation,
    MalformedConfig if the configuration file is missing a manifest.path key,
    and FileNotFoundError if the manifest.path file doesn't exist.'''
    ret = os.path.join(util.west_topdir(), _mpath(), 'west.yml')
    # It's kind of annoying to manually instantiate a FileNotFoundError.
    # This seems to be the best way.
    if not os.path.isfile(ret):
        raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), ret)
    return ret
コード例 #18
0
ファイル: project.py プロジェクト: bengartner/west
def _fetch(project):
    # Fetches upstream changes for 'project' and updates the 'manifest-rev'
    # branch to point to the revision specified in the manifest. If the
    # project's repository does not already exist, it is created first.

    if not _cloned(project):
        _msg(project.format('{name}: cloning and initializing'))
        _git(project, 'init {abspath}', cwd=util.west_topdir())
        # This remote is only added for the user's convenience. We always fetch
        # directly from the URL specified in the manifest.
        _git(project, 'remote add -- {remote_name} {url}')

    # Fetch the revision specified in the manifest into the manifest-rev branch

    msg = "{name}: fetching changes"
    if project.clone_depth:
        fetch_cmd = "fetch --depth={clone_depth}"
        msg += " with --depth {clone_depth}"
    else:
        fetch_cmd = "fetch"

    _msg(project.format(msg))
    # This two-step approach avoids a "trying to write non-commit object" error
    # when the revision is an annotated tag. ^{commit} type peeling isn't
    # supported for the <src> in a <src>:<dst> refspec, so we have to do it
    # separately.
    #
    # --tags is required to get tags when the remote is specified as an URL.
    if _is_sha(project.revision):
        # Don't fetch a SHA directly, as server may restrict from doing so.
        _git(project, fetch_cmd + ' -f --tags '
             '-- {url} refs/heads/*:refs/west/*')
        _git(project, 'update-ref ' + QUAL_MANIFEST_REV + ' {revision}')
    else:
        _git(project, fetch_cmd + ' -f --tags -- {url} {revision}')
        _git(project,
             'update-ref ' + QUAL_MANIFEST_REV + ' FETCH_HEAD^{{commit}}')
    _git(project, 'lfs fetch {remote_name} FETCH_HEAD^{{commit}}')

    if not _head_ok(project):
        # If nothing it checked out (which would usually only happen just after
        # we initialize the repository), check out 'manifest-rev' in a detached
        # HEAD state.
        #
        # Otherwise, the initial state would have nothing checked out, and HEAD
        # would point to a non-existent refs/heads/master branch (that would
        # get created if the user makes an initial commit). That state causes
        # e.g. 'west rebase' to fail, and might look confusing.
        #
        # The --detach flag is strictly redundant here, because the
        # refs/heads/<branch> form already detaches HEAD, but it avoids a
        # spammy detached HEAD warning from Git.
        _git(project, 'checkout --detach ' + QUAL_MANIFEST_REV)
コード例 #19
0
    def __init__(self,
                 name,
                 path=None,
                 revision='(not set)',
                 url='(not set)',
                 west_commands=None):
        '''Specify a Special Project by name, and url, and optional information.

        :param name: Special Project's user-defined name in the manifest
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If None,
                     the project's ``name`` is used.
        :param revision: Project revision as given in the manifest, if present.
        :param url: Complete URL for special project.
        :param west_commands: path to a YAML file in the project containing
                              a description of west extension commands provided
                              by the project, if given. This obviously only
                              makes sense for the manifest project, not west.
        '''
        if name == 'west' and west_commands:
            raise ValueError('setting west_commands on west is forbidden')

        self.name = name
        '''Project name, either "west" or "manifest".'''

        self.url = url
        '''Complete fetch URL for the project.'''

        self.path = path or name
        '''Relative path to the project in the installation.'''

        self.abspath = os.path.realpath(
            os.path.join(util.west_topdir(), self.path))
        '''Absolute path to the project.'''

        self.posixpath = PurePath(self.abspath).as_posix()
        '''Absolute path to the project, POSIX style (with forward slashes).'''

        self.revision = revision
        '''Revision to check out for the west project, as given in the manifest,
        from manifest defaults, or from the default supplied by west. Undefined
        for the manifest project.'''

        self.remote = None
        '''None, provided for analogy with Project.'''

        self.clone_depth = None
        '''None, provided for analogy with Project.'''

        self.west_commands = west_commands
        '''Path to project's "west-commands", for the manifest project, or
コード例 #20
0
    def __init__(self,
                 name,
                 remote,
                 defaults,
                 path=None,
                 clone_depth=None,
                 revision=None,
                 west_commands=None):
        '''Specify a Project by name, Remote, and optional information.

        :param name: Project's user-defined name in the manifest.
        :param remote: Remote instance corresponding to this Project as
                       specified in the manifest. This is used to build
                       the project's URL, and is also stored as an attribute.
        :param defaults: If the revision parameter is not given, the project's
                         revision is set to defaults.revision.
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If not given,
                     the project's ``name`` is used.
        :param clone_depth: Nonnegative integer clone depth if present in
                            the manifest.
        :param revision: Project revision as given in the manifest, if present.
                         If not given, defaults.revision is used instead.
        :param west_commands: path to a YAML file in the project containing
                              a description of west extension commands provided
                              by the project, if given.
        '''
        _wrn_if_not_remote(remote)

        self.name = name
        '''Project name as it appears in the manifest.'''
        self.remote = remote
        '''`Remote` instance corresponding to the project's remote.'''
        self.url = remote.url_base + '/' + name
        '''Complete fetch URL for the project.'''
        self.path = os.path.normpath(path or name)
        '''Relative path to the project in the installation.'''
        self.abspath = os.path.realpath(
            os.path.join(util.west_topdir(), self.path))
        '''Absolute path to the project.'''
        self.posixpath = PurePath(self.abspath).as_posix()
        '''Absolute path to the project, POSIX style (with forward slashes).'''
        self.clone_depth = clone_depth
        '''Project's clone depth, or None'''
        self.revision = revision or defaults.revision
        '''Revision to check out for this project, as given in the manifest,
        from manifest defaults, or from the default supplied by west.'''
        self.west_commands = west_commands
        '''Path to project's "west-commands", or None.'''
コード例 #21
0
ファイル: manifest.py プロジェクト: frkv/west
def manifest_path():
    '''Return the path to the manifest file.

    Raises: WestNotFound if called from outside of a west working directory,
    MalformedConfig if the configuration file is missing a manifest.path key,
    and FileNotFoundError if the manifest.path file doesn't exist.'''
    try:
        ret = os.path.join(util.west_topdir(), config.get('manifest', 'path'),
                           'west.yml')
    except (configparser.NoOptionError, configparser.NoSectionError) as e:
        raise MalformedConfig('no "manifest.path" config option is set') from e
    # It's kind of annoying to manually instantiate a FileNotFoundError.
    # This seems to be the best way.
    if not os.path.isfile(ret):
        raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), ret)
    return ret
コード例 #22
0
    def __init__(self, name, path=None, revision=None, url=None):
        '''Specify a Special Project by name, and url, and optional information.

        :param name: Special Project's user-defined name in the manifest
        :param path: Relative path to the project in the west
                     installation, if present in the manifest. If None,
                     the project's ``name`` is used.
        :param revision: Project revision as given in the manifest, if present.
        :param url: Complete URL for special project.
        '''
        self.name = name
        self.url = url
        self.path = path or name
        self.abspath = os.path.realpath(os.path.join(util.west_topdir(),
                                                     self.path))
        self.revision = revision
        self.remote = None
        self.clone_depth = None
コード例 #23
0
ファイル: project.py プロジェクト: ioannisg/west
    def do_run(self, args, user_args):
        manifest_file = os.path.join(args.local or args.cache, 'west.yml')

        project = Manifest.from_file(manifest_file)\
            .projects[MANIFEST_PROJECT_INDEX]

        if args.local is not None:
            rel_manifest = os.path.relpath(args.local, util.west_topdir())
            _update_key(config, 'manifest', 'path', rel_manifest)
        else:
            if project.path is None:
                url_path = urlparse(args.manifest_url).path
                project.path = posixpath.basename(url_path)
                project.name = project.path

            _inf(project, 'Creating repository for {name_and_path}')
            shutil.move(args.cache, project.abspath)

            _update_key(config, 'manifest', 'path', project.path)
コード例 #24
0
ファイル: fw.py プロジェクト: ridephysics/imulogger
    def __init__(self, cmdname, cmddesc, projectdir, builddir):
        super().__init__(cmdname, cmddesc, None, accepts_unknown_args=True)

        self.top_dir = util.west_topdir()
        self.build_dir = os.path.join(self.top_dir,
                                      os.path.join('build', builddir))
        self.project_dir = os.path.join(self.top_dir, projectdir)
        self.idf_path = os.path.join(self.top_dir, 'external/esp-idf')
        self.extra_component_dirs = [
            os.path.join(self.top_dir, 'components'),
            os.path.join(self.top_dir, 'components/usfs/lib'),
        ]
        self.sdkconfig_final = os.path.join(self.build_dir, 'sdkconfig')
        self.sdkconfig_defaults = os.path.join(self.build_dir,
                                               'sdkconfig.defaults')
        self.sdkconfigs = [
            os.path.join(self.project_dir, 'sdkconfig.defaults'),
            os.path.join(self.top_dir, 'sdkconfig.defaults'),
        ]
コード例 #25
0
ファイル: manifest.py プロジェクト: tliqit/west
def manifest_path():
    '''Absolute path of the manifest file in the current installation.

    Exceptions raised:

        - `west.util.WestNotFound` if called from outside of a west
          installation

        - `MalformedConfig` if the configuration file has no
          ``manifest.path`` key

        - ``FileNotFoundError`` if no ``west.yml`` exists in
          ``manifest.path``
    '''
    ret = os.path.join(util.west_topdir(), _mpath(), _WEST_YML)
    # It's kind of annoying to manually instantiate a FileNotFoundError.
    # This seems to be the best way.
    if not os.path.isfile(ret):
        raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), ret)
    return ret
コード例 #26
0
ファイル: walker.py プロジェクト: zephyrproject-rtos/zephyr
    def setupDocuments(self):
        log.dbg("setting up placeholder documents")

        # set up build document
        cfgBuild = DocumentConfig()
        cfgBuild.name = "build"
        cfgBuild.namespace = self.cfg.namespacePrefix + "/build"
        cfgBuild.docRefID = "DocumentRef-build"
        self.docBuild = Document(cfgBuild)

        # we'll create the build packages in walkTargets()

        # the DESCRIBES relationship for the build document will be
        # with the zephyr_final package
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docBuild
        rd.otherType = RelationshipDataElementType.TARGETNAME
        rd.otherTargetName = "zephyr_final"
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

        # set up zephyr document
        cfgZephyr = DocumentConfig()
        cfgZephyr.name = "zephyr-sources"
        cfgZephyr.namespace = self.cfg.namespacePrefix + "/zephyr"
        cfgZephyr.docRefID = "DocumentRef-zephyr"
        self.docZephyr = Document(cfgZephyr)

        # also set up zephyr sources package
        cfgPackageZephyr = PackageConfig()
        cfgPackageZephyr.name = "zephyr-sources"
        cfgPackageZephyr.spdxID = "SPDXRef-zephyr-sources"
        # relativeBaseDir is Zephyr sources topdir
        try:
            cfgPackageZephyr.relativeBaseDir = west_topdir(
                self.cm.paths_source)
        except WestNotFound:
            log.err(
                f"cannot find west_topdir for CMake Codemodel sources path {self.cm.paths_source}; bailing"
            )
            return False
        pkgZephyr = Package(cfgPackageZephyr, self.docZephyr)
        self.docZephyr.pkgs[pkgZephyr.cfg.spdxID] = pkgZephyr

        # create DESCRIBES relationship data
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docZephyr
        rd.otherType = RelationshipDataElementType.PACKAGEID
        rd.otherPackageID = cfgPackageZephyr.spdxID
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

        # set up app document
        cfgApp = DocumentConfig()
        cfgApp.name = "app-sources"
        cfgApp.namespace = self.cfg.namespacePrefix + "/app"
        cfgApp.docRefID = "DocumentRef-app"
        self.docApp = Document(cfgApp)

        # also set up app sources package
        cfgPackageApp = PackageConfig()
        cfgPackageApp.name = "app-sources"
        cfgPackageApp.spdxID = "SPDXRef-app-sources"
        # relativeBaseDir is app sources dir
        cfgPackageApp.relativeBaseDir = self.cm.paths_source
        pkgApp = Package(cfgPackageApp, self.docApp)
        self.docApp.pkgs[pkgApp.cfg.spdxID] = pkgApp

        # create DESCRIBES relationship data
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docApp
        rd.otherType = RelationshipDataElementType.PACKAGEID
        rd.otherPackageID = cfgPackageApp.spdxID
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

        if self.cfg.includeSDK:
            # set up SDK document
            cfgSDK = DocumentConfig()
            cfgSDK.name = "sdk"
            cfgSDK.namespace = self.cfg.namespacePrefix + "/sdk"
            cfgSDK.docRefID = "DocumentRef-sdk"
            self.docSDK = Document(cfgSDK)

            # also set up zephyr sdk package
            cfgPackageSDK = PackageConfig()
            cfgPackageSDK.name = "sdk"
            cfgPackageSDK.spdxID = "SPDXRef-sdk"
            # relativeBaseDir is SDK dir
            cfgPackageSDK.relativeBaseDir = self.sdkPath
            pkgSDK = Package(cfgPackageSDK, self.docSDK)
            self.docSDK.pkgs[pkgSDK.cfg.spdxID] = pkgSDK

            # create DESCRIBES relationship data
            rd = RelationshipData()
            rd.ownerType = RelationshipDataElementType.DOCUMENT
            rd.ownerDocument = self.docSDK
            rd.otherType = RelationshipDataElementType.PACKAGEID
            rd.otherPackageID = cfgPackageSDK.spdxID
            rd.rlnType = "DESCRIBES"

            # add it to pending relationships queue
            self.pendingRelationships.append(rd)

        return True
コード例 #27
0
ファイル: manifest.py プロジェクト: tliqit/west
    def from_file(source_file=None, topdir=None):
        '''Manifest object factory given a source YAML file.

        Results depend on the parameters given:

            - If both *source_file* and *topdir* are given, the
              returned Manifest object is based on the data in
              *source_file*, rooted at *topdir*. The configuration
              files are not read in this case. This allows parsing a
              manifest file "as if" its project hierarchy were rooted
              at another location in the system.

            - If neither *source_file* nor *topdir* is given, the file
              system is searched for *topdir*. That installation's
              ``manifest.path`` configuration option is used to find
              *source_file*, ``topdir/<manifest.path>/west.yml``.

            - If only *source_file* is given, *topdir* is found
              starting there. The directory containing *source_file*
              doesn't have to be ``manifest.path`` in this case.

            - If only *topdir* is given, that installation's
              ``manifest.path`` is used to find *source_file*.

        Exceptions raised:

            - `west.util.WestNotFound` if no *topdir* can be found

            - `MalformedManifest` if *source_file* contains invalid
              data

            - `MalformedConfig` if ``manifest.path`` is needed and
              can't be read

            - ``ValueError`` if *topdir* is given but is not a west
              installation root

        :param source_file: path to the manifest YAML file
        :param topdir: west installation top level directory
        '''
        if source_file is None and topdir is None:
            # neither source_file nor topdir: search the filesystem
            # for the installation and use its manifest.path.
            topdir = util.west_topdir()
            source_file = _west_yml(topdir)
            return Manifest(source_file=source_file, topdir=topdir)
        elif source_file is not None and topdir is None:
            # just source_file: find topdir starting there.
            # fall_back is the default value -- this is just for emphasis.
            topdir = util.west_topdir(start=os.path.dirname(source_file),
                                      fall_back=True)
        elif topdir is not None and source_file is None:
            # just topdir. verify it's a real west installation root.
            msg = 'topdir {} is not a west installation root'.format(topdir)
            try:
                real_topdir = util.west_topdir(start=topdir, fall_back=False)
            except util.WestNotFound:
                raise ValueError(msg)
            if PurePath(topdir) != PurePath(real_topdir):
                raise ValueError(msg + '; but {} is'.format(real_topdir))
            # find west.yml based on manifest.path.
            source_file = _west_yml(topdir)
        else:
            # both source_file and topdir. nothing more to do, but
            # let's check the invariant.
            assert source_file
            assert topdir

        return Manifest(source_file=source_file, topdir=topdir)
コード例 #28
0
ファイル: project.py プロジェクト: machinelinux-root/west
def _clone(project):
    log.small_banner(project.format('{name}: cloning and initializing'))
    project.git('init {abspath}', cwd=util.west_topdir())
    # This remote is only added for the user's convenience. We always fetch
    # directly from the URL specified in the manifest.
    project.git('remote add -- {remote_name} {url}')
コード例 #29
0
ファイル: main.py プロジェクト: XIZHAOJUN/west
def set_zephyr_base(args):
    '''Ensure ZEPHYR_BASE is set
    Order of precedence:
    1) Value given as command line argument
    2) Value from environment setting: ZEPHYR_BASE
    3) Value of zephyr.base setting in west config file

    Order of precedence between 2) and 3) can be changed with the setting
    zephyr.base-prefer.
    zephyr.base-prefer takes the values 'env' and 'configfile'

    If 2) and 3) has different values and zephyr.base-prefer is unset a warning
    is printed to the user.'''

    if args.zephyr_base:
        # The command line --zephyr-base takes precedence over
        # everything else.
        zb = os.path.abspath(args.zephyr_base)
        zb_origin = 'command line'
    else:
        # If the user doesn't specify it concretely, then use ZEPHYR_BASE
        # from the environment or zephyr.base from west.configuration.
        #
        # `west init` will configure zephyr.base to the project that has path
        # 'zephyr'.
        #
        # At some point, we need a more flexible way to set environment
        # variables based on manifest contents, but this is good enough
        # to get started with and to ask for wider testing.
        zb_env = os.environ.get('ZEPHYR_BASE')
        zb_prefer = config.config.get('zephyr', 'base-prefer', fallback=None)
        zb_config = config.config.get('zephyr', 'base', fallback=None)
        if zb_config is not None:
            zb_config = os.path.join(west_topdir(), zb_config)

        if zb_prefer == 'env' and zb_env is not None:
            zb = zb_env
            zb_origin = 'env'
        elif zb_prefer == 'configfile' and zb_config is not None:
            zb = zb_config
            zb_origin = 'configfile'
        elif zb_env is not None:
            zb = zb_env
            zb_origin = 'env'
            try:
                different = (zb_config is not None
                             and not os.path.samefile(zb_config, zb_env))
            except FileNotFoundError:
                different = (zb_config is not None and
                             (os.path.normpath(os.path.abspath(zb_config)) !=
                              os.path.normpath(os.path.abspath(zb_env))))
            if different:
                # The environment ZEPHYR_BASE takes precedence over the config
                # setting, but in normal multi-repo operation we shouldn't
                # expect to need to set ZEPHYR_BASE.
                # Therefore issue a warning as it might have happened that
                # zephyr-env.sh/cmd was run in some other zephyr installation,
                # and the user forgot about that.
                log.wrn(
                    'ZEPHYR_BASE={}'.format(zb_env),
                    'in the calling environment will be used, but was set '
                    'to', zb_config, 'in west config.\n To disable this '
                    'warning, execute '
                    '\'west config --global zephyr.base-prefer env\'')
        elif zb_config is not None:
            zb = zb_config
            zb_origin = 'configfile'
        else:
            zb = None
            zb_origin = None
            # No --zephyr-base, no ZEPHYR_BASE envronment and no zephyr.base
            # Fallback to loop over projects, to identify if a project has path
            # 'zephyr' for fallback.
            try:
                manifest = Manifest.from_file()
                for project in manifest.projects:
                    if project.path == 'zephyr':
                        zb = project.abspath
                        zb_origin = 'manifest file {}'.format(manifest.path)
                        break
                else:
                    log.err('no --zephyr-base given, ZEPHYR_BASE is unset,',
                            'west config contains no zephyr.base setting,',
                            'and no manifest project has path "zephyr"')
            except MalformedConfig as e:
                log.wrn("Can't set ZEPHYR_BASE:",
                        'parsing of manifest file failed during command',
                        args.command, ':', *e.args)
            except WestNotFound:
                log.wrn("Can't set ZEPHYR_BASE:",
                        'not currently in a west installation')

    if zb is not None:
        os.environ['ZEPHYR_BASE'] = zb
        log.dbg('ZEPHYR_BASE={} (origin: {})'.format(zb, zb_origin))
コード例 #30
0
ファイル: manifest.py プロジェクト: skelliam/west
    def from_file(source_file=None, topdir=None):
        '''Create and return a new Manifest object given a source YAML file.

        :param source_file: Path to a YAML file containing the manifest.
        :param topdir: If given, the returned Manifest has a project
                       hierarchy rooted at this directory.

        If neither *source_file* nor *topdir* is given, a search is
        performed in the filesystem for a west installation, which is
        used as topdir. Its manifest.path configuration option is used
        to find source_file, ``topdir/<manifest.path>/west.yml``.

        If only *source_file* is given, the search for the
        corresponding topdir is done starting from its parent
        directory.  This directory containing *source_file* does NOT
        have to be manifest.path in this case, allowing parsing of
        additional manifest files besides the "main" one in an
        installation.

        If only *topdir* is given, that directory must be a west
        installation root, and its manifest.path will be used to find
        the source file.

        If both *source_file* and *topdir* are given, the returned
        Manifest object is based on the data in *source_file*, rooted
        at *topdir*. The configuration files are not read in this
        case.  This allows parsing a manifest file "as if" its project
        hierarchy were rooted at another location in the system.

        Exceptions raised:

        - `west.util.WestNotFound` if a .west directory is
          needed but cannot be found.
        - `MalformedManifest` in case of validation errors.
        - `MalformedConfig` in case of a missing manifest.path
          configuration option or otherwise malformed configuration.
        - `ValueError` if topdir is not a west installation root
          and needs to be

        '''
        if source_file is None and topdir is None:
            # neither source_file nor topdir: search the filesystem
            # for the installation and use its manifest.path.
            topdir = util.west_topdir()
            source_file = _west_yml(topdir)
            return Manifest(source_file=source_file, topdir=topdir)
        elif source_file is not None and topdir is None:
            # just source_file: find topdir starting there.
            # fall_back is the default value -- this is just for emphasis.
            topdir = util.west_topdir(start=os.path.dirname(source_file),
                                      fall_back=True)
        elif topdir is not None and source_file is None:
            # just topdir. verify it's a real west installation root.
            msg = 'topdir {} is not a west installation root'.format(topdir)
            try:
                real_topdir = util.west_topdir(start=topdir, fall_back=False)
            except util.WestNotFound:
                raise ValueError(msg)
            if PurePath(topdir) != PurePath(real_topdir):
                raise ValueError(msg + '; but {} is'.format(real_topdir))
            # find west.yml based on manifest.path.
            source_file = _west_yml(topdir)
        else:
            # both source_file and topdir. nothing more to do, but
            # let's check the invariant.
            assert source_file
            assert topdir

        return Manifest(source_file=source_file, topdir=topdir)