Skip to content
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

writeShellApplication: Document and extend arguments #280592

Merged
merged 6 commits into from
Feb 2, 2024

Conversation

9999years
Copy link
Contributor

@9999years 9999years commented Jan 12, 2024

Description of changes

Documented pkgs.writeShellApplication arguments, expanded the test suite, and added several new arguments:

  1. The default Bash options can be customized with bashOptions.

    This is useful to e.g. exclude nounset if you want to check [[ -n "$myVar" ]] on a potentially-unset variable, or disable pipefail to use grep in a pipeline. Previously you could do set +o pipefail, but running that right after set -o pipefail always felt clumsy to me.

  2. Added a derivationArgs argument which is used for extra stdenv.mkDerivation arguments.

    This allows customizing postCheck and other such parameters.

  3. Runtime environment variables can now be set with runtimeEnv.

I also took care to make sure this doesn't change the hashes of derivations produced with any of the involved functions, so we don't have to worry about excessive rebuilds.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@9999years 9999years force-pushed the write-shell-application-options branch 4 times, most recently from 4a1f0d8 to 3047769 Compare January 13, 2024 00:45
@9999years 9999years marked this pull request as ready for review January 13, 2024 00:47
@9999years 9999years force-pushed the write-shell-application-options branch from 3047769 to a231103 Compare January 13, 2024 00:51
@9999years 9999years changed the title writeShellApplication: Document and extend options writeShellApplication: Document and extend arguments Jan 13, 2024
@9999years 9999years force-pushed the write-shell-application-options branch from a231103 to aaf17c8 Compare January 13, 2024 01:03
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 10.rebuild-linux: 1 labels Jan 13, 2024
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new tests are awesome, thanks!

I have some comments for the other bits though :)

@@ -152,19 +152,30 @@ rec {
, meta ? { }
, allowSubstitutes ? false
, preferLocalBuild ? true
}:
, ...
}@args:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runCommandWith already supports the derivationArgs attribute with the same purpose (which I also think is cleaner). The same interface can be adopted for writeTextFile and writeShellApplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

writeTextFile passes all of its arguments to runCommandWith as derivationArgs. I don't think this makes sense unless you also support renaming writeTextFile's checkPhase argument to derivationArgs.checkPhase.

In the sense that writeShellApplication wraps writeTextFile and writeTextFile wraps runCommand, this is just extending the existing behavior to forward arbitrary arguments in addition to the explicitly blessed ones.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ... pattern where you pick certain arguments and forward the rest to some mkDerivation-derivative is just a bit too full of holes imo:

  • It makes typos not trigger an error, since mkDerivation happily accepts pretty much any value and uses them as environment variables.
  • It makes it so that you can't use new mkDerivation attributes in case they happen to conflict with the picked arguments (what if mkDerivation gets a destination attribute with different semantics?).
    • And similarly, if somebody passes some derivation attribute, but later that becomes a picked-out function argument, stuff might break.
  • It makes the distinction between the stable function interface and internals less clear. In particular setting derivation attributes has the potential to break stuff, whereas the function arguments don't.
  • It makes the code less maintainable and harder to understand. Updating function arguments now requires changes in two parts of the code and some thinking. Solutions have been proposed to this, but I think we should just design better interfaces instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I change writeTextFile's interface as well, to be consistent?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so yeah

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, though I suspect this will cause breakage with callers and confusion around arguments like meta and checkPhase which are also stdenv.mkDerivation arguments.

