-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
manifest.project-filter
#664
manifest.project-filter
#664
Conversation
There's a field whose initialization procedure differs enough from the comment describing it that it's worth clarifying. Signed-off-by: Martí Bolívar <[email protected]>
The filename attribute no longer exists. Instead, we have a better str() result for a ManifestImportFailed. Use it instead. Signed-off-by: Martí Bolívar <[email protected]>
Fixing the test case logic causes it to fail, so mark it xfail. This is bug zephyrproject-rtos#663. The test case test_group_filter_self_import() is incorrect, which conveniently enough provides steps to reproduce. The test case should read as follows (patch applies to f6f5cf6): diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 14f2941..e934b71 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -2828,7 +2828,7 @@ def test_group_filter_imports(manifest_repo): sha2 = setup_project('project2', '[+gy,+gy,-gz]') v0_9_expected = ['+ga', '-gc'] - v0_10_expected = ['-ga', '-gb', '-gc', '-gw', '-gy', '-gz'] + v0_10_expected = ['-ga', '-gb', '-gc', '-gw', '-gz'] # # Basic tests of the above setup. In other words, west incorrectly concludes that group 'gy' is disabled in this scenario, when it should be enabled. The test creates the following layout, where ./mp/west.yml is the main manifest: ─────────────────────────────────────── File: ./mp/west.yml ─────────────────────────────────────── manifest: version: "0.10" group-filter: [+ga,-gc] projects: - name: project1 revision: ... import: true - name: project2 revision: ... import: true self: import: self-import.yml .. ─────────────────────────────────────── ─────────────────────────────────────── File: ./project1/west.yml ─────────────────────────────────────── manifest: group-filter: [-gw,-gw,+gx,-gy] ─────────────────────────────────────── ─────────────────────────────────────── File: ./project2/west.yml ─────────────────────────────────────── manifest: group-filter: [+gy,+gy,-gz] ─────────────────────────────────────── ─────────────────────────────────────── File: ./mp/self-import.yml ─────────────────────────────────────── manifest: group-filter: [-ga,-gb] ─────────────────────────────────────── The west docs say: In other words, let: - the submanifest resolved from self-import have group filter self-filter - the top-level manifest file have group filter top-filter - the submanifests resolved from import-1 through import-N have group filters filter-1 through filter-N respectively The final resolved group-filter value is then filter1 + filter-2 + ... + filter-N + top-filter + self-filter, where + here refers to list concatenation. - https://docs.zephyrproject.org/latest/develop/west/manifest.html Applying these rules, the final filter should be concatenated from ./project1/west.yml, ./project2/west.yml, ./mp/west.yml, ./mp/self-import.yml, in that order. Since neither ./mp/west.yml nor ./mp/self-import.yml have a group filter which affects gy, the result should be that it is enabled, since ./project2/west.yml enables it explicitly. Fix the test so it matches the expected behavior. We'll fix the implementation in a separate commit. Signed-off-by: Martí Bolívar <[email protected]>
This is a more convenient way to construct manifests, so we might as well have it around and use it to save some typing. Signed-off-by: Martí Bolívar <[email protected]>
Improve error handling to avoid dumping stack. Signed-off-by: Martí Bolívar <[email protected]>
We're not using the 'i' variable. Signed-off-by: Martí Bolívar <[email protected]>
The error handling in the _load_imap() function is not being tested. This was discovered by manually inspecting the HTML coverage data. Add statement coverage for the error handling. Signed-off-by: Martí Bolívar <[email protected]>
Thanks @mbolivar-nordic, it is looking very nice so far. |
Regarding the "default-inactive" feature. Would it make sense to add it right away?
(apart from the extra changes to support that extra project key) |
I don't think so. There is still a fair bit of work to do to get the current feature set in a merge-able state and I think such an addition is not a blocker. |
That's a bug, thanks |
To be confirmed: |
For west commands that require the whole manifest to be resolved (e.g. |
Moving all the "work" of main() into WestApp.run() will help us in future patches where we need to set up logging in a way that requires internal state from that object. Signed-off-by: Martí Bolívar <[email protected]>
We've been avoiding this for a long time, but we can't any longer and it's time to bite the bullet. There are some chicken-and-egg problems in our argument parsing that can only be handled if we do some manual command line argument parsing to determine what the common options (like --verbose) are set to, and to determine what the command name (if any) is. For example, we would ideally like to know the verbosity level of the west command *before* we set up logging for the west.manifest module, so that we can set the log level for that module appropriately. Right now, we can't do that, because we load the manifest to figure out what the extension commands are, and from there delegate to argparse to count the '--verbose' options. By the time argparse runs, then, it's too late: we already loaded the manifest, and any log messages from west.manifest are lost. Enable solving this and other problems by writing our own, very limited, command line parser that just figures out the global options (west -hvVz) and the command name. We won't need all of this right away, but we might as well try to be complete from the start. This is prep work only; we'll put it to work in later patches. Signed-off-by: Martí Bolívar <[email protected]>
Right now if you run a zephyr extension like 'west build' outside of a workspace, argparse says: [...] invalid choice: ‘build’ [...] This is because argparse's subcommand parser doesn't seem to have any API to add a catch-all value for when the user provides an unknown command, so it expects that exactly the subcommands we told it about are available. This is confusing to users, and now that we have our own EarlyArgs parsed, we can do better by printing some west-specific help if we aren't in a workspace: usage: west [-h] [-z ZEPHYR_BASE] [-v] [-V] <command> ... west: unknown command "build"; do you need to run this inside a workspace? as well as if you are: usage: west [-h] [-z ZEPHYR_BASE] [-v] [-V] <command> ... west: unknown command "foo"; workspace /home/mbolivar/zp does not define this extension command -- try "west help" Signed-off-by: Martí Bolívar <[email protected]>
Commit 92c18ac ("main: move verbose manifest logging to project.py") did not achieve its purpose. We are loading the manifest long before we call the setup_logging() methods in each of the project.py classes, so any messages from the manifest class have long been discarded by the time that we enable them. Now that we have EarlyArgs in main.py, we can use that to centralize logging and enforce the following: - warnings and above for west APIs are emitted by default - info and above emitted with west -v - debug and above with west -vv or higher Fixes: zephyrproject-rtos#665 Signed-off-by: Martí Bolívar <[email protected]>
Put the first argument on the same line as the string "error:", to make it easier to grep. Signed-off-by: Martí Bolívar <[email protected]>
This will still fail or succeed in the same situations, but it is convenient to do it this way as prep work for future enhancements. Signed-off-by: Martí Bolívar <[email protected]>
In order to support the manifest.project-filter configuration option, we need to forbid certain characters from occurring in project names. Making that happen is a backwards incompatible change, however, so phase it in by emitting a warning. We will make it a hard error if manifest.project-filter is set later on. That way, users will only see an error if they are opting into the latest west for now, and other users will get a warning and have time to migrate their projects. Signed-off-by: Martí Bolívar <[email protected]>
This adds initial support for loading a 'manifest.project-filter' configuration option. This option is special in that its values in the system, global, and local configuration files are all considered at the same time, rather than just whichever one is defined at highest precedence. This is because the eventual purpose of this configuration option is to allow people to deactivate or activate projects using the configuration file system, and it seems nicer to allow people to progressively refine a filter instead of having to synchronize global settings that they always want applied into each workspace they have or may create. This patch doesn't actually do anything with the option values besides defining the internal representation, validating the options on the file system, and saving the results in the import context state that we carry around while importing projects. Applying the filter itself will come in future patches. See source code comments for details on behavior (these will eventually make their way into the documentation). Signed-off-by: Martí Bolívar <[email protected]>
Add support for this option. The option's value is a comma-separated list of regular expressions, each prefixed with '+' or '-', like this: +re1,-re2,-re3 Project names are matched against each regular expression (re1, re2, re3, ...) in the list, in order. If the entire project name matches the regular expression, that element of the list either deactivates or activates the project. The project is deactivated if the element begins with '-'. The project is activated if the element begins with '+'. (Project names cannot contain ',' if this option is used, so the regular expressions do not need to contain a literal ',' character.) If a project's name matches multiple regular expressions in the list, the result from the last regular expression is used. For example, if manifest.project-filter is: -hal_.*,+hal_foo Then a project named 'hal_bar' is inactive, but a project named 'hal_foo' is active. If a project is made inactive or active by a list element, the project is active or not regardless of whether any or all of its groups are disabled. (This is also now the only way to make a project that has no groups inactive.) Otherwise, i.e. if a project does not match any regular expressions in the list, it is active or inactive according to the usual rules related to its groups. Within an element of a manifest.project-filter list, leading and trailing whitespace are ignored. That means these example values are equivalent: +foo,-bar +foo , -bar Any empty elements are ignored. That means these example values are equivalent: +foo,,-bar +foo,-bar The lists in the manifest.project-filter options in the system, global, and local configuration files are concatenated together. For example, on Linux, with: /etc/westconfig: [manifest] project-filter = +foo ~/.westconfig: [manifest] project-filter = -bar_.* <workspace>/.west/config: [manifest] project-filter = +bar_local Then the overall project filter when within the workspace <workspace> is: +foo,-bar_.*,+bar_local This lets you set defaults in the system or global files that can be overridden within an individual workspace as needed, without having to maintain the defaults across multiple workspaces. Signed-off-by: Martí Bolívar <[email protected]>
Internal discussion at Nordic indicates that the semantics for 'west manifest --resolve' should probably be something along the lines of "resolve the manifest but ignore the value of manifest.project-filter, and print the resolved result". This is consistent with the way that these commands are not affected by the value of manifest.group-filter. However, we don't have a way to support this right now: west.manifest has no API for loading itself but with manifest.project-filter ignored. Such an API would be straightforward to add, but we don't have time for that right now, as we're under time pressure to add support for this option to resolve an issue during the zephyr v3.4 stabilization period. For now, work around the issue by just erroring out if the option is set at all, telling the user that they can get in touch with us if they need this. We'll let the level of noise that results be our guide in prioritizing this enhancement. Signed-off-by: Martí Bolívar <[email protected]>
Add test cases for behavior and matching rules. Signed-off-by: Martí Bolívar <[email protected]>
9fe3cb1
to
605903e
Compare
Note that this is just a temporary solution. We can add full support for these commands at a later date when the enhancement is required for a concrete use case. This differs from #660, which would have prevented us from implementing these commands at all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mbolivar-nordic , it's looking good.
Just 3 minor nits, for which there is no need to hold this.
i'm not so sure on this. For example if I can have:
why can I then not have similar for groups ?
I know |
@aescolar and myself discussed this comment with @tejlmand. The inconsistency in handling the aggregation of different config levels between |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed together with @aescolar.
Commit d842371 ("app: handle unexpected command name better") intentionally created a big error handling difference between extensions and built-in commands. As an unfortunate side effect, it lost the relevant "manifest import failure" error messages for _extension_ commands. This is especially ironic when the extension command is missing because the import failed, see example in zephyrproject-rtos#726. Error handling is generally very hard to test comprehensively and even more so in this complex "bootstrap" area. Rather than trying to refactor it once again, tweak the existing error messages to gently steer the user away from (potentially missing) extensions and towards built-in commands that provide a simpler and better error handling out of the box: they still show relevant, manifest error messages! Always have. Also recommand the -vv option which conveniently includes git error messages like "dubious ownership" since commit fcbb0a2 ("app: tweak logging on malformed manifest or configuration") from the same PR zephyrproject-rtos#664. Signed-off-by: Marc Herbert <[email protected]>
def handle_early_arg_errors(self, early_args): | ||
# If early_args indicates we should error out, handle it | ||
# gracefully. This provides more user-friendly output than | ||
# argparse can do on its own. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take three at trying to provide an "import filtering" (#543) solution that will work to allow making the bsim project in zephyr/west.yml inactive, so you can
west build
etc without it cloned.To test:
alternatively:
Add support for a new manifest.project-filter configuration option.
The option's value is a comma-separated list of regular expressions,
each prefixed with '+' or '-', like this:
Project names are matched against each regular expression (re1, re2,
re3, ...) in the list, in order. If the entire project name matches
the regular expression, that element of the list either deactivates or
activates the project. The project is deactivated if the element
begins with '-'. The project is activated if the element begins with
'+'. (Project names cannot contain ',' if this option is used, so the
regular expressions do not need to contain a literal ',' character.)
If a project's name matches multiple regular expressions in the list,
the result from the last regular expression is used. For example,
if manifest.project-filter is:
Then a project named 'hal_bar' is inactive, but a project named
'hal_foo' is active.
If a project is made inactive or active by a list element, the project
is active or not regardless of whether any or all of its groups are
disabled. (This is also now the only way to make a project that has no
groups inactive.)
Otherwise, i.e. if a project does not match any regular expressions in
the list, it is active or inactive according to the usual rules
related to its groups.
Within an element of a manifest.project-filter list, leading and
trailing whitespace are ignored. That means these example values
are equivalent:
The lists in the manifest.project-filter options in the system,
global, and local configuration files are concatenated together.
For example, on Linux, with:
Then the overall project filter when within the workspace
is:
This lets you set defaults in the system or global files that can be
overridden within an individual workspace as needed, without having to
maintain the defaults across multiple workspaces.
Fixes #653