Skip to content
Open
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,34 @@ nix shell <PATH>#<LANGUAGE>[.<PKG1>.<PKG2> ...]
- `LANGUAGE` is the name of the language (see [Supported Languages](#supported-languages))
- `PKGS` are the package names (separated by `.`) that will be included with the language


### Make the `<PATH>` shorter

To avoid having to write `github:tomberek/-` each time (which can be quite verbose),
you can run this command in your shell:
```sh
nix registry add flake:lang github:tomberek/-
```
> PS: you can change the registry name to anything you like, `lang` is just an example :)

After, you only have to prefix `lang` as the `<PATH>` of the command.

### Examples

Start a shell environment with python and the packages `scipy`, `matplotlib`, and `numpy`:
```sh
nix shell github:tomberek/-#python3With.scipy.matplotlib.numpy

# If you added the registry
nix shell lang#python3With.scipy.matplotlib.numpy
```

Start a shell environment with perl and the packages `HTMLTokeParserSimple` and `LWP`:
```sh
nix shell github:tomberek/-#perlWith.HTMLTokeParserSimple.LWP

# If you added the registry
nix shell lang#perlWith.HTMLTokeParserSimple.LWP
```


Expand All @@ -49,5 +67,8 @@ See the [documentation](https://nixos.org/manual/nix/stable/command-ref/new-cli/
- Python3 (`python3With`)
- Python39 (`python39With`)
- Python310 (`python310With`)
- Python311 (`python311With`)
- Python312 (`python312With`)
- Python313 (`python313With`)
- Haskell (`haskellWith`)
- Perl (`perlWith`)
95 changes: 62 additions & 33 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,73 @@

# Helper functions
forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system;
overlays = [ self.overlay ]; });
nixpkgsFor = forAllSystems (system: import nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
});

makeMerger = self: packageset: packagesetfunc:
let
gen = name: paths: self.buildEnv {
inherit name;
paths = [
(packagesetfunc (ps: paths))
] ++ paths ;
ignoreCollisions = true;
meta.mainProgram = let
last = self.lib.last paths; in last.meta.mainProgram
or (builtins.parseDrvName last.name).name;

# Use lists not attrsets because order matters
passthru = with builtins; mapAttrs (n: v: gen
(if length paths > 5 then "merged-environment" else "${name}-${n}")
(paths ++ [ v ])
) (self // packageset);
};
in gen "merged" [ ];
in {
overlay = self: super: {
"-" = self.pkgsMerge;
"+" = self.pkgsMerge;
pkgsMerge = makeMerger self super (paths: paths {});
python2With = makeMerger self super.python2Packages super.python2.withPackages;
python3With = makeMerger self super.python3Packages super.python3.withPackages;
python39With = makeMerger self super.python39Packages super.python39.withPackages;
python310With = makeMerger self super.python310Packages super.python310.withPackages;
haskellWith = makeMerger self super.haskellPackages super.haskellPackages.ghcWithPackages;
perlWith = makeMerger self super.perlPackages super.perl.withPackages;
let
gen = name: paths: self.buildEnv {
inherit name;
paths = [
(packagesetfunc (ps: paths))
] ++ paths;
ignoreCollisions = true;
meta.mainProgram =
let
last = self.lib.last paths;
in
last.meta.mainProgram
or (builtins.parseDrvName last.name).name;

# Use lists not attrsets because order matters
passthru = with builtins; mapAttrs
(n: v: gen
(if length paths > 5 then "merged-environment" else "${name}-${n}")
(paths ++ [ v ])
)
(self // packageset);
};
in
gen "merged" [ ];

addLanguage = { lang, langRepo ? lang, langPackages ? lang + "Packages", withPackages ? "withPackages", langWith ? lang + "With" }: {
inherit lang langPackages withPackages langWith langRepo;
};

languages = [
(addLanguage { lang = "python2"; })
(addLanguage { lang = "python3"; })
(addLanguage { lang = "python310"; })
(addLanguage { lang = "python311"; })
(addLanguage { lang = "python312"; })
(addLanguage { lang = "python313"; })
(addLanguage { lang = "perl"; })
(addLanguage { lang = "haskell"; langRepo = "haskellPackages"; withPackages = "ghcWithPackages"; })
];

mergeLang = self: super: lang: makeMerger self super.${lang.langPackages} super.${lang.langRepo}.${lang.withPackages};
in
{
overlays.default = final: prev:
let
self = final;
super = prev;
mergedLangs = builtins.map (lang: { ${lang.langWith} = mergeLang self super lang; }) languages;
in
builtins.foldl' (x: y: x // y)
{
"-" = self.pkgsMerge;
"+" = self.pkgsMerge;
pkgsMerge = makeMerger self super (paths: paths { });
}
mergedLangs;

legacyPackages = forAllSystems (system: nixpkgsFor.${system});
packages = forAllSystems (system: { inherit (nixpkgsFor.${system})
pkgsMerge "+" "-" python3With ;});
packages = forAllSystems (system: {
inherit (nixpkgsFor.${system}) pkgsMerge"+" "-" python3With;
});

defaultPackage = forAllSystems (system: self.packages."${system}".pkgsMerge);
};
Expand Down