pkgs/build-support/trivial-builders/default.nix Outdated Show resolved Hide resolved
@@ -367,6 +367,7 @@ rec {
, text
, runtimeShell ? runtimeShell'
, runtimeInputs ? [ ]
, runtimeEnv ? null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reminds me of makeWrapper, which provides the same functionality via --set <VAR> <VALUE>. How about we make this function internally use makeWrapper instead? We can then also use --prefix PATH : ${makeBinPath runtimeInputs}.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makeWrapper doesn't support setting values to lists or maps. I also think it's nicer to keep the written script contained to one file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, we might want to reconsider this in the future though, especially if the need for more makeWrapper-like features comes up.

Comment on lines 363 to 251
/* The name of the script to write.

Type: String
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the doc comments here aren't rendered into the manual. Can you follow the style from the very new #277534 instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh they aren't? But we could wire them up, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that could be done with nixdoc, just like with the lib docs.

Copy link
Contributor

@fricklerhandwerk fricklerhandwerk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great improvement, thanks a lot. Finally we can configure the shell!

Note that the checkPhase uses stdenv.shell for the test run of the script,
while the generated shebang uses runtimeShell. If, for whatever reason,
those were to mismatch you might lose fidelity in the default checks.
Similar to `writeShellScriptBin` and `writeScriptBin`.
Copy link
Contributor

@fricklerhandwerk fricklerhandwerk Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better:

Suggested change
Similar to `writeShellScriptBin` and `writeScriptBin`.
Similar to [](#trivial-builder-writeShellScriptBin) and [](#trivial-builder-writeScriptBin).

This will render sensibly in HTML now that #277534 is merged.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of directly contradicts what I said in #280592 (comment) 😅

I guess you meant that if this content is moved to trivial-build-helpers.chapter.md, it would get rendered correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, updated the manual. I'll leave the argument documentation where it is, so it'll get rendered when nixdoc gets wired up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's good to have docs at all, so I don't want to block on this, but really it would be best if the docs were actually visible from the manual instead of people having to look through the source all the time.

Also I want to highlight that @DanielSidhion is recently writing some really nice rendered documentation for function arguments:

### Inputs {#ssec-pkgs-dockerTools-buildImage-inputs}

Rendered: https://nixos.org/manual/nixpkgs/unstable/#ssec-pkgs-dockerTools-buildImage-inputs

pkgs/build-support/trivial-builders/default.nix Outdated Show resolved Hide resolved
@delroth delroth added the 12.approvals: 1 This PR was reviewed and approved by one reputable person label Jan 15, 2024
@9999years 9999years force-pushed the write-shell-application-options branch from aaf17c8 to fe2c1bc Compare January 22, 2024 17:33
@delroth delroth removed the 12.approvals: 1 This PR was reviewed and approved by one reputable person label Jan 22, 2024
@9999years 9999years force-pushed the write-shell-application-options branch 2 times, most recently from f53b152 to 68d79fa Compare January 29, 2024 18:30
@9999years
Copy link
Contributor Author

Addressed review comments, PTAL.

@infinisil infinisil force-pushed the write-shell-application-options branch 3 times, most recently from 2188fe9 to 68d79fa Compare February 1, 2024 22:08
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops didn't want to force push here yet before I got confirmation first (asked you in PMs), I undid that for now. Mainly I'm suggesting to clean up the Git log, but also to split the bash stuff into a separate PR, because it's a bit trickier to get right.

I made the changes in this branch, the diff to your current branch is here. Let me know if it sounds good to push like that.

Comment on lines 309 to 353
${stdenv.shellDryRun} "$target"
# This is `shellDryRun` but for our particular `bash`.
${bash} -n -O extglob "$target"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stdenv.shell (or stdenv.shellDryRun) and pkgs.runtimeShell are not the same, the former is for the build platform, while the latter is for the host platform. This means that replacing both with the same version breaks cross compilation, and I don't see an obvious way to get around this. That's what I meant with splicing shenanigans being necessary in this comment.

I don't know an obvious way to make this work in a clean way, so I'd say let's have that in a separate PR.

@9999years 9999years force-pushed the write-shell-application-options branch from 68d79fa to 41376dd Compare February 2, 2024 00:02
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you pushed my suggested changes, so this definitely looks good to me! Let's merge when CI is greenish and improve anything as necessary going forward.

@infinisil infinisil merged commit 3c29f55 into NixOS:master Feb 2, 2024
25 checks passed
@9999years 9999years deleted the write-shell-application-options branch February 2, 2024 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants