Compare commits

...
Sign in to create a new pull request.

9 commits

Author SHA1 Message Date
6e22a8de3e
primop (stash) 2026-03-15 03:18:39 +10:00
03c72f7582
snow-cli test 2026-03-13 00:42:54 +10:00
9c188c46c9
da future 2026-03-09 02:54:01 +10:00
0314109bc0
begin cerulean's rust cli 2026-03-09 02:44:50 +10:00
2f49295004
backup bash cli 2026-03-09 02:43:40 +10:00
ff0d13034b
"CHANGELOG" my ass, ts hasn't changed at all... 2026-03-08 17:32:45 +10:00
89e36243b2
rename /cerulean -> /nix 2026-03-08 17:30:32 +10:00
dc769da2bd
remove legacy cerulean.mkFlake 2026-03-08 17:29:43 +10:00
aaf9d6422b
progress version 2026-03-08 17:29:24 +10:00
42 changed files with 2736 additions and 198 deletions

View file

@ -31,3 +31,11 @@ Minor patches
## v0.2.4-alpha
- `homeManager` flake reference may now be specified in snowflake
- ``
## v0.2.5-alpha
>[!TODO]
> I've been too focused on upcoming changes...
## v0.2.6-alpha
>[!TODO]
> I've been too focused on upcoming changes...

10
TODO.md
View file

@ -1,4 +1,14 @@
## Next
- [ ] figure out how Cerulean could aid CI/CD (ie hydra + nix-unit)
you can
https://github.com/NotAShelf/nix-bindings/tree/main/nix-bindings
https://notashelf.github.io/nix-bindings/nix_bindings/#structs
https://github.com/nixops4/nix-bindings-rust
https://nix.dev/manual/nix/2.34/c-api.html
- [ ] write a key management system that supports activation time, run time, and build time
https://docs.aws.amazon.com/kms/latest/developerguide/overview.html
- [ ] formalize how the snow flake system compiles outputs, this would remove the need for `mapNodes`
- [ ] groups should allow you to set node configuration defaults

View file

