Commit Graph

722 Commits

Author SHA1 Message Date
Martí Bolívar c50d342cc6 update: add --name-cache, --path-cache options
This allows the user to clone projects for the first time from
existing local repositories instead of fetching from the network.

For an example, consider this west.yml:

  manifest:
    defaults:
      remote: myorg
    remotes:
    - name: myorg
      url-base: https://github.com/myorg
    projects:
    - name: foo
      path: modules/foo
      revision: deadbeef
    - name: bar
      path: modules/bar
      revision: abcd1234

Suppose the 'foo' and 'bar' repositories are already available in a
/var/my-name-cache directory, like this (.git locations shown for clarity):

  /var/my-name-cache
  ├── bar
  │   └── .git
  └── foo
      └── .git

You can then run:

  west update --name-cache /var/my-name-cache

And the 'foo' and 'bar' projects will be cloned from '/var/my-name-cache/foo'
and '/var/my-name-cache/bar', respectively, before being updated.

NOTE:

  It's /var/my-name-cache/foo, NOT /var/my-name-cache/modules/foo.

  Project names are unique in a west manifest, so putting them in the
  top level directory is safe. Doing it this way lets you use
  --name-cache without duplicating cache repositories if project
  paths might move around.

By contrast, if you had this /var/my-path-cache directory:

  my-path-cache
  └── modules
      ├── bar
      │   └── .git
      └── foo
          └── .git

You could run:

  west update --path-cache /var/my-path-cache

And get a similar result: the 'foo' and 'bar' projects will be cloned
from '/var/my-path-cache/modules/foo' and
'/var/my-path-cache/modules/bar', respectively.

Using either option, west update won't hit the network at all if the
'deadbeef' and 'abcd1234' SHAs are already available locally and
the (default) '--fetch=smart' strategy for west update is used.

If both options are given, both caches are checked; --name-cache is
checked first.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-04-13 07:44:17 -07:00
Martí Bolívar 3bdd02674a init: check git version from get_head_branch()
It's been bugging me that we are making assumptions about the git
version without proper checks for a while.

Now we can start using WestCommand.git_version_info where appropriate
instead of making assumptions.

I still honestly have no idea what version of git is the minimum
required by west (we always make sure the version on the latest Ubuntu
LTS passes the test suite, providing some hint). That's unfortunate,
but we can start being more careful now to implement fallbacks if we
use 'new' features.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-04-07 15:50:55 -07:00
Martí Bolívar 7983cba0f0 WestCommand: lift die_if_no_git from project.py
This allows us to reuse the same '_git' attribute already
added to WestCommand.git_version_info.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-04-07 15:50:55 -07:00
Martí Bolívar 54156b57f9 project.py: remove unused warn_once_if_no_git()
Commit c4a3bb8cb7 moved this helper from
manifest.py without adding a user for it. Remove it; the only thing we
are actually using is die_if_no_git().

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-04-07 15:50:55 -07:00
Martí Bolívar 0e348aefed WestCommand: add git_version_info
This is a helper property for getting the git version.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-04-07 15:50:55 -07:00
Martí Bolívar 6742ff5cf4 WestCommand: lift check_call, check_output from Init
Move some helpers into the main WestCommand class so they can be used
from elsewhere.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-04-07 15:50:55 -07:00
Gerard Marull-Paretas 04f6b67f70 manifest: fix docstrings for Project
Submodule was single-quoted (``) causing reference errors.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2021-03-17 08:26:27 -07:00
Martí Bolívar 0bfe88729d tests: avoid bogus shlex.split() output on windows
On Windows, shlex.split('foo C:\\bar\\baz') results in:

    ['foo', 'C:barbaz']

This is not what we want; C:\\bar\\baz is a path and backslashes
should be preserved.

This has the result of making this test lead to different results
depending on whether the manifest URL is used by west as it runs or
not.

We could add posix=False to the shlex.split() call on Windows to avoid
this, but it's easier and more readable to just split the arguments
ourselves.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-15 09:21:37 -07:00
Martí Bolívar dfc16dcc2b west init: get default manifest-rev from remote
Instead of hard-coding a default revision to fetch from the remote,
get it from the remote URL itself if it's not provided by the user.

If that fails, we ask for the --manifest-rev option to be provided
explicitly.

This makes the code more robust by allowing each remote to dictate
policy instead of making assumptions. It is especially important as
many projects use 'main' instead of 'master' now.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-15 09:21:37 -07:00
Martí Bolívar 9a3d35fd71 version: bump version for post-0.10 development
This branch is now open for development again.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:25:04 -08:00
Martí Bolívar ddc23a84d8 manifest: fix validate()
This fix is present in v0.10-branch, but in the wrong commit due to a
botched rebase. Fix it.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:25:04 -08:00
Martí Bolívar 28c76a5206 manifest: re-work group filter handling
For schema version 0.10:

