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

feat(extra-files): add feature to create new files #154

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions extra/files/file-format.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
format: {pkgs, config, lib, ...}:
let
yj-args.json = "-jji";
yj-args.yaml = "-jy";
yj-args.toml = "-jt";
yj-args.hcl = "-jc";
yj-arg = yj-args.${format};
cfg = config.files.${format};
type = (pkgs.formats.json {}).type;
generate = name: value: pkgs.runCommand name {
nativeBuildInputs = [ pkgs.yj ];
value = builtins.toJSON value;
passAsFile = [ "value" ];
} ''
cat "$valuePath"| yj ${yj-arg} > "$out"
'';
toFile = name: value: {
source = generate (builtins.baseNameOf name) value;
};
in {
options.files.${format} = lib.mkOption {
type = lib.types.attrsOf type;
description = ''
Create ${format} files with correponding content
'';
default = {};
example."/hello.${format}".greeting = "hello World";
example."/hellows.${format}".greetings = [ ["Hello World"] ["Ola Mundo" ["Holla Que Tal"]]];
};
config.file = lib.mapAttrs toFile cfg;
}
67 changes: 67 additions & 0 deletions extra/files/file-type.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{ pkgs, config, lib, ... }:
let
inherit (lib) hasPrefix literalExpression mkDefault mkIf mkOption removePrefix types;
in
{
# all rights reserved to nix-community
# copy of https://github.com/nix-community/home-manager/blob/master/modules/lib/file-type.nix
# Constructs a type suitable for a `devshell.file` like option. The
# target path may be absolute, in which case it
# is relative to project root
# Arguments:
# - basePathDesc docbook compatible description of the base path
# - basePath the file base path
fileType = basePathDesc: types.attrsOf (types.submodule (
{ name, config, ... }: {
options = {
target = mkOption {
type = types.str;
defaultText = literalExpression "<name>";
description = ''
Path to target file relative to ${basePathDesc}.
'';
};

text = mkOption {
default = null;
type = types.nullOr types.lines;
description = ''
Text of the file. If this option is null then
<link linkend="devshell.file._name_.source">devshel.file.&lt;name?&gt;.source</link>
must be set.
'';
};

source = mkOption {
type = types.path;
description = ''
Path of the source file or directory. If
<link linkend="devshell.file._name_.text">devshell.file.&lt;name?&gt;.text</link>
is non-null then this option will automatically point to a file
containing that text.
'';
};

executable = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Set the execute bit. If <literal>null</literal>, defaults to the mode
of the <varname>source</varname> file or to <literal>false</literal>
for files created through the <varname>text</varname> option.
'';
};
};

config = {
target = mkDefault name;
source = mkIf (config.text != null) (
mkDefault (pkgs.writeTextFile {
inherit (config) executable text;
name = name;
})
);
};
}
));
}
42 changes: 42 additions & 0 deletions extra/files/files.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{ pkgs, config, lib, ... }:
let
files = config.file;
fileType = (import ./file-type.nix { inherit pkgs config lib; }).fileType;
chmod = file:
if file.executable == null then ""
else if file.executable then "chmod +x $target"
else "chmod -x $target";
# Execute this script to update the project's files
nameToScript = name: builtins.replaceStrings ["/" "."] ["-" "-"] (lib.removePrefix "/" name);
copy-file = name: file: pkgs.writeShellScriptBin (nameToScript name) ''
export PATH=${pkgs.coreutils}/bin:$PATH
out="$(git rev-parse --show-toplevel)"
realOut="$(realpath -m "$out")"
target="$(realpath -m "$realOut/${file.target}")"
mkdir -p "$(dirname "$target")"
cp --no-preserve=mode,ownership,timestamps "${file.source}" "$target"
${chmod file}
'';
startups = lib.mapAttrsToList (n: f:
let name = nameToScript n;
in {
${name}.text = ''
$DEVSHELL_DIR/bin/${name}
'';
}) files;
in {
options.file = lib.mkOption {
description = "Attribute set of files to create into the project root.";
default = {};
type = fileType "<envar>PRJ_ROOT</envar>";
};
config.commands = [
{
name = "files";
help = "Regenerate files";
command = "nix develop --build";
}
];
config.devshell.packages = lib.mapAttrsToList copy-file files;
config.devshell.startup = lib.foldAttrs lib.mergeAttrs {} startups;
}
1 change: 1 addition & 0 deletions extra/files/hcl.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import ./file-format.nix "hcl"
1 change: 1 addition & 0 deletions extra/files/json.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import ./file-format.nix "json"
1 change: 1 addition & 0 deletions extra/files/toml.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import ./file-format.nix "toml"
1 change: 1 addition & 0 deletions extra/files/yaml.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import ./file-format.nix "yaml"