@ -1,191 +0,0 @@
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{
this,
self,
inputs,
systems,
nt,
mix,
...
} @ args: let
inherit
(builtins)
all
attrNames
elem
mapAttrs
warn
;
inherit (inputs.nixpkgs) lib;
inherit (nt) findImport;
in
mix.newMixture args (mixture: let
inherit (mixture) mapNodes;
in {
includes.private = [
./lib/nodes.nix
];
inherit findImport;
# snow.flake
flake = flakeInputs: root: let
module = lib.evalModules {
class = "snowflake";
# TODO: abort if inputs contains reserved names
specialArgs =
(flakeInputs
// {
inherit systems root;
inherit (this) snow;
inputs = flakeInputs;
})
|> (x: builtins.removeAttrs x ["self" "nodes"]);
modules = [
./module.nix
({config, ...}: {
_module.args = {
self = config;
nodes = config.nodes.nodes;
};
})
];
};
nodes = module.config.nodes;
in rec {
nixosConfigurations = mapNodes nodes (
{
base,
lib,
name,
node,
groupModules,
...
}: let
homeManager =
if node.homeManager != null
then node.homeManager
else if nodes.homeManager != null
then nodes.homeManager
else
warn ''
[snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified!
[snowflake] home-manager will NOT be used! User configuration will be ignored!
''
null;
userArgs = nodes.args // node.args;
ceruleanArgs = {
inherit systems root base nodes node;
inherit (node) system;
inherit (this) snow;
hostname = name;
_cerulean = {
inherit inputs userArgs ceruleanArgs homeManager;
specialArgs = userArgs // ceruleanArgs;
};
};
specialArgs = assert (userArgs
|> attrNames
|> all (argName:
! ceruleanArgs ? argName
|| abort ''
`specialArgs` are like super important to Cerulean my love... </3
But `args.${argName}` is a reserved argument name :(
''));
ceruleanArgs._cerulean.specialArgs;
in
lib.nixosSystem {
inherit (node) system;
inherit specialArgs;
modules =
[
self.nixosModules.default
(findImport /${root}/hosts/${name})
]
++ (groupModules root)
++ node.modules
++ nodes.modules;
}
);
deploy.nodes = mapNodes nodes ({
name,
node,
...
}: let
inherit
(node.deploy)
ssh
user
interactiveSudo
remoteBuild
rollback
autoRollback
magicRollback
activationTimeout
confirmTimeout
;
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
in {
hostname =
if ssh.host != null
then ssh.host
else "";
profilesOrder = ["default"]; # profiles priority
profiles.default = {
path = nixosFor node.system nixosConfigurations.${name};
user = user;
sudo = "sudo -u";
interactiveSudo = interactiveSudo;
fastConnection = false;
autoRollback = autoRollback -> rollback;
magicRollback = magicRollback -> rollback;
activationTimeout = activationTimeout;
confirmTimeout = confirmTimeout;
remoteBuild = remoteBuild;
sshUser = ssh.user;
sshOpts =
ssh.opts
++ (
if elem "-p" ssh.opts
then []
else ["-p" (toString ssh.port)]
)
++ (
if elem "-A" ssh.opts
then []
else ["-A"]
);
};
});
checks =
inputs.deploy-rs.lib
|> mapAttrs (system: deployLib:
deployLib.deployChecks deploy);
};
})

21
flake.lock generated
View file

@ -185,9 +185,30 @@
"microvm": "microvm",
"nixpkgs": "nixpkgs",
"nt": "nt",
"sops-nix": "sops-nix",
"systems": "systems_3"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1773096132,
"narHash": "sha256-M3zEnq9OElB7zqc+mjgPlByPm1O5t2fbUrH3t/Hm5Ag=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "d1ff3b1034d5bab5d7d8086a7803c5a5968cd784",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"spectrum": {
"flake": false,
"locked": {

View file

@ -44,7 +44,7 @@
nt,
...
} @ inputs:
import ./cerulean
import ./nix
{
inherit inputs self nt;
inherit (nt) mix;

View file

@ -21,10 +21,7 @@ mix.newMixture args (mixture: {
./snow
];
version = "0.2.5-alpha";
# WARNING: legacy
mkFlake = mixture.snow.flake;
version = "0.2.6-alpha";
overlays = [
# build deploy-rs as a package not from the flake input,

View file

@ -0,0 +1,16 @@
{
modulesPath,
config,
lib,
pkgs,
...
}: {
config = lib.mkIf (config?isoImage) {
# TODO: do i really need to import ALL of this?
imports = [(modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")];
environment.systemPackages = [
pkgs.neovim
];
};
}

195
nix/snow/default.nix Normal file
View file

@ -0,0 +1,195 @@
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{
this,
self,
inputs,
systems,
nt,
mix,
...
} @ args: let
inherit
(builtins)
all
attrNames
elem
mapAttrs
warn
;
inherit (inputs.nixpkgs) lib;
inherit (nt) findImport;
in
mix.newMixture args (mixture: let
inherit (mixture) mapNodes;
in {
includes.private = [
./lib/nodes.nix
];
inherit findImport;
# snow.flake
flake = flakeInputs: root: let
module = lib.evalModules {
class = "snowflake";
# TODO: abort if inputs contains reserved names
specialArgs =
(flakeInputs
// {
inherit systems root;
inherit (this) snow;
inputs = flakeInputs;
})
|> (x: builtins.removeAttrs x ["self" "nodes"]);
modules = [
./module.nix
({config, ...}: {
_module.args = {
self = config;
nodes = config.nodes.nodes;
};
})
];
};
inherit (module) config;
nodes = config.nodes;
in
# TODO: maybe use flake-parts or another module to all merging
config.outputs
// rec {
nixosConfigurations = mapNodes nodes (
{
base,
lib,
name,
node,
groupModules,
...
}: let
homeManager =
if node.homeManager != null
then node.homeManager
else if nodes.homeManager != null
then nodes.homeManager
else
warn ''
[snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified!
[snowflake] home-manager will NOT be used! User configuration will be ignored!
''
null;
userArgs = nodes.args // node.args;
ceruleanArgs = {
inherit systems root base nodes node;
inherit (node) system;
inherit (this) snow;
hostname = name;
_cerulean = {
inherit inputs userArgs ceruleanArgs homeManager;
specialArgs = userArgs // ceruleanArgs;
};
};
specialArgs = assert (userArgs
|> attrNames
|> all (argName:
! ceruleanArgs ? argName
|| abort ''
`specialArgs` are like super important to Cerulean my love... </3
But `args.${argName}` is a reserved argument name :(
''));
ceruleanArgs._cerulean.specialArgs;
in
lib.nixosSystem {
inherit (node) system;
inherit specialArgs;
modules =
[
self.nixosModules.default
(findImport /${root}/hosts/${name})
]
++ (groupModules root)
++ node.modules
++ nodes.modules;
}
);
deploy.nodes = mapNodes nodes ({
name,
node,
...
}: let
inherit
(node.deploy)
ssh
user
interactiveSudo
remoteBuild
rollback
autoRollback
magicRollback
activationTimeout
confirmTimeout
;
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
in {
hostname =
if ssh.host != null
then ssh.host
else "";
profilesOrder = ["default"]; # profiles priority
profiles.default = {
path = nixosFor node.system nixosConfigurations.${name};
user = user;
sudo = "sudo -u";
interactiveSudo = interactiveSudo;
fastConnection = false;
autoRollback = autoRollback -> rollback;
magicRollback = magicRollback -> rollback;
activationTimeout = activationTimeout;
confirmTimeout = confirmTimeout;
remoteBuild = remoteBuild;
sshUser = ssh.user;
sshOpts =
ssh.opts
++ (
if elem "-p" ssh.opts
then []
else ["-p" (toString ssh.port)]
)
++ (
if elem "-A" ssh.opts
then []
else ["-A"]
);
};
});
checks =
inputs.deploy-rs.lib
|> mapAttrs (system: deployLib:
deployLib.deployChecks deploy);
};
})

View file

@ -15,9 +15,14 @@
root,
snow,
...
}: {
}: let
snowFlake = snow.findImport /${root}/snow;
in {
imports = [
./modules
./nodes
(snow.findImport /${root}/snow)
snowFlake
];
outputs = snowFlake;
}

View file

@ -0,0 +1,5 @@
{...}: {
imports = [
./outputs.nix
];
}

View file

@ -0,0 +1,37 @@
{lib, ...}: let
inherit
(lib)
mkOption
types
;
in {
options = {
outputs = mkOption {
type = types.submoduleWith {
modules = [
{
freeformType =
types.lazyAttrsOf
(types.unique
{
message = ''
No option has been declared for this flake output attribute, so its definitions can't be merged automatically.
Possible solutions:
- Load a module that defines this flake output attribute
- Declare an option for this flake output attribute
- Make sure the output attribute is spelled correctly
- Define the value only once, with a single definition in a single module
'';
}
types.raw);
}
];
};
description = ''
Raw flake output attributes. Any attribute can be set here, but some
attributes are represented by options, to provide appropriate
configuration merging.
'';
};
};
}

1057
snow/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

20
snow/Cargo.toml Normal file
View file

@ -0,0 +1,20 @@
[package]
name = "snow"
description = "Cerulean CLI (Wowzers!!)"
version = "0.1.0"
authors = ["_cry64 <them@dobutterfliescry.net>"]
edition = "2024"
[dependencies]
nix-bindings-expr = { git = "https://tearforge.net/cry/nixide" }
nix-bindings-flake = { git = "https://tearforge.net/cry/nixide" }
nix-bindings-fetchers = { git = "https://tearforge.net/cry/nixide" }
nix-bindings-store = { git = "https://tearforge.net/cry/nixide" }
indoc = "2"
anyhow = "1.0.102"
clap = { version = "4.5.60", features = ["derive"] }
log = "0.4.29"
fern = { version="0.7.1", features = ["colored"] }
humantime = "2.3.0"

49
snow/flake.bak/crates.nix Normal file
View file

@ -0,0 +1,49 @@
{...}: {
perSystem = {
config,
pkgs,
...
}: {
nix-bindings-rust.nixPackage = pkgs.nix;
# declare projects
nci.projects."cerulean-project" = {
path = ./.;
# export all crates (packages and devshell) in flake outputs
# alternatively you can access the outputs and export them yourself
export = true;
depsDrvConfig = {
imports = [config.nix-bindings-rust.nciBuildConfig];
};
};
# configure crates
nci.crates."cerulean" = rec {
# profiles.release = rec {
default = true;
runTests = true;
drvConfig =
depsDrvConfig
// {
env.CARGO_TERM_VERBOSE = "true";
};
depsDrvConfig = rec {
env.LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${builtins.toString (pkgs.lib.makeLibraryPath mkDerivation.buildInputs)}";
mkDerivation = {
buildInputs = with pkgs; [
boehmgc.dev
nix.dev
];
nativeBuildInputs = with pkgs; [
pkg-config
rustPlatform.bindgenHook
];
};
};
# };
};
};
}

787
snow/flake.bak/flake.lock generated Normal file
View file

@ -0,0 +1,787 @@
{
"nodes": {
"crane": {
"flake": false,
"locked": {
"lastModified": 1758758545,
"narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=",
"owner": "ipetkov",
"repo": "crane",
"rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364",
"type": "github"
},
"original": {
"owner": "ipetkov",
"ref": "v0.21.1",
"repo": "crane",
"type": "github"
}
},
"crane_2": {
"flake": false,
"locked": {
"lastModified": 1758758545,
"narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=",
"owner": "ipetkov",
"repo": "crane",
"rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364",
"type": "github"
},
"original": {
"owner": "ipetkov",
"ref": "v0.21.1",
"repo": "crane",
"type": "github"
}
},
"dream2nix": {
"inputs": {
"nixpkgs": [
"nci",
"nixpkgs"
],
"purescript-overlay": "purescript-overlay",
"pyproject-nix": "pyproject-nix"
},
"locked": {
"lastModified": 1765953015,
"narHash": "sha256-5FBZbbWR1Csp3Y2icfRkxMJw/a/5FGg8hCXej2//bbI=",
"owner": "nix-community",
"repo": "dream2nix",
"rev": "69eb01fa0995e1e90add49d8ca5bcba213b0416f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "dream2nix",
"type": "github"
}
},
"dream2nix_2": {
"inputs": {
"nixpkgs": [
"nix-bindings-rust",
"nix-cargo-integration",
"nixpkgs"
],
"purescript-overlay": "purescript-overlay_2",
"pyproject-nix": "pyproject-nix_2"
},
"locked": {
"lastModified": 1765953015,
"narHash": "sha256-5FBZbbWR1Csp3Y2icfRkxMJw/a/5FGg8hCXej2//bbI=",
"owner": "nix-community",
"repo": "dream2nix",
"rev": "69eb01fa0995e1e90add49d8ca5bcba213b0416f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "dream2nix",
"type": "github"
}
},
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1772953398,
"narHash": "sha256-fTTHCaEvPLzWyZFxPud/G9HM3pNYmW/64Kj58hdH4+k=",
"owner": "nix-community",
"repo": "fenix",
"rev": "fc4863887d98fd879cf5f11af1d23d44d9bdd8ae",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_3": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nix-bindings-rust",
"nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"git-hooks-nix": {
"inputs": {
"flake-compat": [
"nix-bindings-rust",
"nix"
],
"gitignore": [
"nix-bindings-rust",
"nix"
],
"nixpkgs": [
"nix-bindings-rust",
"nix",
"nixpkgs"
],
"nixpkgs-stable": [
"nix-bindings-rust",
"nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1734279981,
"narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"mk-naked-shell": {
"flake": false,
"locked": {
"lastModified": 1681286841,
"narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=",
"owner": "90-008",
"repo": "mk-naked-shell",
"rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd",
"type": "github"
},
"original": {
"owner": "90-008",
"repo": "mk-naked-shell",
"type": "github"
}
},
"mk-naked-shell_2": {
"flake": false,
"locked": {
"lastModified": 1681286841,
"narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=",
"owner": "90-008",
"repo": "mk-naked-shell",
"rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd",
"type": "github"
},
"original": {
"owner": "90-008",
"repo": "mk-naked-shell",
"type": "github"
}
},
"nci": {
"inputs": {
"crane": "crane",
"dream2nix": "dream2nix",
"mk-naked-shell": "mk-naked-shell",
"nixpkgs": [
"nixpkgs"
],
"parts": "parts",
"rust-overlay": "rust-overlay",
"treefmt": "treefmt"
},
"locked": {
"lastModified": 1772951573,
"narHash": "sha256-ALlAShJadjr4NpaqrJeXX8nrpqJGk571/1JVsSQ0OMI=",
"owner": "90-008",
"repo": "nix-cargo-integration",
"rev": "a7a34450d5a99c6bffa48497528ed9bf809085d6",
"type": "github"
},
"original": {
"owner": "90-008",
"repo": "nix-cargo-integration",
"type": "github"
}
},
"nix": {
"inputs": {
"flake-compat": "flake-compat_2",
"flake-parts": "flake-parts_2",
"git-hooks-nix": "git-hooks-nix",
"nixpkgs": [
"nix-bindings-rust",
"nixpkgs"
],
"nixpkgs-23-11": "nixpkgs-23-11",
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1772224943,
"narHash": "sha256-jJIlRLPPVYu860MVFx4gsRx3sskmLDSRWXXue5tYncw=",
"owner": "NixOS",
"repo": "nix",
"rev": "0acd0566e85e4597269482824711bcde7b518600",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nix",
"type": "github"
}
},
"nix-bindings-rust": {
"inputs": {
"flake-parts": "flake-parts",
"nix": "nix",
"nix-cargo-integration": "nix-cargo-integration",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1772492331,
"narHash": "sha256-UrYoUqNVwXLtAB5Q/KIkm0xPLA0DeK+9YbB4HTES558=",
"owner": "nixops4",
"repo": "nix-bindings-rust",
"rev": "7de15fa26057c8cf0b6178ff166e529c09ea89a7",
"type": "github"
},
"original": {
"owner": "nixops4",
"repo": "nix-bindings-rust",
"type": "github"
}
},
"nix-cargo-integration": {
"inputs": {
"crane": "crane_2",
"dream2nix": "dream2nix_2",
"mk-naked-shell": "mk-naked-shell_2",
"nixpkgs": [
"nix-bindings-rust",
"nixpkgs"
],
"parts": "parts_2",
"rust-overlay": "rust-overlay_2",
"treefmt": "treefmt_2"
},
"locked": {
"lastModified": 1772260057,
"narHash": "sha256-NaUqM0i6XIGdgRNxxQ9sfgCAVeE2Ko9rz7e19RsNUKw=",
"owner": "90-008",
"repo": "nix-cargo-integration",
"rev": "c783c5dff02c06f2af6226d4dd4d494542d0a4d2",
"type": "github"
},
"original": {
"owner": "90-008",
"repo": "nix-cargo-integration",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1772198003,
"narHash": "sha256-I45esRSssFtJ8p/gLHUZ1OUaaTaVLluNkABkk6arQwE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dd9b079222d43e1943b6ebd802f04fd959dc8e61",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-23-11": {
"locked": {
"lastModified": 1717159533,
"narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1769909678,
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "72716169fe93074c333e8d0173151350670b824c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-lib_2": {
"locked": {
"lastModified": 1772328832,
"narHash": "sha256-e+/T/pmEkLP6BHhYjx6GmwP5ivonQQn0bJdH9YrRB+Q=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "c185c7a5e5dd8f9add5b2f8ebeff00888b070742",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-regression": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1772773019,
"narHash": "sha256-E1bxHxNKfDoQUuvriG71+f+s/NT0qWkImXsYZNFFfCs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "aca4d95fce4914b3892661bcb80b8087293536c6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"parts": {
"inputs": {
"nixpkgs-lib": [
"nci",
"nixpkgs"
]
},
"locked": {
"lastModified": 1772408722,
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"parts_2": {
"inputs": {
"nixpkgs-lib": [
"nix-bindings-rust",
"nix-cargo-integration",
"nixpkgs"
]
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"parts_3": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": {
"lastModified": 1772408722,
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"purescript-overlay": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"nci",
"dream2nix",
"nixpkgs"
],
"slimlock": "slimlock"
},
"locked": {
"lastModified": 1728546539,
"narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=",
"owner": "thomashoneyman",
"repo": "purescript-overlay",
"rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4",
"type": "github"
},
"original": {
"owner": "thomashoneyman",
"repo": "purescript-overlay",
"type": "github"
}
},
"purescript-overlay_2": {
"inputs": {
"flake-compat": "flake-compat_3",
"nixpkgs": [
"nix-bindings-rust",
"nix-cargo-integration",
"dream2nix",
"nixpkgs"
],
"slimlock": "slimlock_2"
},
"locked": {
"lastModified": 1728546539,
"narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=",
"owner": "thomashoneyman",
"repo": "purescript-overlay",
"rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4",
"type": "github"
},
"original": {
"owner": "thomashoneyman",
"repo": "purescript-overlay",
"type": "github"
}
},
"pyproject-nix": {
"inputs": {
"nixpkgs": [
"nci",
"dream2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1763017646,
"narHash": "sha256-Z+R2lveIp6Skn1VPH3taQIuMhABg1IizJd8oVdmdHsQ=",
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"rev": "47bd6f296502842643078d66128f7b5e5370790c",
"type": "github"
},
"original": {
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"type": "github"
}
},
"pyproject-nix_2": {
"inputs": {
"nixpkgs": [
"nix-bindings-rust",
"nix-cargo-integration",
"dream2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1763017646,
"narHash": "sha256-Z+R2lveIp6Skn1VPH3taQIuMhABg1IizJd8oVdmdHsQ=",
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"rev": "47bd6f296502842643078d66128f7b5e5370790c",
"type": "github"
},
"original": {
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"type": "github"
}
},
"root": {
"inputs": {
"fenix": "fenix",
"nci": "nci",
"nix-bindings-rust": "nix-bindings-rust",
"nixpkgs": "nixpkgs_2",
"parts": "parts_3",
"systems": "systems"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1772877513,
"narHash": "sha256-RcRGv2Bng5I9y75XwFX7oK2l6mLH1dtbTTG9U8qun0c=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "a1b86d600f88be98643e5dd61d6ed26eda17c09e",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nci",
"nixpkgs"
]
},
"locked": {
"lastModified": 1772939270,
"narHash": "sha256-HbxD5DJAKxzo0G8on5wdY+OZNiUWt3FTvGmXmVEmg7g=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "bb93f191a07c0165992ed6d0b4197ee5c7e6e641",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"rust-overlay_2": {
"inputs": {
"nixpkgs": [
"nix-bindings-rust",
"nix-cargo-integration",
"nixpkgs"
]
},
"locked": {
"lastModified": 1772247314,
"narHash": "sha256-x6IFQ9bL7YYfW2m2z8D3Em2YtAA3HE8kiCFwai2fwrw=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "a1ab5e89ab12e1a37c0b264af6386a7472d68a15",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"slimlock": {
"inputs": {
"nixpkgs": [
"nci",
"dream2nix",
"purescript-overlay",
"nixpkgs"
]
},
"locked": {
"lastModified": 1688756706,
"narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=",
"owner": "thomashoneyman",
"repo": "slimlock",
"rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c",
"type": "github"
},
"original": {
"owner": "thomashoneyman",
"repo": "slimlock",
"type": "github"
}
},
"slimlock_2": {
"inputs": {
"nixpkgs": [
"nix-bindings-rust",
"nix-cargo-integration",
"dream2nix",
"purescript-overlay",
"nixpkgs"
]
},
"locked": {
"lastModified": 1688756706,
"narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=",
"owner": "thomashoneyman",
"repo": "slimlock",
"rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c",
"type": "github"
},
"original": {
"owner": "thomashoneyman",
"repo": "slimlock",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
},
"treefmt": {
"inputs": {
"nixpkgs": [
"nci",
"nixpkgs"
]
},
"locked": {
"lastModified": 1772660329,
"narHash": "sha256-IjU1FxYqm+VDe5qIOxoW+pISBlGvVApRjiw/Y/ttJzY=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "3710e0e1218041bbad640352a0440114b1e10428",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt_2": {
"inputs": {
"nixpkgs": [
"nix-bindings-rust",
"nix-cargo-integration",
"nixpkgs"
]
},
"locked": {
"lastModified": 1770228511,
"narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "337a4fe074be1042a35086f15481d763b8ddc0e7",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

61
snow/flake.bak/flake.nix Normal file
View file

@ -0,0 +1,61 @@
{
description = "Cerulean CLI";
inputs = {
systems.url = "github:nix-systems/default-linux";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs.follows = "nixpkgs";
};
nci = {
url = "github:90-008/nix-cargo-integration";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-bindings-rust.url = "github:nixops4/nix-bindings-rust";
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs @ {
parts,
nci,
nix-bindings-rust,
...
}:
parts.lib.mkFlake {inherit inputs;} {
imports = [
parts.flakeModules.easyOverlay
nci.flakeModule
nix-bindings-rust.modules.flake.default
./crates.nix
];
systems = import inputs.systems;
perSystem = {
config,
pkgs,
...
}: let
outputs = config.nci.outputs;
in {
overlayAttrs = {
cerulean = outputs."cerulean".packages.default;
};
# nix-bindings-rust.nixPackage = pkgs.nix;
devShells.default = outputs."cerulean-project".devShell;
packages = rec {
inherit (pkgs) cerulean;
default = cerulean;
};
};
};
}

82
snow/flake.lock generated Normal file
View file

@ -0,0 +1,82 @@
{
"nodes": {
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1772953398,
"narHash": "sha256-fTTHCaEvPLzWyZFxPud/G9HM3pNYmW/64Kj58hdH4+k=",
"owner": "nix-community",
"repo": "fenix",
"rev": "fc4863887d98fd879cf5f11af1d23d44d9bdd8ae",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1772822230,
"narHash": "sha256-yf3iYLGbGVlIthlQIk5/4/EQDZNNEmuqKZkQssMljuw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "71caefce12ba78d84fe618cf61644dce01cf3a96",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"fenix": "fenix",
"nixpkgs": "nixpkgs",
"systems": "systems"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1772877513,
"narHash": "sha256-RcRGv2Bng5I9y75XwFX7oK2l6mLH1dtbTTG9U8qun0c=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "a1b86d600f88be98643e5dd61d6ed26eda17c09e",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

99
snow/flake.nix Normal file
View file

@ -0,0 +1,99 @@
{
description = "Cerulean CLI";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
systems.url = "github:nix-systems/default";
fenix.url = "github:nix-community/fenix";
fenix.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = {
self,
nixpkgs,
...
} @ inputs: let
systems = import inputs.systems;
mkPkgs = system: repo:
import repo {
inherit system;
allowUnfree = false;
allowBroken = false;
overlays = builtins.attrValues self.overlays or {};
};
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system (mkPkgs system nixpkgs));
in {
overlays.default = final: prev: {
libclang = prev.llvmPackages_21.libclang;
# ttywire = pkgs.rustPlatform.buildRustPackage {
# pname = "cerulean";
# version = "0.1.0";
# src = ./.;
#
# cargoHash = "sha256-NxFdFCuB456uBeVeqT2bsRtBrIoLdijBaga7VB9KPF8=";
#
# # runtime dependencies (propagated out of derivation)
# buildInputs = with pkgs; [
# boehmgc.dev
# nix.dev
# ];
#
# # build-time/shellHook dependencies (not propagates)
# nativeBuildInputs = with pkgs; [
# pkg-config
# ];
#
# meta = with lib; {
# description = "Cerulean CLI";
# homepage = "https://github.com/cry128/cerulean";
# license = lib.licenses.asl20;
# maintainers = with maintainers; [
# cry64
# ];
# };
# };
};
checks = self.packages or {};
# packages = forAllSystems (
# system: pkgs: rec {
# inherit (pkgs) ttywire;
# default = ttywire;
# }
# );
devShells = forAllSystems (
system: pkgs: {
default = pkgs.mkShell rec {
shell = "${pkgs.bash}/bin/bash";
strictDeps = true;
packages = with pkgs; [
cargo
rustc
inputs.fenix.packages.${system}.complete.rustfmt
];
# packages we should be able to link against
buildInputs = with pkgs; [
boehmgc.dev
nix.dev
];
# packages we run at build time / shellHook
nativeBuildInputs = with pkgs; [
pkg-config
rustPlatform.bindgenHook
];
LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${builtins.toString (pkgs.lib.makeLibraryPath buildInputs)}";
};
}
);
};
}

28
snow/src/main.rs Normal file
View file

@ -0,0 +1,28 @@
mod nix;
use nix_bindings_expr::eval_state::{gc_register_my_thread, init, EvalState};
use nix_bindings_store::store::Store;
use std::collections::HashMap;
fn main() -> anyhow::Result<()> {
// Initialize Nix library and register thread with GC
init()?;
let guard = gc_register_my_thread()?;
// Open a store connection and create an evaluation state
let store = Store::open(None, HashMap::new())?;
let mut eval_state = EvalState::new(store, [])?;
// Evaluate a Nix expression
let value = eval_state.eval_from_string("[1 2 3]", "<example>")?;
// Extract typed values
let elements: Vec<_> = eval_state.require_list_strict(&value)?;
for element in elements {
let num = eval_state.require_int(&element)?;
println!("Element: {}", num);
}
drop(guard);
Ok(())
}

114
snow/src/nix/flake.rs Normal file
View file

@ -0,0 +1,114 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use anyhow::Result;
use nix_bindings_expr::{eval_state::EvalState, value::Value};
use nix_bindings_fetchers::FetchersSettings;
use nix_bindings_flake::{FlakeLockFlags, FlakeSettings, LockedFlake};
use nix_bindings_store::store::Store;
use crate::nix::FlakeRef;
#[derive(Debug, Clone)]
pub enum FlakeLockMode {
/// Configures [LockedFlake::lock] to make incremental changes to the lock file as needed. Changes are written to file.
WriteAsNeeded,
/// Like [FlakeLockMode::WriteAsNeeded], but does not write to the lock file.
Virtual,
/// Make [LockedFlake::lock] check if the lock file is up to date. If not, an error is returned.
Check,
}
pub struct FlakeBuilder {
flake_ref: Rc<RefCell<FlakeRef>>,
lock_mode: FlakeLockMode,
lock_flags: FlakeLockFlags,
eval_state: Option<EvalState>,
}
pub struct Flake {
flake_ref: Rc<RefCell<FlakeRef>>,
locked_flake: LockedFlake,
lock_mode: FlakeLockMode,
eval_state: EvalState,
}
impl FlakeBuilder {
pub fn new(flake_ref: Rc<RefCell<FlakeRef>>, lock_mode: FlakeLockMode) -> Result<Self> {
let mut lock_flags = FlakeLockFlags::new(&flake_ref.as_ref().borrow().flake_settings)?;
match lock_mode {
FlakeLockMode::WriteAsNeeded => lock_flags.set_mode_write_as_needed(),
FlakeLockMode::Virtual => lock_flags.set_mode_virtual(),
FlakeLockMode::Check => lock_flags.set_mode_check(),
}?;
Ok(FlakeBuilder {
flake_ref: flake_ref,
lock_mode,
lock_flags,
eval_state: None,
})
}
/// Adds an input override to the lock file that will be produced.
/// The [LockedFlake::lock] operation will not write to the lock file.
///
/// # Arguments
///
/// * `path` - The input name/path to override (must not be empty)
/// * `flake_ref` - The flake reference to use as the override
pub fn override_input(mut self, path: &str, flake_ref: &FlakeRef) -> Result<Self> {
assert!(
!path.is_empty(),
"The input path for `FlakeBuilder::override_input` cannot be an empty string slice!"
);
self.lock_flags.add_input_override(path, &flake_ref.ref_)?;
Ok(self)
}
pub fn build(&mut self) -> Result<Flake> {
let eval_state = match self.eval_state.take() {
Some(state) => state,
None => {
let store = Store::open(None, HashMap::new())?;
EvalState::new(store, [])?
}
};
let locked_flake = LockedFlake::lock(
&FetchersSettings::new()?,
&FlakeSettings::new()?,
&eval_state,
&self.lock_flags,
&self.flake_ref.as_ref().borrow().ref_,
)?;
Ok(Flake {
flake_ref: Rc::clone(&self.flake_ref),
locked_flake,
lock_mode: self.lock_mode.clone(),
eval_state,
})
}
}
impl Flake {
pub fn new(flake_ref: Rc<RefCell<FlakeRef>>, lock_mode: FlakeLockMode) -> Result<Self> {
let mut builder = FlakeBuilder::new(flake_ref, lock_mode)?;
builder.build()
}
pub fn outputs(&mut self) -> Result<Value> {
self.locked_flake.outputs(
&self.flake_ref.as_ref().borrow().flake_settings,
&mut self.eval_state,
)
}
}

79
snow/src/nix/flakeref.rs Normal file
View file

@ -0,0 +1,79 @@
use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use indoc::indoc;
use nix_bindings_fetchers::FetchersSettings;
use nix_bindings_flake::{FlakeReference, FlakeReferenceParseFlags, FlakeSettings};
pub struct FlakeRef {
pub(super) ref_: FlakeReference,
pub path: PathBuf,
pub flake_settings: FlakeSettings,
pub fetch_settings: FetchersSettings,
}
impl FlakeRef {
/// Parse a flake reference from a string.
/// The string must be a valid flake reference, such as `github:owner/repo`.
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
/// in which case, the returned `flake_ref.path` will contain the fragment.
pub fn new<P: AsRef<Path>>(reference: &str, base_directory: Option<P>) -> Result<FlakeRef> {
let flake_settings = FlakeSettings::new()?;
let fetch_settings = FetchersSettings::new()?;
let mut flags = FlakeReferenceParseFlags::new(&flake_settings)?;
if let Some(base_directory) = base_directory {
flags.set_base_directory(
base_directory
.as_ref()
.to_str()
.context("The given flake reference path is not provided as valid unicode")?,
)?;
} else {
// TODO: try see if libnix uses the cwd as a fallback (aka is this assert pointless?)
assert!(
reference.starts_with("."),
indoc! {"
Attempted to construct FlakeRef from relative path without declaring `base_directory`!
Call to `FlakeRef::absolute(&str)` should actually be `FlakeRef::relative(&str, dyn AsRef<Path>)`.
"}
);
}
FlakeReference::parse_with_fragment(&fetch_settings, &flake_settings, &flags, reference)
.map(|(reference, path)| FlakeRef {
ref_: reference,
path: PathBuf::from(path),
flake_settings,
fetch_settings,
})
}
/// >[!WARNING]
/// > Do not use [FlakeRef::absolute(&str)](FlakeRef::absolute) to construct a [FlakeRef] from a relative path!
/// > Use [FlakeRef::relative(&str, dyn AsRef<Path>)](FlakeRef::relative) instead to declare the `base_directory`.
///
/// Parse a flake reference from a string.
/// The string must be a valid flake reference, such as `github:owner/repo`.
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
/// in which case, the returned `flake_ref.path` will contain the fragment.
pub fn absolute(reference: &str) -> Result<FlakeRef> {
FlakeRef::new(reference, None::<&Path>)
}
/// Parse a flake reference from a string.
/// The string must be a valid flake reference, such as `github:owner/repo`.
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
/// in which case, the returned `flake_ref.path` will contain the fragment.
pub fn relative<P: AsRef<Path>>(reference: &str, base_directory: P) -> Result<FlakeRef> {
FlakeRef::new(reference, Some(base_directory))
}
}
impl Into<FlakeReference> for FlakeRef {
fn into(self) -> FlakeReference {
self.ref_
}
}

9
snow/src/nix/mod.rs Normal file
View file

@ -0,0 +1,9 @@
mod flake;
mod flakeref;
mod nix;
mod primop;
pub use flake::{Flake, FlakeBuilder, FlakeLockMode};
pub use flakeref::FlakeRef;
pub use nix::Nix;
pub use primop::PrimOp;

10
snow/src/nix/nix.rs Normal file
View file

@ -0,0 +1,10 @@
use std::path::Path;
use anyhow::{Context, Result};
use derive_more::From;
use nix_bindings_fetchers::FetchersSettings;
use nix_bindings_flake::{FlakeReference, FlakeReferenceParseFlags, FlakeSettings};
pub struct Nix {}
impl Nix {}

40
snow/src/nix/primop.rs Normal file
View file

@ -0,0 +1,40 @@
use std::ffi::{CStr, CString, NulError};
use anyhow::Result;
use nix_bindings_expr::{eval_state::EvalState, primop::PrimOpMeta, value::Value};
pub struct PrimOp<'a, const N: usize> {
// pub name: &'a CStr,
// pub doc: &'a CStr,
// pub args: [&'a CStr; N],
meta: PrimOpMeta<'a, N>,
// f: Box<dyn Fn(&mut EvalState, &[Value; N]) -> Result<Value>>,
}
impl<'a, const N: usize> PrimOp<'a, N> {
pub fn new<S>(name: S, doc: S, args: [&'a CStr; N]) -> Result<Self>
where
S: AsRef<str>,
{
let name = CString::new(name.as_ref())?.as_ref();
let doc = CString::new(doc.as_ref())?.as_ref();
// let args = args
// .iter()
// .map(|x| CString::new(x.as_ref()).as_ref())
// .collect::<Result<Vec<&CString>, &NulError>>()?
// .iter()
// .map(|x| x.as_ref())
// .collect::<Vec<&CStr>>()
// .as_slice();
Ok(PrimOp {
// name,
// doc,
// args,
meta: PrimOpMeta { name, doc, args },
})
// Ok(PrimOp {
// meta: PrimOpMeta { name, doc, args },
// })
}
}