Allow group-filter values from imported manifests to affect the top
level manifest group filter. Simplify the results so that
Manifest.group_filter is just a list of disabled groups.

Manifests have the same precedence on the final group filter as they
do on project definition: manifests which appear earlier in the import
order have higher precedence on the group filter, just as they have
higher precedence when it comes to whether a project definition comes
from them or is ignored.

Delay loading the manifest.group-filter value from the local
configuration file until we actually need to know its value in
is_active().

Preserve 0.9 semantics if that is explicitly requested, but warn if
there are group filters anywhere.

Add test cases for the updated group-filter behavior, and regression
tests to ensure that 0.9 semantics are preserved when explicitly
requested.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar 330309756d manifest: check the schema version against valid values
This will be required by a later patch which uses the value '0.9'
explicitly to see if the user is requesting group-filter behavior that
we're going to change. It is also just a good way to tighten up the
error handling.

The intent here is to reject '0.9.99' as an invalid schema version, to
make sure nobody tries to do that. We're bumping the schema from 0.9
to 0.10 as part of the v0.10.0 development branch. Any unreleased
master branches during that time will have to request schema version
0.10 instead of 0.9.99 or something like that.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar 9feab36e0e manifest: move some type aliases around
Move RawGroupType right before its only point of use.

Move GroupFilterType and GroupsType to the top level list of type
aliases, as prep work for using them in more places. Change the '#:'
comment style to '#' while we're here; the '#:' style is reserved for
comments which are also docstrings that end up in Sphinx, which
doesn't apply here.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar 2cc96eda61 manifest: improve _import_ctx readability
Add more source code comments describing this internal class's
purpose. Use kwargs for fields whenever initializing an instance.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar 9e585ea86d manifest: clear up import map filter vs group filter
Change some things related to import map names:

- rename the _import_ctx 'filter_fn' attribute to 'imap_filter',
  along with local variables using the same name
- rename _filter_ok() to _imap_filter_allows()
- rename _and_filters() to _compose_imap_filters()
- rename _new_ctx() to _compose_ctx_and_imap()
- adjust the debug logging when an import map filter rejects a project

This helps disambiguate filtering on projects that is due to import
map allowlists and blocklists versus project group filters.

These are all internal names: there are no API changes here.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar b01ae87797 manifest: fix group filter round trip
Freezing, resolving, etc. a manifest file should result in output that
reflects the input's group-filter value too, but it doesn't. Fix that.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar 984aec8ecd manifest: allow missing projects list
It's annoying to have to specify projects lists in some cases
when all you're trying to do is exercise something else.

Though the number of situations where a manifest with no projects is
useful may be limited, they nonetheless exist, so make it possible.

This is a backwards incompatible change, so bump the schema version.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar c90b4157e4 __init__: add null handler for 'west' logger
API modules like west.manifest are using the standard logging module.
This module prints messages at warning severity or above to stderr by
default.

That prints messages twice when a west command configures its own
logger, like this:

  $ west foo
  some warning message
  WARNING: some warning message

The first line comes from the print to stderr done by the default
handler. The second one is from a ProjectCommandLogHandler.

Disable the first message, which we do not want, by registering a null
handler for the top level. This results in just the
ProjectCommandLogHandler output being shown, like this:

  $ west foo
  WARNING: some warning message

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-03-10 12:56:35 +01:00
Martí Bolívar 3eb1732b6a tests: change create_workspace and_git kwarg default
Looking at the users, the better default is clearly True.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-02-15 15:32:51 -08:00
Martí Bolívar 6104682972 ci: test on 3.9 too
This has been out for a while.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-02-10 09:06:29 -08:00
Martí Bolívar 2824c3d04b tox.ini: add comment justifying tox
For the curious.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-02-10 09:06:29 -08:00
Martí Bolívar d57aa43d6e tests: ensure we're run via tox
Otherwise, setup functions that set git config variables like
user.name are potentially dangerous to run.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-02-10 09:06:29 -08:00
Martí Bolívar 8ef8a1c117 tests: remove WEST_SKIP_SLOW_TESTS
There's just one test that's being skipped this way, and it's not that
slow compared to the rest.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-02-10 09:06:29 -08:00
West Test 02444d0583 manifest: make optional the 'name' attribute unused by Submodule
Forcing users to define something unused is not just tedious, it's also
confusing.

Note the name attribute is mostly unused by git submodule too.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
2021-02-08 16:07:28 -08:00
West Test 8e72a9cf90 manifest: refactor _is_submodule_dict_ok(); add nested _assert()
Add nested _assert() function that raises an exception and reduces
"return False" duplication. Because of the added scaffolding this adds
about 10 lines, on other hand it brings all conditions together in one
place, removes negations and makes it easier to add conditions.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
2021-02-08 16:07:28 -08:00
Martí Bolívar fac7c84567 manifest-schema.yml: fix a comment
This is stale from before the move to group-filter and changing its
semantics to requiring a + and -.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-02-02 09:39:32 -08:00
Martí Bolívar 9d9b29b1fb Update some group enable/disable stragglers
Some test cases are still referring to groups as things that can be
'allowed' and 'blocked'. We switched that language to 'enabled' and
'disabled' in code and documentation. Keep tests up to date.

Do the same in manifest-schema.yml.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-27 01:06:15 -08:00
Martí Bolívar 06ed61f97a Rename some things to 'group-filter' from 'groups'
As a result of review of the project groups feature documentation,
change some of the names to be more clear, and be a bit more forgiving
in the error handling.

A project's 'groups' list remains the same. No changes there.

However, we make the following changes:

- 'manifest: groups:' is now 'manifest: group-filter:'
- we add a west.manifest.Manifest.group_filter value, exposing
  'manifest: group-filter:' after validation and string conversion
- the config option 'manifest.groups' is now 'manifest.group-filter'
- invalid values in manifest.group-filter are downgraded to warnings
- the west update '--groups' option becomes '--group-filter', with
  a slightly shorter name '--gf' if you can't handle that

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-27 01:06:15 -08:00
Ilya Tagunov fa7bba2d0c commands: import importlib.util explicitly
Python environments usually do not import importlib.util
unless asked to do so specifically:

>>> import importlib
>>> importlib.util
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'

Therefore it would be better to import importlib.util explicitly.
Some commands (e.g. west zephyr-export) do not work on my setup
without that change.

Signed-off-by: Ilya Tagunov <tagunil@gmail.com>
2021-01-26 11:21:07 -08:00
Martí Bolívar 2c06baaf50 Bump versions for post-0.9 development
This branch is now moving independently of v0.9-branch.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-22 09:20:23 -08:00
Martí Bolívar 1b04e7a48e groups are 'enabled' or 'disabled' now
During review of the documentation for the 0.9 release, the following
changes to manifest groups were requested:

- groups should be 'enabled' and 'disabled', not 'allowed' or
  'blocked'

- enabling a group should be done by prefixing its name with '+'
  in "manifest: groups:" or manifest.groups

Projects are still 'active' or 'inactive'.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-21 09:32:41 -08:00
Martí Bolívar e467a6ec5f manifest: empty strings are not valid groups
This case was overlooked during testing.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-21 09:32:41 -08:00
Martí Bolívar 197bda1c6c west init: fix "self: path: foo/bar"
If the manifest repository path is placed in a nested subdirectory of
the workspace, shutil.move() does not guarantee success. Strangely,
this works on Linux, even though it probably shouldn't, but it fails
on Windows. Fix that and add a regression test.

Fixes: #463

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar bfbc543863 west update: fix --groups help
There's a missing word that makes all the difference.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar f638e3fe57 project.py: make some debug logs consistent
Use consistent debug text when skipping inactive projects.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 2bd3950810 west update: update anything explicitly requested
This makes 'west update foo' behavior consistent with
'west list foo' in case 'foo' is inactive: we were given a specific
project, so we should "do the thing" even if the project is inactive.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar f57d324113 tests: add test case for updating a blocked group
This is currently failing.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 209a874f0a project.py: improve help text
Miscellaneous help text improvements. Add missing information, adjust
misleading bits, and clear up usage.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 1f39be57a5 west update: inline a helper procedure
_init_project() is only called once in the entire file, so just inline
it into its caller.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 8992e69460 west update: add submodule update to --stats output
We aren't individually tracking the time it takes to update a
project's submodules when we run west update --stats; fix that.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 77c093203c west update: clean up helper procedure
There's no need for the call_location variable in update_submodules();
Project.git() runs in the project's abspath by default.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 16f071d4f0 manifest: add Submodule documentation
Add it to the documented instance attributes within a Project, and
document the NamedTuple itself.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar bbd34c24b7 manifest: fix up and rename a submodules helper
The _get_submodules() method is setting a 'submodules' attribute on
the Manifest object. It should just return a value instead. The
submodules data is per-project, so there's no need for the Manifest
object to track this, since it already has a list of projects.

Fix that, renaming the method to _load_submodules() as well for
consistency with the other helper procedures called by _load().

Move its definition underneath _validate_project_groups() while we're
here, since that is the previous step inside the caller
(_load_project()).

Align the error handling messages with _load_imap()'s by printing the
name of the project that's causing problems on error.

Convert the docstring to a comment like we do for all the other
private helpers, so west API users calling help() aren't encouraged to
rely on its behavior.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 9228057446 manifest: fix SubmodulesType
The type's values are either lists of Submodule objects, or bools.

Wrapping this in Optional means that None is a valid value, which
isn't ideal, as it forces users to check for that type. The value
False is just as good in this case, so let's just use that.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Martí Bolívar 2ddfaca377 manifest: fix submodule dict validation logic/namespace
The Manifest.is_submodule_ok() helper is allowing extra beyond 'name'
and 'path'. Fix that so we make sure that if the dict is present, it
has exactly those keys.

Move it to a top-level helper named _is_submodule_dict_ok(). The '_'
prefix is a hint that it's private; Python methods that don't begin
with '_' are usually considered fair game for public use.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2021-01-20 18:44:48 -08:00
Kamil Kasperczyk 5430edad97 update: add support for git submodules in west update.
The submodules were added to the manifest in order to enable
updating projects submodules when performing update operation.

Description of the `west update` command behaviour regarding
submodules:
* Submodules can be defined in the west manifest file
for the specific project, by adding submodules: field.
* Submodules field is not required for every project
and should be added only if it is desired.
* Submodules field may have boolean values (true/false)
or be the list of specific submodules.
* Assigning false value to the submodules field means
that submodules are not used for given project. Example
presented below:
- name: example_project
  submodules: false
* Assigning true value to the submodules field means
that all submodules attached by git to the project repository
will be updated. Example presented below:
projects:
- name: example_project
  submodules: true
* Assigning list of submodules to the submodules field
means that only those submodules present on the list will be
updated (no matter that there might be any other submodules
attached in git). Every element of the submodules list should
have the name and the path fields (which is an absolute path
to the directory where submodule should be updated). Example
presented below:
- name: example_project
  submodules:
    - name: first_submodule
      path: first_submodule_dir/repo
    - name: second_submodule
      path: second_submodule_dir/repo
* Submodules for each project are defined independently,
so in some cases they might have assigned true/false values,
lists or not be defined at all.
* When calling `west update` command, submodules for each project
are detected and updated with the `recursive` option.
* By default submodules are updated using `--checkout` strategy,
however it is possible to update them using `--rebase` strategy,
by calling `west update -r` command.

What `west update` command does not do with the submodules:
* Updating submodules does not support `west update -k` option.
In case of using such command, `-k` option is ignored
and submodules are updated using default `--checkout` strategy.
* Assigning true or false value to the submodules field does not
apply to the all projects and their submodules, but only to the all
submodules of a specific project for which submodules field
was defined.

Signed-off-by: Kamil Kasperczyk <kamil.kasperczyk@nordicsemi.no>
2021-01-11 13:43:40 -08:00
Martí Bolívar 36f3f91e27 configuration: fix round-trip bugs by removing configobj
West has historically relied on the third-party configobj library for
writing configuration files instead of using the standard library's
configparser module. The reason why is that configobj has round-trip
support for comments.

However, the public reading API uses configparser. Up until now, we
were assuming that the two were compatible for the simple purposes we
needed, and indeed they've proven compatible "enough" that the
different code paths on read vs. write haven't been an issue.

This has become a problem now that we are introducing the
manifest.groups configuration option, though, because its value
contains commas. The configparser and configobj file formats have a
semantic difference between these two options, though:

   [section]
   foo = "one,two"
   bar = one,two

The difference is:

- in configobj, 'foo' is the string "one,two" and 'bar' is the list
  ['one', 'two']

- in configparser, 'foo' is the string '"one,two"' and bar is the string
  'one,two'

Further, the configobj library automatically adds quotes around any
string that contains commas to enforce this distinction.

This is breaking round-trips, since:

  west config section.foo one,two   # configobj writes "one,two"
  west config section.foo           # configparser reads '"one,two"'

Looking at it further, configobj development seems to have stalled in
2014, and the most significant user it claims in its
documentation (IPython) has moved on to .py and .json configuration
files.

This isn't worth the hassle. Just drop the configobj dependency and
use configparser everywhere. This will delete comments that users have
added to their configuration files and may otherwise reorder sections,
but having the round-trip semantics correct is more important than
that.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-12-18 13:42:40 -08:00
Martí Bolívar 91cca37903 tests: add xfail for round-tripping a string
This is currently failing because we are using configparser to read,
but configobj to write. The two don't seem to be compatible.

Setting an option to 'bar,baz' uses configobj, which writes the string
"bar,baz" -- with quotes -- to the config file. Then when we read it
back with configparser, we get the value '"bar,baz"' -- quotes are
not stripped.

This will need to be fixed.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-12-18 13:42:40 -08:00
Martí Bolívar 66a5da3ab5 west config: tweak help string
Make it fit on one line in the west help output.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-12-18 13:42:40 -08:00