mirror of
https://github.com/NixOS/nix
synced 2025-06-25 02:21:16 +02:00
Add nix formatter build
command
`nix formatter build` is sort of like `nix build`: it builds, links, and
prints a path to the formatter program:
$ nix formatter build
/nix/store/cb9w44vkhk2x4adfxwgdkkf5gjmm856j-treefmt/bin/treefmt
Note that unlike `nix build`, this prints the full path to the program,
not just the store path (in the example above that would be
`/nix/store/cb9w44vkhk2x4adfxwgdkkf5gjmm856j-treefmt`).
Motivation
----------
I maintain a vim plugin that automatically runs `nix fmt` on files on
save. Since `nix fmt` can be quite slow due to nix evaluation, I choose
to cache the `nix fmt `entrypoint. This was very awkward to do, see the
implementation for details:
7864607231/lua/null-ls/builtins/formatting/nix_flake_fmt.lua (L83-L110)
.
I recently discovered that my implementation was buggy (it didn't handle
flakes that expose a `formatter` package, such as nixpkgs), so I had to
rework the implementation:
https://github.com/nvimtools/none-ls.nvim/pull/272.
With the new `nix formatter build` command, I can delete all this akward
code, and it will be easier for other folks to build performant editor
integrations for `nix fmt`.
This commit is contained in:
parent
5ea7b97147
commit
ba6b617e75
3 changed files with 127 additions and 4 deletions
23
src/nix/formatter-build.md
Normal file
23
src/nix/formatter-build.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
R""(
|
||||
|
||||
# Description
|
||||
|
||||
`nix formatter build` builds the formatter specified in the flake.
|
||||
|
||||
Similar to [`nix build`](@docroot@/command-ref/new-cli/nix3-build.md),
|
||||
unless `--no-link` is specified, after a successful
|
||||
build, it creates a symlink to the store path of the formatter. This symlink is
|
||||
named `./result` by default; this can be overridden using the
|
||||
`--out-link` option.
|
||||
|
||||
It always prints the command to standard output.
|
||||
|
||||
# Examples
|
||||
|
||||
* Build the formatter:
|
||||
|
||||
```console
|
||||
# nix formatter build
|
||||
/nix/store/cb9w44vkhk2x4adfxwgdkkf5gjmm856j-treefmt/bin/treefmt
|
||||
```
|
||||
)""
|
|
@ -1,6 +1,8 @@
|
|||
#include "nix/cmd/command.hh"
|
||||
#include "nix/cmd/installable-value.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/store/local-fs-store.hh"
|
||||
#include "nix/cmd/installable-derived-path.hh"
|
||||
#include "run.hh"
|
||||
|
||||
using namespace nix;
|
||||
|
@ -25,7 +27,7 @@ struct CmdFormatter : NixMultiCommand
|
|||
|
||||
static auto rCmdFormatter = registerCommand<CmdFormatter>("formatter");
|
||||
|
||||
struct CmdFormatterRun : SourceExprCommand
|
||||
struct CmdFormatterRun : SourceExprCommand, MixJSON
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
|
||||
|
@ -87,6 +89,80 @@ struct CmdFormatterRun : SourceExprCommand
|
|||
|
||||
static auto rFormatterRun = registerCommand2<CmdFormatterRun>({"formatter", "run"});
|
||||
|
||||
struct CmdFormatterBuild : SourceExprCommand
|
||||
{
|
||||
Path outLink = "result";
|
||||
|
||||
CmdFormatterBuild()
|
||||
{
|
||||
addFlag({
|
||||
.longName = "out-link",
|
||||
.shortName = 'o',
|
||||
.description = "Use *path* as prefix for the symlink to the build result. It defaults to `result`.",
|
||||
.labels = {"path"},
|
||||
.handler = {&outLink},
|
||||
.completer = completePath,
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "no-link",
|
||||
.description = "Do not create symlink to the build results.",
|
||||
.handler = {&outLink, Path("")},
|
||||
});
|
||||
}
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "build the current flake's formatter";
|
||||
}
|
||||
|
||||
std::string doc() override
|
||||
{
|
||||
return
|
||||
#include "formatter-build.md"
|
||||
;
|
||||
}
|
||||
|
||||
Category category() override
|
||||
{
|
||||
return catSecondary;
|
||||
}
|
||||
|
||||
Strings getDefaultFlakeAttrPaths() override
|
||||
{
|
||||
return Strings{"formatter." + settings.thisSystem.get()};
|
||||
}
|
||||
|
||||
Strings getDefaultFlakeAttrPathPrefixes() override
|
||||
{
|
||||
return Strings{};
|
||||
}
|
||||
|
||||
void run(ref<Store> store) override
|
||||
{
|
||||
auto evalState = getEvalState();
|
||||
auto evalStore = getEvalStore();
|
||||
|
||||
auto installable_ = parseInstallable(store, ".");
|
||||
auto & installable = InstallableValue::require(*installable_);
|
||||
auto unresolvedApp = installable.toApp(*evalState);
|
||||
auto app = unresolvedApp.resolve(evalStore, store);
|
||||
|
||||
Installables installableContext;
|
||||
for (auto & ctxElt : unresolvedApp.unresolved.context)
|
||||
installableContext.push_back(make_ref<InstallableDerivedPath>(store, DerivedPath{ctxElt}));
|
||||
auto buildables = Installable::build(evalStore, store, Realise::Outputs, installableContext);
|
||||
|
||||
if (outLink != "")
|
||||
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
createOutLinks(outLink, toBuiltPaths(buildables), *store2);
|
||||
|
||||
logger->cout("%s", app.program);
|
||||
};
|
||||
};
|
||||
|
||||
static auto rFormatterBuild = registerCommand2<CmdFormatterBuild>({"formatter", "build"});
|
||||
|
||||
struct CmdFmt : CmdFormatterRun
|
||||
{
|
||||
void run(ref<Store> store) override
|
||||
|
|
|
@ -7,11 +7,14 @@ TODO_NixOS # Provide a `shell` variable. Try not to `export` it, perhaps.
|
|||
clearStoreIfPossible
|
||||
rm -rf "$TEST_HOME"/.cache "$TEST_HOME"/.config "$TEST_HOME"/.local
|
||||
|
||||
cp ./simple.nix ./simple.builder.sh ./fmt.simple.sh "${config_nix}" "$TEST_HOME"
|
||||
cp ./simple.nix ./simple.builder.sh ./formatter.simple.sh "${config_nix}" "$TEST_HOME"
|
||||
|
||||
cd "$TEST_HOME"
|
||||
|
||||
nix fmt --help | grep "forward"
|
||||
nix formatter --help | grep "build or run the formatter"
|
||||
nix fmt --help | grep "reformat your code"
|
||||
nix fmt run --help | grep "reformat your code"
|
||||
nix fmt build --help | grep "build"
|
||||
|
||||
cat << EOF > flake.nix
|
||||
{
|
||||
|
@ -23,16 +26,37 @@ cat << EOF > flake.nix
|
|||
buildCommand = ''
|
||||
mkdir -p \$out/bin
|
||||
echo "#! ${shell}" > \$out/bin/formatter
|
||||
cat \${./fmt.simple.sh} >> \$out/bin/formatter
|
||||
cat \${./formatter.simple.sh} >> \$out/bin/formatter
|
||||
chmod +x \$out/bin/formatter
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
EOF
|
||||
|
||||
# No arguments check
|
||||
[[ "$(nix fmt)" = "Formatting(0):" ]]
|
||||
[[ "$(nix formatter run)" = "Formatting(0):" ]]
|
||||
|
||||
# Argument forwarding check
|
||||
nix fmt ./file ./folder | grep 'Formatting(2): ./file ./folder'
|
||||
nix formatter run ./file ./folder | grep 'Formatting(2): ./file ./folder'
|
||||
|
||||
# Build checks
|
||||
## Defaults to a ./result.
|
||||
nix formatter build | grep ".\+/bin/formatter"
|
||||
[[ -L ./result ]]
|
||||
rm result
|
||||
|
||||
## Can prevent the symlink.
|
||||
nix formatter build --no-link
|
||||
[[ ! -e ./result ]]
|
||||
|
||||
## Can change the symlink name.
|
||||
nix formatter build --out-link my-result | grep ".\+/bin/formatter"
|
||||
[[ -L ./my-result ]]
|
||||
rm ./my-result
|
||||
|
||||
# Flake outputs check.
|
||||
nix flake check
|
||||
nix flake show | grep -P "package 'formatter'"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue