Allow stack traces for unexpected errors to propagate to the user.
Leave the CalledProcessError handling since subprocess failure is
basically a RuntimeError and can happen for many reasons that
aren't west's fault.
Fixes#79.
Signed-off-by: Marti Bolivar <marti@foundries.io>
I got tired of typing 'list-projects' all the time.
'list' might be a bit less obviously related to projects, but I don't
think it would be that bad.
Signed-off-by: Ulf Magnusson <ulfalizer@gmail.com>
The URL is taken literally from the manifest. It's unlikely that anyone
would put a URL starting with a '-', but having weirdly named stuff be
correctly interpreted by Git could help with diagnosing bugs.
Maybe some other Git commands could be tightened up too, but they looked
safe from a glance.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
This doesn't affect the default functionality of the runner, but it's
nicer to flash hex files if possible. For example, some tools find it
easier to post-process hex files than binary files for flashing on the
board.
Keep test cases up to date.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Signed-off-by: Michael Scott <michael@foundries.io>
Set ZEPHYR_BASE in the environment for the duration of the command if
possible.
In order of decreasing precedence, get ZEPHYR_BASE from:
1. The west command line
2. The manifest file project named 'zephyr'
3. The calling environment's ZEPHYR_BASE
If the calling environment's ZEPHYR_BASE differs from the value
actually used, emit a warning. The user has probably run a zephyr-env
script in another Zephyr directory and forgotten about that, and will
almost certainly not like what they get.
Hopefully over time we can deprecate the zephyr-env scripts entirely,
but that remains to be seen.
Fixes: #46
Signed-off-by: Marti Bolivar <marti@foundries.io>
While implementing a manifest-based scan for the zephyr project, I
noticed that we aren't ensuring that projects always have distinct
paths (it's generally OK for them to have non-overlapping names; they
just can't be cloned to the same directories on the file system).
Add a check for that in west.manifest, along with a regression test.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Currently, west.manifest mostly can just return a list of Project
types, each of which is a namedtuple for the project contents we care
about.
It would be better and more flexible to have a "real" data type for
the manifest, along with concrete representations for its contents
such as default values and remotes.
Reimplement the module to add just these things, adding Manifest,
Defaults, and Remote types, and re-working the Project namedtuple into
a class type. All of these (except Manifest) use __slots__ to restrict
their attributes.
Keep the current users and test cases up to date, extending the tests
a bit more as well. This moves a bit more code out of project.py into
west.manifest.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Exercise both invalid manifest detection and correct parsing of valid
manifests. To make it easier to write tests for invalid manifests,
just glob for any invalid_*.yml files in the same directory as the
test file.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Add checks for nonexistent default remotes, projects without well
defined remotes, and projects without remotes (this last one in the
absence of a default remote).
Signed-off-by: Marti Bolivar <marti@foundries.io>
pykwalify raises a CoreError if you pass it an empty manifest. This is
by definition malformed, but the current manifest code lets this
exception pass rather than catching it and reporting the issue.
Avoid the exception by explicitly checking for, and handling, empty
manifest data. This has the ancillary benefit of only loading the
manifest file once.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Add a new module for parsing the manifest, containing the Project
definition, as well as a routine for extracting projects from a
manifest. For now, this is a pretty straightforward copy/paste job,
but we do avoid calling log.die from the manifest parsing code by
adding a new MalformedManifest exception type.
Move the manifest schema to src/west/manifest-schema.yml as part of this.
Signed-off-by: Marti Bolivar <marti@foundries.io>
We are getting user feedback about missing dependencies (like
"commands" and "log") that are actually imports of internal west
modules by those names.
We've been playing games with the python path to omit typing "west",
but this always caused inconsistency (as the bootstrapper version is
imported as west._bootstrap.version) and now it's causing outright
user confusion.
Let's just be consistent and import everything as west.xxx.
Fixes#57.
Signed-off-by: Marti Bolivar <marti@foundries.io>
The comment added to print_version_info() explains the situation:
The bootstrapper will print its own version, as well as that of
the west repository itself, then exit. So if this file is being
asked to print the version, it's because it's being run
directly, and not via the bootstrapper.
Rather than play tricks like invoking "pip show west" (which
assumes the bootstrapper was installed via pip, the common but
not universal case), refuse the temptation to make guesses and
print an honest answer.
This will go away as we phase out the west doskey macro and shell
script in the Zephyr repository.
Signed-off-by: Marti Bolivar <marti@foundries.io>
The error message is confusing since what's output is not what was
tested. We also want to make sure to do absolute paths on both cached
and source directories just in case of issues (e.g. on Windows,
case-sensitivity is a potential source of problems).
(We can't use os.path.samefile because that's not cross-platform.)
Signed-off-by: Marti Bolivar <marti@foundries.io>
Also to allow this version of West to be contained within a monorepo
Zephyr tree, make sure we don't assume the bootstrap package is
available when determining its version.
Signed-off-by: Marti Bolivar <marti@foundries.io>
We need to be able to keep copying west into Zephyr's scripts/meta/
directory, because that's the only way for bug fixes and commands
which are safe for monorepo installs (like "attach") to make their way
back to users.
To make that happen, detect if the current west tree -- not the
directory from which it's called from -- is part of a multi-repo
installation, and expose the project related commands if so.
This allows a copy of west in a monorepo Zephyr to work as expected. A
multi-repo installation will be invoked either
1. by the bootstrapper
2. by a launcher shim in zephyr itself (in case zephyr-env.{sh,cmd}
was run)
In case 1., the west install discovered by the bootstrapper is
multi-repo by construction. In case 2., the launcher shim will invoke
the multi-repo version of west in TOP/west/west, not
TOP/zephyr/scripts/meta/west, which is multi-repo as well.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Allow finding the top level west install directory from any starting
point on the system with a new start kwarg in west_dir() and
west_topdir().
Add a new convenience predicate, in_multirepo_install(), for simply
checking whether or not a starting point is part of a multi-repo west
installation.
Signed-off-by: Marti Bolivar <marti@foundries.io>
In order to simplify debugging and support to users starting with west,
print the location of both the bootstrapper and west itself when running
west --version.
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
Shorten the code a bit while preserving readability.
SVN also uses e.g. http:// and file://, so checking the URL scheme is
probably not a reliable way to guess intention.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Reorganize parameters to match git-clone(1), and add a '--' to allow
weird project names (which could indirectly give more informative error
messages). This ought to be done for the project code too.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Directly check whether west/.west_toplevel exists instead of checking if
'west' is a directory whose contents include '.west_toplevel', which is
also a bit more efficient.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Put the version into src/west/_bootstrap/version.py, and extract it in
setup.py. This will allow us to inspect it in the bootstrapper and
west itself.
For details, see: https://packaging.python.org/guides/single-sourcing-package-version/#single-sourcing-the-version
This option was chosen from the many given there mainly because it
worked cleanly with west's split into bootstrapper and "main" pieces.
Fixes#45
Signed-off-by: Marti Bolivar <marti@foundries.io>
This accomplishes two goals:
1. cleans up the installation namespace by installing all west-related
code into a 'west' namespace package
2. allows us a somewhat clean way to share a version specifier among
the bootstrapper, west itself, and setup.py
Signed-off-by: Marti Bolivar <marti@foundries.io>
Exec doesn't work well on windows:
https://bugs.python.org/issue19124
While we're here, delete the extra warning. West itself should print
an error if something goes wrong.
Signed-off-by: Marti Bolivar <marti@foundries.io>
The instructions for using an arbitrary west installation are OK, but
the docs on how to create and install a custom bootstrapper could use
some fixes. Change them to build and install the bootstrapper from a
wheel instead, and provide instructions for how to back that change
out.
(Prefer wheel here to follow the general trend treating them as the
favored package format, and also because the wheel format is
cross-platform.)
While we're here, remove the instructions on executing directly out of
the repository. You can run a custom "main" west via instructions that
are added in this patch, and it doesn't make much sense to run the
bootstrapper unless you've installed it as an entry point script
somewhere.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Remove support for python setup.py test in favor of an
environment-variable based approach. Add Windows instructions as well.
With this patch, west can now be installed from a setuptools source
distribution (sdist), e.g. with "pip3 install west-0.1.99.tar.gz".
Signed-off-by: Marti Bolivar <marti@foundries.io>
The use of requirements.txt is resulting in an incorrectly packaged
source distribution (sdist) for west. This is because while setup.py
is copied into the sdist archive, requirements.txt is not, so using
"pip install <sdist>.tar.gz" fails like so (shown with the 0.1.0
sdist):
$ wget 77593677335ba03c2b7122c07c5b4d/west-0.1.0.tar.gz
$ pip install west-0.1.0.tar.gz
[...]
FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
[...]
I didn't notice this when uploading 0.1.0 because pip prefers to
install wheels over sdists, our 0.1.0 wheel works, and I never tested
installing the sdist.
Further review of the way requirements.txt is meant to be used
(https://packaging.python.org/discussions/install-requires-vs-requirements/)
seems to indicate that the two are not meant to be used together.
Work towards fixing the sdist by inlining the requirements.txt
contents into setup.py. (Another issue with tests_requirements.txt is
next).
Signed-off-by: Marti Bolivar <marti@foundries.io>
The --context output is pretty long, and is divided into multiple
sections. Colorize the section headers to make them easier to visually
distinguish.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Use some of the helpers from the build module (not the build command
itself, but the helper module with shared code related to build) to
improve the heuristics used to find the build directory if it is not
explicitly given:
1. if the build directory is given, use that
2. otherwise, if os.getcwd()/build/ is a build directory, use that
3. default to os.getwcd(), but crash with an error if it's not a
build directory
Signed-off-by: Marti Bolivar <marti@foundries.io>
- Require the user to pass --force if the source directory doesn't
contain a CMakeLists.txt. That should never happen, and probably
means they are not in an app source directory and forgot to use -s.
- Print the build directory in a message involving an error about it.
Signed-off-by: Marti Bolivar <marti@foundries.io>
Similarly to how Zephyr indicates the next development version with a
.99 patch level, update west so it's clear this is post-0.1.0.
Signed-off-by: Marti Bolivar <marti@foundries.io>
I assumed WEST_TOPDIR was the path to the top-level West directory and
not the name of the west/.west_topdir file. Rename it to WEST_MARKER to
avoid confusion.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
The self-update mechanism checks the West and manifest repositories in
west/ for upstream changes and rebases them to the latest version if any
are found.
'west fetch' and 'west pull' run a self-update before fetching any
project data. It probably makes sense to always work with the latest
version of West and the manifest there. The self-update can be
suppressed with --no-update.
There's also a 'west update' command for manually updating West and/or
the manifest.
West automatically restarts itself after a self-update, before running
any commands or parsing the manifest. This makes it safe to add a new
feature to West and immediately start using it in the manifest.
The restarting is done with a plain exec(3). Getting this to work
required a few changes:
- West now uses absolute instead of relative imports, to make it
possible to execute src/west/main.py directly. This also makes it a
bit simpler to work on West. Relative imports seem to be discouraged
when googling around a bit.
__init__.py was removed from src/west. West is more of an application
than a package now (though it uses some packages internally).
- The internal 'cmd' package was renamed to 'commands', to avoid
clashing with a module in the Python standard library.
'runner' was renamed to 'runners' as well, for consistency.
The tests now have to be run from the West repository root with
'PYTHONPATH=src/west pytest'. The previous testing setup "just working"
relied on having run 'pip3 install -e .' first, which happened to add
src/west to the path due to the bootstrap script being there.
__init__.py was removed from the test directories as well. Packages
mostly make sense for tests if there are naming collisions, and naming
collisions will be obvious if packages aren't used.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Add setuptools-scm to test_requirements.txt to work around an issue on
Python 3.4:
distutils.errors.DistutilsError: Could not find suitable
distribution for Requirement.parse('setuptools-scm>=1.15.0')
Not sure why it didn't appear before. Maybe something in CI changed.
See https://github.com/pypa/pypi-legacy/issues/322 and
https://github.com/pytest-dev/pytest-xdist/issues/136. I suspect the
issue is related to setup_requires= using easy_install.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>