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

Conversation

hugosenari
Copy link

@hugosenari hugosenari commented Dec 10, 2021

Add feature to create new file with module

Following #152 suggestion, those are most basic feature of devshell-files:

  • File creation
  • JSON, TOML, YAML, HCL e TEXT
# hello.nix
# nix example require modules to imported at flake.nix
{
  # high level interface
  files.json."/generated/hello.json".hello = "world";
  files.toml."/generated/hello.toml".hello = "world";
  files.yaml."/generated/hello.yaml".hello = "world";
  files.hcl."/generated/hello.hcl".hello = "world";
  # low level interface
  file.hello.target = "/generated/hello.sh";
  file.hello.text = "echo Hello World";
  file.hello.executable = true;
}
# hello.toml

imports = ["files/files", "files/yaml", "files/json", "files/toml", "files/hcl"]
# high level interface
[files.yaml."/generated/hello.yaml"]
hello = "world :)"

[files.json."/generated/hello.json"]
hello = "world :)"

[files.toml."/generated/hello.toml"]
hello = "world :)"

[files.hcl."/generated/hello.hcl"]
hello = "world :)"

# low level interface
[file.hello]
target = "/generated/hello.txt"
text = "hello world :)"
executable = true

TODO:

  • Properly test it
  • Check license issue
  • Add TOML example
  • Update documentation

The license Issue:

file-type.nix is a copy from home-manager I don't know how to properly share file or if there are any license issue related.

edit 1: remove text high interface
edit 2: adding TOML example

@bew
Copy link
Contributor

bew commented Dec 10, 2021

note: I'm not the author

I have a feeling that this module is a bit too complex and could be made simpler, with only the 'lowlevel' interface and a few helper functions to build a json/toml/yaml/hcl/... file from a attrset.

This way the implementation of files is more modular/flexible, and is not highly coupled to what formats are available in the yj tool.
Adding more formats is easy: Add a new helper function.

The way I see it would look like:

{ lib, ... }:
{
  file."/generated/hello.json".text = lib.toJSON { hello = "world"; };
  file."/generated/hello.toml".text = lib.toTOML { hello = "world"; };
  file."/generated/hello.yaml".text = lib.toYAML { hello = "world"; };
  file."/generated/hello.hcl".text = lib.toHCL { hello = "world"; };
  file."/generated/hello.txt".text = "hello world :)";
  # Special file config:
  file.hello = {
    text = "echo Hello World";
    target = "/generated/hello.sh";
    executable = true;
  };
}

What do you think?

@hugosenari
Copy link
Author

hugosenari commented Dec 11, 2021

You decide.
I'm biased in favor of this feature.
I will keep using it in devshell-files extending low interface, so doesn't matter.

But for in TOML configuration, call function isn't nice. I realised that it isn't just nix to YAML but also TOML to YAML feature (unintended side effect).

Other point and reason why I'm biassed, it makes my nix file 'fluent' (I don't know the proper name of pattern, fluent APi is from OOP world). I like write things like this, if could get rid of any function call or array I do, sadly isn't always possible. I had no proper study about it but seems to me that it removes cognitive load for reading. And nobody would be afraid of nix Lang if it looks like Java properties file.

# actual config file I use in some personal project
{ config, ...}:
{
  imports = [ ./event.nix ];
  config.files.gitignore.enable = true;
  config.files.gitignore.template.Python = true;
  config.files.cmds."nodePackages.serverless" = true;
  config.files.cmds.python39 = true;
  config.files.alias.deploy = ''
    STAGE=$(get-stage)
    sls deploy -s $STAGE
  '';
  config.gh-actions.ci-cd.enable = true;
  config.gh-actions.ci-cd.on.push.branches = ["master" "staging"];
  config.gh-actions.ci-cd.on.push.paths = ["src/**"];
  config.gh-actions.ci-cd.ssh-secret-name = "GH_ACTIONS_SSH_KEY";
  config.gh-actions.ci-cd.env.deploy = config.pontix.aws.ci-cd.envs;
  config.gh-actions.ci-cd.deploy = ''
    STAGE=$(get-stage)
    sls print -s $STAGE > sls_cfg.lock
    use-cache sls_cfg.lock ./
    deploy
    cache-it sls_cfg.lock .serverless
  '';
  config.gh-actions.ci-cd.post-deploy = "tag-it";
  config.gh-actions.notify-slack.enable = true;
  config.gh-actions.notify-slack.on.push.branches = ["master" "staging"];
  config.gh-actions.notify-slack.ssh-secret-name = "GH_ACTIONS_SSH_KEY";
}

We are not limited to formats supported by yj, (ie text.nix), I just put all formats accepted by yj in a single file to reuse code.

Fun fact my first version was with pkgs.formats but it uses python instead of a pre-compiled binary...

But again, to me it doesn't change nothing and I know that accept this complexity could be a problem you have deal after accepting this.

So ok if you request to remove it.

@hugosenari
Copy link
Author

@bew thank you,
You made me realize that text.nix isn't required at all 😄

Author or not, your points are insightful.

@hugosenari
Copy link
Author

@bew, add TOML example to description now we can see how interesting it is ;-)

@zimbatm Should I create an extras/files.nix with all them to make import simplier?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants