-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
[WIP] Chromium OS fork's Portage Ebuild changes #2704
base: master
Are you sure you want to change the base?
Conversation
Sorry, it's been a busy year. Can you give me some background for this? Why does Gentoo's build system need build time variables in ShellCheck? |
No worries! The short version is that Gentoo's package manager, Portage, uses ebuilds which are very bash-like. Google's ChromeOS (and its open-source flavour ChromiumOS) use Portage to maintain... some parts of the system; I've never had to dig too far into it. At some point a ChromeOS or ChromiumOS developer added functionality to their fork of shellcheck so that it could be used to lint ebuilds without an excessive amount of false positives. The fork is outdated and for fun (?) I decided to update the patches to run on a more modern version of shellcheck. I'd like to use it as part of my Gentoo ebuild QA, and several developers and members of the community seem interested as well. The ChromiumOS code seems to work well enough so I thought I'd see about getting those changes merged rather than maintaining another set of patches. I guess my questions at this point are:
Please note that I don't intend to suggest that this PR be merged in its current state; the PR is just a monolithic patch submitted for feedback with all of the ChromiumOS fork's commits rebased, modified, and squashed. Cheers! |
The main problem that the patch seems to be solving is that shellcheck catches false positives on well-defined constants in $ shellcheck persistent-2.14.5.0.ebuild
In persistent-2.14.5.0.ebuild line 1:
# Copyright 1999-2023 Gentoo Authors
^-- SC2148 (error): Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.
In persistent-2.14.5.0.ebuild line 4:
EAPI=8
^--^ SC2034 (warning): EAPI appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 9:
CABAL_FEATURES="lib profile haddock hoogle hscolour test-suite"
^------------^ SC2034 (warning): CABAL_FEATURES appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 12:
DESCRIPTION="Type-safe, multi-backend data serialization"
^---------^ SC2034 (warning): DESCRIPTION appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 13:
HOMEPAGE="https://www.yesodweb.com/book/persistent"
^------^ SC2034 (warning): HOMEPAGE appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 15:
LICENSE="MIT"
^-----^ SC2034 (warning): LICENSE appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 16:
SLOT="0/${PV}"
^--^ SC2034 (warning): SLOT appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 17:
KEYWORDS="~amd64 ~x86"
^------^ SC2034 (warning): KEYWORDS appears unused. Verify use (or export if used externally).
In persistent-2.14.5.0.ebuild line 43:
DEPEND="${RDEPEND}
^----^ SC2034 (warning): DEPEND appears unused. Verify use (or export if used externally).
For more information:
https://www.shellcheck.net/wiki/SC2148 -- Tips depend on target shell and y...
https://www.shellcheck.net/wiki/SC2034 -- CABAL_FEATURES appears unused. Ve... |
Is the set of variables known in advanced? How far would one get by adding |
Hi @koalaman, While ebuild/eclass variables do change over time, it is possible to extract them automatically (which is how As best I can what you've described is basically what we're doing with this patch; set ebuilds to be an alias for bash script, hardcode |
My understanding was that it essentially adds a de facto build time dependency on Python and out-of-tree ChromeOS build files, and is then tailored to work on ChromeOS ebuilds. Is that not the case? |
I don't intend for the python scripts to remain in their current state - They're ripped directly from the ChromeOS/ChromiumOS ebuild repository and have a different licence from the rest of your code. It'll be easy enough to rework those down the track, if required, and probably even port them to Haskell. They were included in the WIP for completeness, and also because if you're not interested in merging a revised version of this PR then there's no point in doing that porting work! It may also make more sense for these scripts to live in the Gentoo ebuild repository (associated with the shellcheck package) so that package maintainers / Gentoo users can use them to assist with providing updates upstream without the scripts being checked into VCS here. It does add a dependency on the Gentoo ebuild repository (which is just a git repo that contains text files). This could be handled in a few ways:
The intent here is to build against the Gentoo ebuild repository. Almost everything downstream of Gentoo will be able to take advantage of the changes as-is - they tend to mirror Gentoo eclasses at the very least. Some projects (Likely ChromeOS) may wish to regenerate I'm interested in hearing your thoughts. Thanks for your time this morning! |
I'm not opposed to merging a polished version of the functionality, the source and upkeep of the variable data is my only real concern. Could/should these be collected at runtime instead? I imagine a significant motivator for the current approach was to simplify the patch and its rebasing -- which it definitely does -- rather than any benefits of collecting the data at compile time. |
Sorry, got hit by a migraine then swamped with work! I'll see if I can come up with a performant approach that will gather the vast majority of the variables from eclasses at runtime - basically everything that goes into |
Sounds good! Don't worry too much about threading it through into the right places, I can help out with that. The main thing is a function in |
Quick update, it's not forgotten I just moved halfway across a continent and hurt both of my arms. @hololeap has made some good progress on getting us a runtime ebuild repository parser that (if I'm remembering our discussions properly) should be a lot more flexible when working with non-gentoo repositories. I'll try and get back into this "soon", recovery permitting :) |
@koalaman I created a function that scans the system and creates an shellcheck/src/ShellCheck/Data.hs Line 156 in 22bd5a4
The problem is that I don't see anywhere to run in the Line 247 in dd747b2
Ideally, the loaded file needs to be determined to be an ebuild before attempting to scan for eclasses, which could also fail on non-Gentoo systems. If found, the eclass data would then need to be passed deeper into the code, and I don't see an existing way to do that. |
Uses the `portageq` command to scan for repositories, which in turn are scanned for eclasses, which are then scanned for eclass variables. The variables are scanned using a heuristic which looks for "# @ECLASS_VARIABLE: " at the start of each line, which means only properly documented variables will be found. Signed-off-by: hololeap <[email protected]>
I put my current code up here. The most relevant parts are |
Creates a Map of eclass names to eclass variables by scanning the system for repositories and their respective eclasses. Runs `portageq` to determine repository names and locations. Emits a warning if an IOException is caught when attempting to run `portageq`. This Map is passed via CheckSpec to AnalysisSpec and finally to Parameters, where it is read by `checkUnusedAssignments` in order to determine which variables can be safely ignored by this check. Signed-off-by: hololeap <[email protected]>
The Gentoo eclass list is now populated using pure Haskell. The old python generators and generated module are no longer needed. Signed-off-by: hololeap <[email protected]>
Signed-off-by: hololeap <[email protected]>
I will test these changes when I'm home from dog show stuff, thanks for committing them here.
Can we avoid the external dependency by reading up on the Gentoo PMS?. It's probably sane to assume that Gentoo / Portage users will have access to Regardless it looks great and I can't wait to test it soon |
I haven't had a chance to look deeply into your changes yet, but here are my thoughts for plumbing: This adds a function Some thoughts:
|
Thanks for the attention on this. I can give some insight on your questions.
The ChromiumOS code has some kind of functionality in place to check for shellcheck/src/ShellCheck/Analytics.hs Lines 2094 to 2099 in e3d8483
The eclasses are stored in a shellcheck/src/ShellCheck/PortageVariables.hs Lines 45 to 55 in 08ae7ef
Parsing all
I admittedly am not very familiar with optimizing
I understand that adding another dependency isn't ideal either, and that with the other optimizations (such as only scanning the needed |
Thanks! I managed to get a Gentoo environment running in Docker, and got a bit further on this in https://github.com/koalaman/shellcheck/tree/ebuild It now runs end-to-end, but I ended up reverting a number of changes when going from Parameters to SystemInterface, and I'm still working on adding them back one by one. |
It's been a busy September, but https://github.com/koalaman/shellcheck/tree/ebuild now has most of the changes from the original patch, and I replaced the lovely attoparsec code with some janky regex matching and regular IO to avoid pulling in the additional dependencies. In the original PR, checking a small ebuild took 240ms, of which 200ms was invoking The original PR had a check for KEYWORDS in 9999.ebuild files, but it was gated on inheriting an eclass Could you try it out and let me know how it works in practice, and what I may have missed from the original PR? |
It's your software!
I'll get back to you, but
That seems very ChromiumOS specific. I wouldn't worry about it too much -
I'll build a copy right now! |
It took ages to update my hackage index. I've got to run off to work shortly so detailed testing will have to wait for a bit but overall it looks great. It's probably worth suppressing the 'eclass dir does not exist' message outside of verbose/debug - most repos just use gentoo eclasses, though there are a good number that do ship their own eclasses.
Otherwise, when run across an ebuild that I maintain the branch only returned valid warnings - ebuild syntax isn't flagged as a warning. I'll try and find some actual issues but that's a positive result so far! |
I've got a Curl ebuild bump to prepare for, which gave me a good opportunity to do some testing. For
This guy is consumed by portage! Can we whitelist it?
Edit: We can probably scan over I'll try and come up with a better way to find edge cases like this but it looks good so far! |
These are pretty minor nits that could be worked around with documentation IMO, but there are a whole class of false-positives that might be easily addressable with some haskell trickery - overall everything I've checked so far has so much less noise than it did proviously. |
I see. So, I guess there are two surmountable issues:
And some significantly more annoying issues:
I'm starting to wonder about the relative value of supporting and maintaining ebuild support with workarounds upstream, compared to some more flexible 80% solution like having CI awk/grep the variables into assignments file that shellcheck can read with |
Yeah, I can see how this part in particular is a nuisance. There's not that many of them and they're well-defined at least though.
This one is a quirk because the user might set
We could probably just ignore
I've not been involved in the discussion thus far so I don't want to say "yes, definitely do that", but it sounds appealing and like a reasonable fit given all the quirks. |
An observation: all of the changes in this PR are essentially adding things to whitelists for various checks ( What if For instance, the whitelists could exist in a directory tree, the structure looking like: $ find /usr/share/shellcheck/whitelists/
/usr/share/shellcheck/whitelists/ebuild/core.wl
/usr/share/shellcheck/whitelists/ebuild/eclasses/cmake.wl
/usr/share/shellcheck/whitelists/ebuild/eclasses/haskell-cabal.wl The individual
|
Hi all,
I've been working on bringing the Chromium OS fork's Portage Ebuild changes to base shellcheck. It seems to be working pretty well and I was wondering if there's any interest in merging portage support.
I have a few questions:
It's been a while since I worked in Haskell, but I'm willing to give it a try if there's interest. I would like to be able to use this to validate the Gentoo ebuild repository!
I will need to redo the rebase by cherry picking individual commits to do proper attribution. I also plan to redo the chromium-overlay-sourced python scripts so that they can be consistently licensed.
Please review this work-in-progress PR and let me know your thoughts.
Thanks for your time!