Commit Graph

918 Commits

Author SHA1 Message Date
Marti Bolivar a52159b043 west: main: don't swallow Exception
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>
2018-10-18 08:09:39 -06:00
Ulf Magnusson ac1d631b4a Rename 'list-projects' to 'list'
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>
2018-10-10 09:54:21 -06:00
Ulf Magnusson 96e2cd0b27 commands: projects: Put '--' before URL in 'git remote add'
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>
2018-10-05 10:17:34 -06:00
Marti Bolivar b678172f60 Set bootstrap version to post-release 0.2.99
This mirrors what gets done in Zephyr.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-10-05 16:00:23 +02:00
Marti Bolivar 21fda3ab1a West 0.2.0
Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-10-05 15:32:47 +02:00
Marti Bolivar d722bb0b6f runners: pyocd: prefer hex files to bin files if possible
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>
2018-10-02 11:35:58 -06:00
Marti Bolivar b001a1243d West 0.2.0rc3
Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-10-02 19:29:45 +02:00
Marti Bolivar df134cea13 main.py: set ZEPHYR_BASE whenever possible
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar d21374bd55 west.manifest: forbid duplicate project paths
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar 7527b98442 Reimplement west.manifest with more complete abstract types
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar 57e18b3ab1 Add test cases for west.manifest.
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar f4a1f5d685 west.manifest: fix some remote validation issues
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar 1b973297f6 west.manifest: don't crash if the manifest contains no data
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar 1104f45e1e Extract manifest parsing to west.manifest
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>
2018-10-02 01:20:57 +02:00
Marti Bolivar 166ed2457e Import all west modules from west.
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>
2018-10-01 15:12:54 -06:00
Marti Bolivar 797dce2366 README.rst: fix instructions so users get 0.2.0rc2 from pypi
This is leading early testers astray.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-10-01 15:12:54 -06:00
Henrik Brix Andersen 76c162dbb1 runner: pyocd: add support for specifying SWDCLK frequency
Add support for specifying the SWDCLK frequency in Hz for pyOCD.

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
2018-09-25 12:59:58 -06:00
Marti Bolivar fff3c89926 West 0.2.0rc2
Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 18:05:53 +02:00
Marti Bolivar 682dda9907 west/main.py: don't try to guess the bootstrap version at all.
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>
2018-09-25 17:51:17 +02:00
Marti Bolivar a3b124e809 commands: build: clean up help output for missing source dir
Treat the case of a missing source directory specially, to make the
error message clearer.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 17:51:17 +02:00
Marti Bolivar 65a6ec5b0d commands: build: fix source directory consistency check
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>
2018-09-25 17:51:17 +02:00
Marti Bolivar abc308e090 commands: project: don't assume there is a defaults key
The defaults key in a manifest is optional. Don't assume it's present.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 17:51:17 +02:00
Marti Bolivar 9f974de1cc west/main.py: fix west repository location check
This is currently printing the path to west/src/west, not west/.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 17:51:17 +02:00
Marti Bolivar f45f3b739e west/main.py: fix version checks for monorepo installations
Another patch for monorepo compatibility.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 17:51:17 +02:00
Marti Bolivar de2ec3ba22 west/main.py: don't assume a bootstrapper is installed
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>
2018-09-25 17:51:17 +02:00
Marti Bolivar 2872e77a1c west/main.py: only expose project commands in multi-repo installations
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>
2018-09-25 17:51:17 +02:00
Marti Bolivar f744592b81 west.util: generalize top-level directory detection
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>
2018-09-25 17:51:17 +02:00
Marti Bolivar b75647fd27 bootstrap: add missing space to west version printline
Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 17:51:17 +02:00
Marti Bolivar e78b43ccc0 bootstrap: fix rebase error
Fix a merge that didn't rebase properly.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-25 17:51:17 +02:00
Carles Cufi 56b6c31bcf version: Print script location next to version
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>
2018-09-24 14:40:05 -06:00
Ulf Magnusson 197aa64968 bootstrap: Clean up clone() a bit
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>
2018-09-24 12:26:29 -06:00
Ulf Magnusson a1a8f3cd40 bootstrap: Clean up 'git clone' parameters a bit
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>
2018-09-24 12:26:29 -06:00
Ulf Magnusson 32a1ceaf91 Simplify west/.west_toplevel existence checks
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>
2018-09-24 12:24:53 -06:00
Marti Bolivar 77c78f2beb West version v0.2.0rc1.
Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-24 00:34:22 +02:00
Marti Bolivar 2c14392b9f Extract west version from a Python file
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar c497abee6c bootstrap: move to west._bootstrap
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar 1a216a0aa2 bootstrap: use subprocess instead of exec
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar 3e72d2ac25 tests: ensure all runners are imported in west.runner.core
Try to make sure the duct tape in west.runner.core doesn't tear.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-24 00:34:22 +02:00
Marti Bolivar a9785cdfe2 Update instructions for installing a custom bootstrapper
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar d671e63245 Decouple testing from setup.py, fixing sdists
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar 867f01243e Move requirements.txt contents into setup.py
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar 4e889e4b81 commands: run_common: colorize context output
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar e0dfd27e2b commands: run_common: improve build directory detection
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>
2018-09-24 00:34:22 +02:00
Marti Bolivar ad20631ce5 commands: build: help the user recover from more errors
- 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>
2018-09-24 00:34:22 +02:00
Marti Bolivar 91605b3ed7 commands: build: fix BOARD check
Add a missing check for a source of the BOARD CMake variable.

Signed-off-by: Marti Bolivar <marti@foundries.io>
2018-09-24 00:34:22 +02:00
Marti Bolivar 35d9e72da3 commands: build: colorize informational messages 2018-09-24 00:34:22 +02:00
Marti Bolivar 488ecece72 setup.py: bump version to 0.1.99
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>
2018-09-24 00:34:22 +02:00
Ulf Magnusson b94d57fd2f Rename WEST_TOPDIR to WEST_MARKER
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>
2018-09-23 12:23:21 -06:00
Ulf Magnusson f8bd521dea Add self-update for West and the manifest
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>
2018-09-21 16:50:54 -06:00
Ulf Magnusson 70b6892575 test_requirements.txt: Add setuptools-scm, to fix Python 3.4
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>
2018-09-21 16:50:54 -06:00