-
-
Notifications
You must be signed in to change notification settings - Fork 130
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
Add feature: standalone package export (nixpkgs compatibility) #170
Comments
I think we can do this in a way that wouldn't require us to symlink files around. We can split We can modify {
importModule =
{file, extraArgs}:
let
# stuff
module = (import file ({inherit lib config;} // extraArgs));
in
{inherit module file;};
} We can then export every module we want to expose to all modules in a big attrset: {
# dlib functions
dlib-func1 = importModule {file = ...;};
dlib-func2 = ...;
# builders
builders-rust-crane = ...;
# translators
translators-rust-cargo-lock = ...;
} of course these wouldn't be declared by hand as we can just collect files from a directory and create an attrset (we already do for subsystems). The naming for modules would need to be unique of course. Then again in {
# all modules
importedModules = /* the attrset of modules imported with importModule */;
allModules = l.mapAttrs (imported: imported.module) importedModules;
importModule =
{file, extraArgs}:
let
# stuff
args = {inherit lib;} // allModules // extraArgs;
moduleFunc = import file;
module = moduleFunc args;
dependsOn = let
modulesUsed = l.attrKeys (l.functionArgs moduleFunc);
deps = l.catAttrs modulesUsed modules;
depsFiles = l.map (attrs: attrs.file) deps;
in
depsFiles ++ [file];
in
{inherit module file dependsOn;};
} what this basically does is, it passes all modules to every module. Then, using the function argument names (for the module we are importing), it gets a list of all modules for those and maps the modules to their paths. We export this in a For a builder, this could look like this: # a builder module, say it was under subsystems/rust/builders/crane
{dlib-func1, dlib-func2, ...}: {
type = "pure";
build = {...}: {...}: ...;
} which is basically the same as what we have now, except that we don't take {
module = {
type = "pure";
build = {...}: {...}: ...;
};
file = <the file path of this module>;
dependsOn = [
<the path of this module>
<the path of dlib-func1>
<the path of dlib-func2>
];
} then we can just copy all the files there in a folder (maybe called # nixpkgs
{lib, callPackage, ...}:
let
modules = {
builders-rust-crane = importModule ./lib/builder;
dlib-func1 = importModule ./lib/dlib-func1;
dlib-func2 = importModule ./lib/dlib-func2;
};
importModule = file: import file (modules // {inherit lib;});
in and then the modules can be used. Of course the whole What do you think about this? One downside is you won't be able to use |
BTW, the above also applies to if we switch to nixos modules. It would be even easier with nixos modules since you can just export the |
Now that we have most of the things migrated to nixos modules, the |
The most efficient method of using dream2nix in nixpkgs would probably be to just copy the whole framework into nixpkgs and let individual packages reference the code from there.
But this only makes sense if we have a stable API, otherwise we break tons of packages on each change.
In the mean time I would like to allow for another way of using dream2nix in nixpkgs.
The idea of this feature is to allow users to generate standalone packages via dream2nix. These packages would consist of a dream-lock.json file plus some nix expression.
That nix expression should be minimal and only require nixpkgs as an input, nothing else.
Implementation
We somehow need to know which code/files of dream2nix we need to export and put it alongside the generated dream-lock.json.
This will usually be the nix file of the builder + it's dependencies inside dream2nix + some glue code, executing the builder. This requires some kind of mechanism to detect which other files of dream2nix the builder depends on.
import via symlink architecture
One idea cold be to introduce a policy, so that builders are only allowed to depend on code that is located in the same directory as the builder's
default.nix
. This way we always know which files we need to ship.For other files of the framework required by the builder, we can create a symlink from the builders directory to that file.
The problem is just that builders depend on
externals
anddlib
which are both quite large and we don't want to copy those in full.dlib
We could re-factor dlib, so that each set of independent functions lives in their own file, maximizing the amount of files, and minimizing code per file. Alongside the builders, we can then create symlinks pointing to the few files we depend on and import them from there.
externals
Looking at
externalPaths
in our flake.nix, we already know which ones are the relevant files to install for each external.Now we just need to learn which externals are used by a builder. For this we could add a flag
externalsUsed
to each bilder, signaling the need for an external.@yusdacra I plan to start working on that soon. Let me know in case you have any ideas.
The text was updated successfully, but these errors were encountered: