Skip to content

Commit e751aa5

Browse files
committed
feat: Validate specified plugins against the list of supported plugins
1 parent b2743a2 commit e751aa5

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

nix/shell-plugins.nix

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
{ pkgs, lib, config, is-home-manager, ... }:
22
with lib;
3-
let cfg = config.programs._1password-shell-plugins;
3+
let
4+
cfg = config.programs._1password-shell-plugins;
5+
6+
supported_plugins = splitString "\n" (lib.readFile "${
7+
# get the list of supported plugin executable names
8+
pkgs.runCommand "op-plugin-list" { }
9+
# 1Password CLI tries to create the config directory automatically, so set a temp XDG_CONFIG_HOME
10+
# since we don't actually need it for this
11+
"mkdir $out && XDG_CONFIG_HOME=$out ${pkgs._1password}/bin/op plugin list | cut -d ' ' -f1 | tail -n +2 > $out/plugins.txt"
12+
}/plugins.txt");
13+
getExeName = package:
14+
# NOTE: SAFETY: This is okay because the `packages` list is also referred
15+
# to below as `home.packages = packages;` or `environment.systemPackages = packages;`
16+
# depending on if it's using `home-manager` or not; this means that Nix can still
17+
# compute the dependency tree, even though we're discarding string context here,
18+
# since the packages are still referred to below without discarding string context.
19+
strings.unsafeDiscardStringContext (baseNameOf (getExe package));
420
in {
521
options = {
622
programs._1password-shell-plugins = {
@@ -17,19 +33,25 @@ in {
1733
'';
1834
description =
1935
"CLI Packages to enable 1Password Shell Plugins for; ensure that a Shell Plugin exists by checking the docs: https://developer.1password.com/docs/cli/shell-plugins/";
36+
# this is a bit of a hack to do option validation;
37+
# ensure that the list of packages include only packages
38+
# for which the executable has a supported 1Password Shell Plugin
39+
apply = package_list:
40+
map (package:
41+
if (elem (getExeName package) supported_plugins) then
42+
package
43+
else
44+
abort "${
45+
getExeName package
46+
} is not a valid 1Password Shell Plugin. A list of supported plugins can be found by running `op plugin list` or at: https://developer.1password.com/docs/cli/shell-plugins/")
47+
package_list;
2048
};
2149
};
2250
};
2351

2452
config = let
2553
# executable names as strings, e.g. `pkgs.gh` => `"gh"`, `pkgs.awscli2` => `"aws"`
26-
pkg-exe-names = map (package:
27-
# NOTE: SAFETY: This is okay because the `packages` list is also referred
28-
# to below as `home.packages = packages;` or `environment.systemPackages = packages;`
29-
# depending on if it's using `home-manager` or not; this means that Nix can still
30-
# compute the dependency tree, even though we're discarding string context here,
31-
# since the packages are still referred to below without discarding string context.
32-
strings.unsafeDiscardStringContext (baseNameOf (getExe package))) cfg.plugins;
54+
pkg-exe-names = map getExeName cfg.plugins;
3355
# Explanation:
3456
# Map over `cfg.plugins` (the value of the `plugins` option provided by the user)
3557
# and for each package specified, get the executable name, then create a shell alias

0 commit comments

Comments
 (0)