From 800e72309a4e70ddbcbac7c36fe193988746dd95 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sun, 22 Dec 2024 15:28:43 -0700 Subject: [PATCH 1/5] feat!: remove features API --- .github/workflows/test.yml | 14 ----- atom-nix/README.md | 9 +-- atom-nix/core/compose.nix | 37 ++---------- atom-nix/core/features.nix | 65 --------------------- atom-nix/core/importAtom.nix | 48 +++++---------- atom-nix/core/mod.nix | 9 ++- atom-nix/core@.toml | 4 -- atom-nix/dev@.toml | 5 -- atom-nix/std@.toml | 22 ------- test/features/recursive-features | 1 - test/features/recursive-features-loop | 1 - test/features/recursive-features-loop@.toml | 8 --- test/features/recursive-features@.toml | 8 --- test/features/resolve.nix | 7 --- test/features/resolve.sh | 9 --- test/features/resolve/mod.nix | 6 -- test/scope.toml | 18 ------ test/std-import/default | 1 - test/std-import/default@.toml | 3 - test/std-import/explicit | 1 - test/std-import/explicit@.toml | 8 --- test/std-import/import.nix | 9 --- test/std-import/import.sh | 37 ------------ test/std-import/import/mod.nix | 10 ---- test/std-import/no-std | 1 - test/std-import/no-std@.toml | 6 -- test/std-import/with-lib | 1 - test/std-import/with-lib@.toml | 6 -- 28 files changed, 26 insertions(+), 328 deletions(-) delete mode 100644 atom-nix/core/features.nix delete mode 120000 test/features/recursive-features delete mode 120000 test/features/recursive-features-loop delete mode 100644 test/features/recursive-features-loop@.toml delete mode 100644 test/features/recursive-features@.toml delete mode 100644 test/features/resolve.nix delete mode 100755 test/features/resolve.sh delete mode 100644 test/features/resolve/mod.nix delete mode 100644 test/scope.toml delete mode 120000 test/std-import/default delete mode 100644 test/std-import/default@.toml delete mode 120000 test/std-import/explicit delete mode 100644 test/std-import/explicit@.toml delete mode 100644 test/std-import/import.nix delete mode 100755 test/std-import/import.sh delete mode 100644 test/std-import/import/mod.nix delete mode 120000 test/std-import/no-std delete mode 100644 test/std-import/no-std@.toml delete mode 120000 test/std-import/with-lib delete mode 100644 test/std-import/with-lib@.toml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 63e8d0c..868e378 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,20 +19,6 @@ jobs: - uses: nixbuild/nix-quick-install-action@v28 - name: Code Format Check run: eval "$(nix print-dev-env -f shell.nix)" && treefmt --fail-on-change - std-config: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: nixbuild/nix-quick-install-action@v28 - - name: Std Library Config Test - run: cd test/std-import && ./import.sh > /dev/null - features: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: nixbuild/nix-quick-install-action@v28 - - name: Feature Parsing Test - run: cd test/features && ./resolve.sh > /dev/null purity: runs-on: ubuntu-latest steps: diff --git a/atom-nix/README.md b/atom-nix/README.md index 921bddc..d3716c0 100644 --- a/atom-nix/README.md +++ b/atom-nix/README.md @@ -107,9 +107,6 @@ name = "dev" version = "0.1.0" description = "Development environment" -[features] -default = [] - [fetch.pkgs] name = "nixpkgs" import = true @@ -128,11 +125,7 @@ let atom = builtins.fetchGit "https://github.com/ekala-project/atom"; importAtom = import "${atom}/atom-nix/core/importAtom.nix"; in -importAtom { - features = [ - # enabled flags - ]; -} ./atom-nix/dev.toml +importAtom { } ./atom-nix/dev.toml ``` ## Future Directions: Ekala Platform diff --git a/atom-nix/core/compose.nix b/atom-nix/core/compose.nix index 5b1b91e..002cc9a 100644 --- a/atom-nix/core/compose.nix +++ b/atom-nix/core/compose.nix @@ -60,12 +60,8 @@ in { src, root, - config, + cfg, extern ? { }, - features ? [ ], - # internal features of the composer function - stdFeatures ? core.stdToml.features.default or [ ], - coreFeatures ? core.coreToml.features.default, # enable testing code paths __internal__test ? false, __isStd__ ? false, @@ -73,25 +69,9 @@ in let par = (root + "/${src}"); - std = core.importStd { - features = stdFeatures; - inherit __internal__test; - } (../. + "/std@.toml"); + std = core.importStd { inherit __internal__test; } (../. + "/std@.toml"); - coreFeatures' = core.features.resolve core.coreToml.features coreFeatures; - stdFeatures' = core.features.resolve core.stdToml.features stdFeatures; - - cfg = config // { - features = config.features or { } // { - resolved = { - atom = features; - core = coreFeatures'; - std = stdFeatures'; - }; - }; - }; - - msg = core.errors.debugMsg config; + msg = core.errors.debugMsg cfg; f = f: pre: dir: @@ -125,13 +105,12 @@ let preOpt { _if = !__isStd__; + + inherit std; atom = atomScope; + _else.std = atomScope; } - { - _if = !__isStd__ && l.elem "std" coreFeatures'; - inherit std; - } { _if = __internal__test; # information about the internal module system itself @@ -206,10 +185,6 @@ let in core.set.inject fixed [ ({ _if = __isStd__; } // core.pureBuiltinsForStd fixed) - { - _if = __isStd__ && l.elem "lib" cfg.features.resolved.atom; - inherit (extern) lib; - } { _if = __isStd__ && __internal__test; __internal = { diff --git a/atom-nix/core/features.nix b/atom-nix/core/features.nix deleted file mode 100644 index 7241094..0000000 --- a/atom-nix/core/features.nix +++ /dev/null @@ -1,65 +0,0 @@ -let - l = builtins; -in -{ - /** - Resolve feature dependencies for Atom's module composer. - - This function takes a set of features and their dependencies, and an initial list of features. - It returns a list of all required features, including dependencies, without duplicates. - - # Examples - - Given a TOML file with feature declarations: - - ```toml - [features] - default = ["foo", "bar"] - foo = ["baz"] - bar = ["qux"] - baz = [] - qux = ["baz"] - ``` - - Nix usage: - - ```nix - features.resolve featureSet ["foo", "bar"] => ["foo", "baz", "bar", "qux"] - ``` - - # Type - - ``` - features.resolve :: AttrSet -> [String] -> [String] - ``` - - # Parameters - - - `featureSet`: An attribute set where keys are feature names and values are lists of dependencies. - - `initials`: A list of initially requested features. - - # Return Value - - A list of strings representing all required features, including dependencies, without duplicates. - - # Notes - - - The function handles circular dependencies. - - The order of features in the output list is not guaranteed. - - Features not present in the `featureSet` are ignored. - */ - resolve = - featureSet: initials: - let - resolve = - features: acc: - let - features' = l.filter (f: !(acc ? ${f})) features; - acc' = l.foldl' (a: f: a // { ${f} = null; }) acc features'; - in - if features' == [ ] then acc' else resolve (l.concatMap (f: featureSet.${f} or [ ]) features') acc'; - - resolved = resolve initials { }; - in - l.attrNames resolved; -} diff --git a/atom-nix/core/importAtom.nix b/atom-nix/core/importAtom.nix index f86ed6f..1872c43 100644 --- a/atom-nix/core/importAtom.nix +++ b/atom-nix/core/importAtom.nix @@ -16,8 +16,8 @@ valid input (and the CLI should type check on it's end) */ { - features ? null, __internal__test ? false, + __isStd__ ? false, }: path': let @@ -26,22 +26,12 @@ let path = mod.prepDir path'; file = builtins.readFile path; - config = builtins.fromTOML file; - atom = config.atom or { }; + manifest = builtins.fromTOML file; + atom = manifest.atom or { }; id = builtins.seq version (atom.id or (mod.errors.missingAtom path' "id")); version = atom.version or (mod.errors.missingAtom path' "version"); - core = config.core or { }; - std = config.std or { }; - - features' = - let - featSet = config.features or { }; - featIn = if features == null then featSet.default or [ ] else features; - in - mod.features.resolve featSet featIn; - - backend = config.backend or { }; + backend = manifest.backend or { }; nix = backend.nix or { }; root = mod.prepDir (dirOf path); @@ -55,7 +45,7 @@ let extern = let fetcher = nix.fetcher or "native"; # native doesn't exist yet - conf = config.fetcher or { }; + conf = manifest.fetcher or { }; f = conf.${fetcher} or { }; root = f.root or "npins"; in @@ -82,37 +72,25 @@ let else src; in - if (v.optional or false && builtins.elem k features') || (!v.optional or false) then - { "${k}" = val; } - else - null - ) config.fetch or { } + { + "${k}" = val; + } + ) manifest.fetch or { } # else if fetcher = "native", etc else { }; - meta = atom.meta or { }; - in mod.compose { inherit extern __internal__test - config + __isStd__ root src ; - features = features'; - coreFeatures = - let - feat = core.features or mod.coreToml.features.default; - in - mod.features.resolve mod.coreToml.features feat; - stdFeatures = - let - feat = std.features or mod.stdToml.features.default; - in - mod.features.resolve mod.stdToml.features feat; - __isStd__ = meta.__is_std__ or false; + cfg = { + inherit (manifest) atom; + }; } diff --git a/atom-nix/core/mod.nix b/atom-nix/core/mod.nix index 058ae54..93fe914 100644 --- a/atom-nix/core/mod.nix +++ b/atom-nix/core/mod.nix @@ -49,8 +49,6 @@ rec { errors = import ./errors.nix; - features = import ./features.nix; - lowerKeys = filterMap (k: v: { ${toLowerCase k} = v; }); collectPublic = filterMap ( @@ -78,7 +76,12 @@ rec { ); }; - importStd = opts: importAtom { inherit (opts) __internal__test features; }; + importStd = + opts: + importAtom { + inherit (opts) __internal__test; + __isStd__ = true; + }; modIsValid = mod: dir: diff --git a/atom-nix/core@.toml b/atom-nix/core@.toml index 2e91a0a..900f3c3 100644 --- a/atom-nix/core@.toml +++ b/atom-nix/core@.toml @@ -2,7 +2,3 @@ id = "core" version = "0.3.0" description = "A purpose built, unopinionated, and performant module system for Nix code." - -[features] -std = [] -default = ["std"] diff --git a/atom-nix/dev@.toml b/atom-nix/dev@.toml index 54b2022..b8d533d 100644 --- a/atom-nix/dev@.toml +++ b/atom-nix/dev@.toml @@ -7,11 +7,6 @@ name = "nixpkgs" import = true args = [{}] -[core] -features = ["std"] -[std] -features = ["lib"] - [backend.nix] # default when `eka` cli is ready # fetcher = "native" diff --git a/atom-nix/std@.toml b/atom-nix/std@.toml index 77b5d27..c5605c1 100644 --- a/atom-nix/std@.toml +++ b/atom-nix/std@.toml @@ -2,25 +2,3 @@ id = "std" version = "0.2.0" description = "Nix Standard Library" - -[fetch.lib] # the name in `atom` scope -name = "nixpkgs.lib" # the name in npins -import = true -subdir = "lib" -optional = true -# TODO: fetched at eval time -type = "lib" -# TODO: fetched at buildtime -# type = "src" - -[backend.nix] -fetcher = "npins" - -[atom.meta] -# special attribute -# for the Nix std library -__is_std__ = true - -[features] -lib = [] -default = [] diff --git a/test/features/recursive-features b/test/features/recursive-features deleted file mode 120000 index 48879a0..0000000 --- a/test/features/recursive-features +++ /dev/null @@ -1 +0,0 @@ -resolve \ No newline at end of file diff --git a/test/features/recursive-features-loop b/test/features/recursive-features-loop deleted file mode 120000 index 48879a0..0000000 --- a/test/features/recursive-features-loop +++ /dev/null @@ -1 +0,0 @@ -resolve \ No newline at end of file diff --git a/test/features/recursive-features-loop@.toml b/test/features/recursive-features-loop@.toml deleted file mode 100644 index 7da0640..0000000 --- a/test/features/recursive-features-loop@.toml +++ /dev/null @@ -1,8 +0,0 @@ -[atom] -id = "features-loop" -version = "0.1.0" - -[features] -a = ["b", "c"] -c = ["b"] -default = ["a"] diff --git a/test/features/recursive-features@.toml b/test/features/recursive-features@.toml deleted file mode 100644 index 86b937a..0000000 --- a/test/features/recursive-features@.toml +++ /dev/null @@ -1,8 +0,0 @@ -[atom] -id = "features" -version = "0.1.0" - -[features] -a = ["b"] -b = ["c"] -default = ["a"] diff --git a/test/features/resolve.nix b/test/features/resolve.nix deleted file mode 100644 index 5d2f78e..0000000 --- a/test/features/resolve.nix +++ /dev/null @@ -1,7 +0,0 @@ -let - f = import ../../atom-nix/core/importAtom.nix { __internal__test = true; }; -in -{ - recursive-features = f (./. + "/recursive-features@.toml"); - recursive-features-loop = f (./. + "/recursive-features-loop@.toml"); -} diff --git a/test/features/resolve.sh b/test/features/resolve.sh deleted file mode 100755 index 763d75c..0000000 --- a/test/features/resolve.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -f="$(nix eval -f resolve.nix recursive-features.resolved)" -[[ "$f" == '[ "a" "b" "c" ]' ]] - -f="$(nix eval -f resolve.nix recursive-features-loop.resolved)" -[[ "$f" == '[ "a" "b" "c" ]' ]] diff --git a/test/features/resolve/mod.nix b/test/features/resolve/mod.nix deleted file mode 100644 index cd40ea6..0000000 --- a/test/features/resolve/mod.nix +++ /dev/null @@ -1,6 +0,0 @@ -let - inherit (__internal) scope; -in -{ - Resolved = cfg.features.resolved.atom; -} diff --git a/test/scope.toml b/test/scope.toml deleted file mode 100644 index 3215b58..0000000 --- a/test/scope.toml +++ /dev/null @@ -1,18 +0,0 @@ -[fetch.lib] -name = "nixpkgs.lib" -import = true -sub = "lib" -optional = true - -[features] -lib = [] -default = [] - -[backends.nix] -root = "std" -fetcher = "npins" - -[project.meta] -# special attribute -# for the Nix std library -__is_std__ = true diff --git a/test/std-import/default b/test/std-import/default deleted file mode 120000 index efca996..0000000 --- a/test/std-import/default +++ /dev/null @@ -1 +0,0 @@ -import \ No newline at end of file diff --git a/test/std-import/default@.toml b/test/std-import/default@.toml deleted file mode 100644 index 84239b5..0000000 --- a/test/std-import/default@.toml +++ /dev/null @@ -1,3 +0,0 @@ -[atom] -id = "std-test" -version = "0.1.0" diff --git a/test/std-import/explicit b/test/std-import/explicit deleted file mode 120000 index efca996..0000000 --- a/test/std-import/explicit +++ /dev/null @@ -1 +0,0 @@ -import \ No newline at end of file diff --git a/test/std-import/explicit@.toml b/test/std-import/explicit@.toml deleted file mode 100644 index 1127c58..0000000 --- a/test/std-import/explicit@.toml +++ /dev/null @@ -1,8 +0,0 @@ -[atom] -id = "explicit-test" -version = "0.1.0" - -[core] -features = ["std"] -[std] -features = [] diff --git a/test/std-import/import.nix b/test/std-import/import.nix deleted file mode 100644 index cd02e5c..0000000 --- a/test/std-import/import.nix +++ /dev/null @@ -1,9 +0,0 @@ -let - f = import ../../atom-nix/core/importAtom.nix { __internal__test = true; }; -in -{ - default = f (./. + "/default@.toml"); - noStd = f (./. + "/no-std@.toml"); - explicit = f (./. + "/explicit@.toml"); - withLib = f (./. + "/with-lib@.toml"); -} diff --git a/test/std-import/import.sh b/test/std-import/import.sh deleted file mode 100755 index 71034a3..0000000 --- a/test/std-import/import.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -# defaults -f="$(nix eval -f import.nix default.coreF)" -[[ "$f" == '[ "std" ]' ]] -f="$(nix eval -f import.nix default.std)" -[[ "$f" == true ]] -f="$(nix eval -f import.nix default.lib)" -[[ "$f" == false ]] -f="$(nix eval -f import.nix default.sanity)" -[[ "$f" == true ]] - -# explicit -f="$(nix eval -f import.nix explicit.coreF)" -[[ "$f" == '[ "std" ]' ]] -f="$(nix eval -f import.nix explicit.std)" -[[ "$f" == true ]] -f="$(nix eval -f import.nix explicit.lib)" -[[ "$f" == false ]] - -# no std set -f="$(nix eval -f import.nix noStd.coreF)" -[[ "$f" == '[ ]' ]] -f="$(nix eval -f import.nix noStd.std)" -[[ "$f" == false ]] -f="$(nix eval -f import.nix noStd.lib)" -[[ "$f" == false ]] - -# no std set -f="$(nix eval -f import.nix withLib.stdF)" -[[ "$f" == '[ "lib" ]' ]] -f="$(nix eval -f import.nix withLib.std)" -[[ "$f" == true ]] -f="$(nix eval -f import.nix withLib.lib)" -[[ "$f" == true ]] diff --git a/test/std-import/import/mod.nix b/test/std-import/import/mod.nix deleted file mode 100644 index 1a73bcb..0000000 --- a/test/std-import/import/mod.nix +++ /dev/null @@ -1,10 +0,0 @@ -let - inherit (__internal) scope; -in -{ - Std = scope ? std; - Lib = scope ? std && scope.std ? lib; - CoreF = cfg.features.resolved.core; - StdF = cfg.features.resolved.std; - Sanity = scope.std.__internal.__isStd__; -} diff --git a/test/std-import/no-std b/test/std-import/no-std deleted file mode 120000 index efca996..0000000 --- a/test/std-import/no-std +++ /dev/null @@ -1 +0,0 @@ -import \ No newline at end of file diff --git a/test/std-import/no-std@.toml b/test/std-import/no-std@.toml deleted file mode 100644 index bba4291..0000000 --- a/test/std-import/no-std@.toml +++ /dev/null @@ -1,6 +0,0 @@ -[atom] -id = "no-std-test" -version = "0.1.0" - -[core] -features = [] # default is ["std"] diff --git a/test/std-import/with-lib b/test/std-import/with-lib deleted file mode 120000 index efca996..0000000 --- a/test/std-import/with-lib +++ /dev/null @@ -1 +0,0 @@ -import \ No newline at end of file diff --git a/test/std-import/with-lib@.toml b/test/std-import/with-lib@.toml deleted file mode 100644 index 8902549..0000000 --- a/test/std-import/with-lib@.toml +++ /dev/null @@ -1,6 +0,0 @@ -[atom] -id = "with-lib-test" -version = "0.1.0" - -[std] -features = ["lib"] From 5df98c4d6a177ba92a2aa10103d45533ef3a6ec3 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sun, 22 Dec 2024 16:54:46 -0700 Subject: [PATCH 2/5] feat!: simplified compose API --- atom-nix/core/compose.nix | 75 +++++++----------------------------- atom-nix/core/importAtom.nix | 32 ++++++++------- atom-nix/core/mod.nix | 58 ++++++++++++++-------------- test/purity/purity.nix | 13 ++++--- test/purity/test/mod.nix | 2 +- test/purity/test@.toml | 3 -- 6 files changed, 69 insertions(+), 114 deletions(-) delete mode 100644 test/purity/test@.toml diff --git a/atom-nix/core/compose.nix b/atom-nix/core/compose.nix index 002cc9a..2715bd3 100644 --- a/atom-nix/core/compose.nix +++ b/atom-nix/core/compose.nix @@ -58,18 +58,13 @@ let core = import ./mod.nix; in { - src, root, cfg, - extern ? { }, - # enable testing code paths - __internal__test ? false, - __isStd__ ? false, + get ? { }, }: let - par = (root + "/${src}"); - std = core.importStd { inherit __internal__test; } (../. + "/std@.toml"); + std = core.importStd (../. + "/std@.toml"); msg = core.errors.debugMsg cfg; @@ -85,8 +80,13 @@ let scope = let - scope' = with core; { - inherit cfg; + static = with core; { + inherit + cfg + std + atom + get + ; mod = modScope; builtins = std; import = errors.import; @@ -98,34 +98,10 @@ let __storePath = errors.storePath; __getEnv = errors.getEnv ""; __getFlake = errors.import; - get = extern; }; - scope'' = core.set.inject scope' [ - preOpt - { - _if = !__isStd__; - - inherit std; - atom = atomScope; - - _else.std = atomScope; - } - { - _if = __internal__test; - # information about the internal module system itself - # available to tests - __internal = { - # a copy of the global scope, for testing if values exist - # for our internal testing functions - scope = scope''; - inherit __isStd__ __internal__test; - src = core; - }; - } - ]; in - scope''; + core.set.inject static [ preOpt ]; Import = scopedImport scope; @@ -143,7 +119,7 @@ let { ${file.name} = let - trace = core.errors.modPath par dir; + trace = core.errors.modPath root dir; in core.errors.context (msg "${trace}.${file.name}") member; } @@ -162,7 +138,7 @@ let name = baseNameOf path; } ); - trace = core.errors.modPath par dir; + trace = core.errors.modPath root dir; in assert core.modIsValid module dir; core.filterMap g contents // (core.errors.context (msg trace) module); @@ -174,31 +150,6 @@ let # Base case: no module { }; - atomScope = l.removeAttrs atom [ - "atom" - (baseNameOf par) - ]; - - atom = - let - fixed = core.fix f null par; - in - core.set.inject fixed [ - ({ _if = __isStd__; } // core.pureBuiltinsForStd fixed) - { - _if = __isStd__ && __internal__test; - __internal = { - inherit __isStd__; - }; - } - ]; + atom = core.fix f null root; in -assert - !__internal__test - # older versions of Nix don't have the `warn` builtin - || core.errors.warn '' - in ${toString ./default.nix}: - Internal testing functionality is enabled via the `__test` boolean. - This should never be `true` except in internal test runs. - '' true; atom diff --git a/atom-nix/core/importAtom.nix b/atom-nix/core/importAtom.nix index 1872c43..e978c95 100644 --- a/atom-nix/core/importAtom.nix +++ b/atom-nix/core/importAtom.nix @@ -16,14 +16,13 @@ valid input (and the CLI should type check on it's end) */ { - __internal__test ? false, - __isStd__ ? false, + cfg ? { }, }: path': let mod = import ./mod.nix; - path = mod.prepDir path'; + path = mod.prepPath path'; file = builtins.readFile path; manifest = builtins.fromTOML file; @@ -34,7 +33,7 @@ let backend = manifest.backend or { }; nix = backend.nix or { }; - root = mod.prepDir (dirOf path); + root = mod.prepPath (dirOf path); src = builtins.seq id ( let file = mod.parse (baseNameOf path); @@ -42,7 +41,7 @@ let in builtins.substring 0 (len - 1) file.name ); - extern = + get = let fetcher = nix.fetcher or "native"; # native doesn't exist yet conf = manifest.fetcher or { }; @@ -63,7 +62,7 @@ let builtins.foldl' ( f: x: let - intersect = x // (builtins.intersectAttrs x extern); + intersect = x // (builtins.intersectAttrs x get); in if builtins.isAttrs x then f intersect else f x ) (import src) v.args @@ -80,17 +79,22 @@ let else { }; + parsedCfg = + if builtins.isString cfg then + builtins.fromJSON cfg + else if builtins.isPath cfg then + builtins.fromJSON (builtins.readFile cfg) + else if builtins.isAttrs cfg then + cfg + else + mod.errors.warn "ignoring invalid config" { }; + in mod.compose { - inherit - extern - __internal__test - __isStd__ - root - src - ; + inherit get; - cfg = { + root = root + "/${src}"; + cfg = parsedCfg // { inherit (manifest) atom; }; } diff --git a/atom-nix/core/mod.nix b/atom-nix/core/mod.nix index 93fe914..dbe96bb 100644 --- a/atom-nix/core/mod.nix +++ b/atom-nix/core/mod.nix @@ -23,6 +23,29 @@ let } ../std/string/toLowerCase.nix; stdToml = l.fromTOML (l.readFile (../. + "/std@.toml")); coreToml = l.fromTOML (l.readFile (../. + "/core@.toml")); + pureBuiltinsForStd = + std: + filterMap ( + builtin: f: + if stdFilter builtin != null then + null + else + { + ${builtin} = + if std ? ${builtin} then + if l.isAttrs std.${builtin} then + ## if std exports builtins named the same as a builtin funciton + ## such as `std.path`, then rexport std's version as a set + std.${builtin} // { __functor = _: f; } + else + ## if std's output is not an attribute set, prefer its version + std.${builtin} + else + ## re-export all non-conflicting builtins + f; + } + ) builtins; + in rec { inherit @@ -77,11 +100,11 @@ rec { }; importStd = - opts: - importAtom { - inherit (opts) __internal__test; - __isStd__ = true; - }; + path: + let + std = importAtom { } path; + in + std // pureBuiltinsForStd std; modIsValid = mod: dir: @@ -91,35 +114,12 @@ rec { ${toString dir}/mod.nix ''; - pureBuiltinsForStd = - std: - filterMap ( - builtin: f: - if stdFilter builtin != null then - null - else - { - ${builtin} = - if std ? ${builtin} then - if l.isAttrs std.${builtin} then - ## if std exports builtins named the same as a builtin funciton - ## such as `std.path`, then rexport std's version as a set - std.${builtin} // { __functor = _: f; } - else - ## if std's output is not an attribute set, prefer its version - std.${builtin} - else - ## re-export all non-conflicting builtins - f; - } - ) builtins; - hasMod = contents: contents."mod.nix" or null == "regular"; # It is crucial that the directory is a path literal, not a string # since the implicit copy to the /nix/store, which provides isolation, # only happens for path literals. - prepDir = + prepPath = dir: let dir' = diff --git a/test/purity/purity.nix b/test/purity/purity.nix index ffe10fa..83d1ac6 100644 --- a/test/purity/purity.nix +++ b/test/purity/purity.nix @@ -1,8 +1,11 @@ let - f = import ../../atom-nix/core/importAtom.nix; - atom = f { __internal__test = true; } ( - # added to test implicit path conversion when path is a string - builtins.toPath (./. + "/test@.toml") - ); + f = import ../../atom-nix/core/compose.nix; + atom = f { + get.stdFilter = import ../../atom-nix/core/stdFilter.nix; + cfg = { }; + root = + # added to test implicit path conversion when path is a string + builtins.toPath (./. + "/test"); + }; in atom diff --git a/test/purity/test/mod.nix b/test/purity/test/mod.nix index 7ae23ac..73f503f 100644 --- a/test/purity/test/mod.nix +++ b/test/purity/test/mod.nix @@ -11,7 +11,7 @@ GetFlake = !std ? getFlake && __getFlake; Std = let - xs = map (x: __internal.src.stdFilter x == null) (std.attrNames std); + xs = map (x: get.stdFilter x == null) (std.attrNames std); in std.elem false xs && abort "impure functions found"; } diff --git a/test/purity/test@.toml b/test/purity/test@.toml deleted file mode 100644 index 91e0e44..0000000 --- a/test/purity/test@.toml +++ /dev/null @@ -1,3 +0,0 @@ -[atom] -id = "test" -version = "0.1.0" From 5fe2e3196518b8ba29b4168839d24b323f634bc9 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sun, 22 Dec 2024 17:59:24 -0700 Subject: [PATCH 3/5] refactor!: modify importAtom API simplify the API by inverting the manifest path handling, and also allows calling from the cli, by passing named args on the cli. --- atom-nix/README.md | 2 +- atom-nix/core/compose.nix | 2 +- atom-nix/core/importAtom.nix | 22 +++++++--------------- atom-nix/core/mod.nix | 6 +----- shell.nix | 2 +- test/integrity/bld.nix | 6 +++--- test/pre.nix | 2 +- test/purity/purity.nix | 2 +- 8 files changed, 16 insertions(+), 28 deletions(-) diff --git a/atom-nix/README.md b/atom-nix/README.md index d3716c0..75218c3 100644 --- a/atom-nix/README.md +++ b/atom-nix/README.md @@ -125,7 +125,7 @@ let atom = builtins.fetchGit "https://github.com/ekala-project/atom"; importAtom = import "${atom}/atom-nix/core/importAtom.nix"; in -importAtom { } ./atom-nix/dev.toml +importAtom { path = ./atom-nix/dev; } ``` ## Future Directions: Ekala Platform diff --git a/atom-nix/core/compose.nix b/atom-nix/core/compose.nix index 2715bd3..ef6bd15 100644 --- a/atom-nix/core/compose.nix +++ b/atom-nix/core/compose.nix @@ -64,7 +64,7 @@ in }: let - std = core.importStd (../. + "/std@.toml"); + std = core.importStd (../std); msg = core.errors.debugMsg cfg; diff --git a/atom-nix/core/importAtom.nix b/atom-nix/core/importAtom.nix index e978c95..e938b6c 100644 --- a/atom-nix/core/importAtom.nix +++ b/atom-nix/core/importAtom.nix @@ -17,30 +17,22 @@ */ { cfg ? { }, + path, }: -path': let mod = import ./mod.nix; - path = mod.prepPath path'; + dir = mod.prepPath path; - file = builtins.readFile path; + file = builtins.readFile (dir + "@.toml"); manifest = builtins.fromTOML file; atom = manifest.atom or { }; - id = builtins.seq version (atom.id or (mod.errors.missingAtom path' "id")); - version = atom.version or (mod.errors.missingAtom path' "version"); + id = builtins.seq version (atom.id or (mod.errors.missingAtom path "id")); + version = atom.version or (mod.errors.missingAtom path "version"); backend = manifest.backend or { }; nix = backend.nix or { }; - root = mod.prepPath (dirOf path); - src = builtins.seq id ( - let - file = mod.parse (baseNameOf path); - len = builtins.stringLength file.name; - in - builtins.substring 0 (len - 1) file.name - ); get = let fetcher = nix.fetcher or "native"; # native doesn't exist yet @@ -50,7 +42,7 @@ let in if fetcher == "npins" then let - pins = import (dirOf path + "/${root}"); + pins = import (dirOf dir + "/${root}"); in mod.filterMap ( k: v: @@ -93,7 +85,7 @@ in mod.compose { inherit get; - root = root + "/${src}"; + root = builtins.seq id dir; cfg = parsedCfg // { inherit (manifest) atom; }; diff --git a/atom-nix/core/mod.nix b/atom-nix/core/mod.nix index dbe96bb..e579c7a 100644 --- a/atom-nix/core/mod.nix +++ b/atom-nix/core/mod.nix @@ -21,8 +21,6 @@ let std = builtins; mod = scopedImport { inherit mod std; } ../std/string/mod.nix; } ../std/string/toLowerCase.nix; - stdToml = l.fromTOML (l.readFile (../. + "/std@.toml")); - coreToml = l.fromTOML (l.readFile (../. + "/core@.toml")); pureBuiltinsForStd = std: filterMap ( @@ -53,8 +51,6 @@ rec { parse filterMap stdFilter - stdToml - coreToml ; path = { @@ -102,7 +98,7 @@ rec { importStd = path: let - std = importAtom { } path; + std = importAtom { inherit path; }; in std // pureBuiltinsForStd std; diff --git a/shell.nix b/shell.nix index 06dc9c3..72b2e0b 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,4 @@ let - dev = (import ./atom-nix/core/importAtom.nix) { } (./. + "/atom-nix/dev@.toml"); + dev = (import ./atom-nix/core/importAtom.nix) { path = ./atom-nix/dev; }; in dev.shell diff --git a/test/integrity/bld.nix b/test/integrity/bld.nix index 7ad6393..96f6cf5 100644 --- a/test/integrity/bld.nix +++ b/test/integrity/bld.nix @@ -1,8 +1,8 @@ let f = import ../../atom-nix/core/importAtom.nix; - atom = f { } ( + atom = f { # added to test implicit path conversion when path is a string - builtins.toPath (./. + "/bld@.toml") - ); + path = builtins.toPath ./bld; + }; in builtins.deepSeq atom atom diff --git a/test/pre.nix b/test/pre.nix index bd79030..0fde756 100644 --- a/test/pre.nix +++ b/test/pre.nix @@ -1 +1 @@ -(import ../atom-nix/core/importAtom.nix { }) (./. + "/pre@.toml") +import ../atom-nix/core/importAtom.nix { path = ./pre; } diff --git a/test/purity/purity.nix b/test/purity/purity.nix index 83d1ac6..0b9d697 100644 --- a/test/purity/purity.nix +++ b/test/purity/purity.nix @@ -5,7 +5,7 @@ let cfg = { }; root = # added to test implicit path conversion when path is a string - builtins.toPath (./. + "/test"); + builtins.toPath ./test; }; in atom From 7cc65decc6976dde814f7892f20e83187357179c Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sun, 22 Dec 2024 18:14:32 -0700 Subject: [PATCH 4/5] remove!: remove npins integration instead parse eka produced locks with #42, which builds off of this PR --- atom-nix/README.md | 5 +-- atom-nix/core/importAtom.nix | 41 +---------------- atom-nix/dev/shell.nix | 1 - atom-nix/dev@.toml | 13 ------ atom-nix/npins/default.nix | 80 --------------------------------- atom-nix/npins/sources.json | 23 ---------- atom-nix/std/set/mergeUntil.nix | 10 +++-- shell.nix | 6 ++- treefmt.toml | 2 +- 9 files changed, 14 insertions(+), 167 deletions(-) delete mode 100644 atom-nix/npins/default.nix delete mode 100644 atom-nix/npins/sources.json diff --git a/atom-nix/README.md b/atom-nix/README.md index 75218c3..9ccb27b 100644 --- a/atom-nix/README.md +++ b/atom-nix/README.md @@ -107,10 +107,7 @@ name = "dev" version = "0.1.0" description = "Development environment" -[fetch.pkgs] -name = "nixpkgs" -import = true -args = [{}] +# TODO ``` ## Usage (Unstable) diff --git a/atom-nix/core/importAtom.nix b/atom-nix/core/importAtom.nix index e938b6c..f82e4ef 100644 --- a/atom-nix/core/importAtom.nix +++ b/atom-nix/core/importAtom.nix @@ -30,46 +30,7 @@ let id = builtins.seq version (atom.id or (mod.errors.missingAtom path "id")); version = atom.version or (mod.errors.missingAtom path "version"); - backend = manifest.backend or { }; - nix = backend.nix or { }; - - get = - let - fetcher = nix.fetcher or "native"; # native doesn't exist yet - conf = manifest.fetcher or { }; - f = conf.${fetcher} or { }; - root = f.root or "npins"; - in - if fetcher == "npins" then - let - pins = import (dirOf dir + "/${root}"); - in - mod.filterMap ( - k: v: - let - src = "${pins.${v.name or k}}/${v.subdir or ""}"; - val = - if v.import or false then - if v.args or [ ] != [ ] then - builtins.foldl' ( - f: x: - let - intersect = x // (builtins.intersectAttrs x get); - in - if builtins.isAttrs x then f intersect else f x - ) (import src) v.args - else - import src - else - src; - in - { - "${k}" = val; - } - ) manifest.fetch or { } - # else if fetcher = "native", etc - else - { }; + get = { }; # TODO: handled in https://github.com/ekala-project/atom/pull/42 parsedCfg = if builtins.isString cfg then diff --git a/atom-nix/dev/shell.nix b/atom-nix/dev/shell.nix index cb99462..3f2389d 100644 --- a/atom-nix/dev/shell.nix +++ b/atom-nix/dev/shell.nix @@ -4,7 +4,6 @@ pkgs.mkShell { packages = with pkgs; [ treefmt - npins nixfmt-rfc-style shfmt taplo diff --git a/atom-nix/dev@.toml b/atom-nix/dev@.toml index b8d533d..bfa91d3 100644 --- a/atom-nix/dev@.toml +++ b/atom-nix/dev@.toml @@ -1,16 +1,3 @@ [atom] id = "dev" version = "0.2.0" - -[fetch.pkgs] -name = "nixpkgs" -import = true -args = [{}] - -[backend.nix] -# default when `eka` cli is ready -# fetcher = "native" -fetcher = "npins" - -[fetcher.npins] -root = "npins" diff --git a/atom-nix/npins/default.nix b/atom-nix/npins/default.nix deleted file mode 100644 index 5e7d086..0000000 --- a/atom-nix/npins/default.nix +++ /dev/null @@ -1,80 +0,0 @@ -# Generated by npins. Do not modify; will be overwritten regularly -let - data = builtins.fromJSON (builtins.readFile ./sources.json); - version = data.version; - - mkSource = - spec: - assert spec ? type; - let - path = - if spec.type == "Git" then - mkGitSource spec - else if spec.type == "GitRelease" then - mkGitSource spec - else if spec.type == "PyPi" then - mkPyPiSource spec - else if spec.type == "Channel" then - mkChannelSource spec - else - builtins.throw "Unknown source type ${spec.type}"; - in - spec // { outPath = path; }; - - mkGitSource = - { - repository, - revision, - url ? null, - hash, - branch ? null, - ... - }: - assert repository ? type; - # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository - # In the latter case, there we will always be an url to the tarball - if url != null then - (builtins.fetchTarball { - inherit url; - sha256 = hash; # FIXME: check nix version & use SRI hashes - }) - else - assert repository.type == "Git"; - let - urlToName = - url: rev: - let - matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url; - - short = builtins.substring 0 7 rev; - - appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else ""; - in - "${if matched == null then "source" else builtins.head matched}${appendShort}"; - name = urlToName repository.url revision; - in - builtins.fetchGit { - url = repository.url; - rev = revision; - inherit name; - # hash = hash; - }; - - mkPyPiSource = - { url, hash, ... }: - builtins.fetchurl { - inherit url; - sha256 = hash; - }; - - mkChannelSource = - { url, hash, ... }: - builtins.fetchTarball { - inherit url; - sha256 = hash; - }; -in -if version == 3 then - builtins.mapAttrs (_: mkSource) data.pins -else - throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`" diff --git a/atom-nix/npins/sources.json b/atom-nix/npins/sources.json deleted file mode 100644 index a66a32d..0000000 --- a/atom-nix/npins/sources.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "pins": { - "nixpkgs": { - "type": "Channel", - "name": "nixpkgs-unstable", - "url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.11pre660607.c3392ad349a5/nixexprs.tar.xz", - "hash": "1g2p74w085252qbxjymrzzccd203bfwxh8sbcyvbzan6bgqfvwi1" - }, - "nixpkgs.lib": { - "type": "Git", - "repository": { - "type": "GitHub", - "owner": "nix-community", - "repo": "nixpkgs.lib" - }, - "branch": "master", - "revision": "8bebd4c74f368aacb047f0141db09ec6b339733c", - "url": "https://github.com/nix-community/nixpkgs.lib/archive/8bebd4c74f368aacb047f0141db09ec6b339733c.tar.gz", - "hash": "0vzy9hs0k8zi9h4lx1krq578j3wdc62d6g4hddxj9sfkdmz8r3bn" - } - }, - "version": 3 -} \ No newline at end of file diff --git a/atom-nix/std/set/mergeUntil.nix b/atom-nix/std/set/mergeUntil.nix index 0c9b8da..be66e79 100644 --- a/atom-nix/std/set/mergeUntil.nix +++ b/atom-nix/std/set/mergeUntil.nix @@ -69,7 +69,9 @@ let f here values ); in -f [ ] [ - rhs - lhs -] +f + [ ] + [ + rhs + lhs + ] diff --git a/shell.nix b/shell.nix index 72b2e0b..7dc119d 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,8 @@ let - dev = (import ./atom-nix/core/importAtom.nix) { path = ./atom-nix/dev; }; + dev = (import ./atom-nix/core/compose.nix) { + root = ./atom-nix/dev; + cfg = { }; + get.pkgs = import { }; + }; in dev.shell diff --git a/treefmt.toml b/treefmt.toml index 5c2618a..deea35f 100644 --- a/treefmt.toml +++ b/treefmt.toml @@ -20,4 +20,4 @@ excludes = [] command = "prettier" options = ["--write"] includes = ["*.json", "*.md", "*.yaml", "*.yml"] -excludes = ["*/sources.json"] +excludes = ["*/sources.json", ".github/CODE_OF_CONDUCT.md"] From d138aa32e4dc959753af06efe43f7e09041e2778 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sun, 22 Dec 2024 18:25:31 -0700 Subject: [PATCH 5/5] ci: fix CI until locking is finished --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 868e378..e2d9bd9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,8 @@ jobs: run: cd test/integrity && ./bld.sh format: runs-on: ubuntu-latest + env: + NIX_PATH: nixpkgs=https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz steps: - uses: actions/checkout@v4 - uses: nixbuild/nix-quick-install-action@v28