Merge pull request 'cli: don't depend on the entire clan-core' (#3424) from push-pzytrksvysmu into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3424
This commit is contained in:
Michael Hoang
2025-04-28 03:30:01 +00:00
6 changed files with 70 additions and 80 deletions

View File

@@ -47,18 +47,27 @@ def find_toplevel(top_level_files: list[str]) -> Path | None:
class TemplateType(Enum): class TemplateType(Enum):
CLAN = "clan" CLAN = "clan"
DISK = "disk" DISK = "disk"
MACHINE = "machine"
def clan_templates(template_type: TemplateType) -> Path: def clan_templates(template_type: TemplateType | None = None) -> Path:
template_path = ( template_path = module_root().parent.parent.parent / "templates"
module_root().parent.parent.parent / "templates" / template_type.value
) if template_type is not None:
template_path /= template_type.value
if template_path.exists(): if template_path.exists():
return template_path return template_path
template_path = module_root() / "templates" / template_type.value
template_path = module_root() / "templates"
if template_type is not None:
template_path /= template_type.value
if not template_path.exists(): if not template_path.exists():
msg = f"BUG! clan core not found at {template_path}. This is an issue with packaging the cli" msg = f"BUG! clan core not found at {template_path}. This is an issue with packaging the cli"
raise ClanError(msg) raise ClanError(msg)
return template_path return template_path

View File

@@ -8,7 +8,7 @@ from tempfile import NamedTemporaryFile
from typing import Any from typing import Any
from clan_cli.cmd import Log, RunOpts, run from clan_cli.cmd import Log, RunOpts, run
from clan_cli.dirs import select_source, user_cache_dir from clan_cli.dirs import nixpkgs_source, select_source, user_cache_dir
from clan_cli.errors import ClanError from clan_cli.errors import ClanError
from clan_cli.nix import ( from clan_cli.nix import (
nix_build, nix_build,
@@ -701,6 +701,18 @@ class Flake:
config = nix_config() config = nix_config()
# these hashes should be filled in by `nix build`
# if we run this Python code directly then we use a fallback
# method to getting the NAR hash
fallback_nixpkgs_hash = "@fallback_nixpkgs_hash@"
if not fallback_nixpkgs_hash.startswith("sha256-"):
fallback_nixpkgs = Flake(str(nixpkgs_source()))
fallback_nixpkgs.invalidate_cache()
assert fallback_nixpkgs.hash is not None, (
"this should be impossible as invalidate_cache() should always set `hash`"
)
fallback_nixpkgs_hash = fallback_nixpkgs.hash
select_hash = "@select_hash@" select_hash = "@select_hash@"
if not select_hash.startswith("sha256-"): if not select_hash.startswith("sha256-"):
select_flake = Flake(str(select_source())) select_flake = Flake(str(select_source()))
@@ -714,8 +726,9 @@ class Flake:
let let
flake = builtins.getFlake "path:{self.store_path}?narHash={self.hash}"; flake = builtins.getFlake "path:{self.store_path}?narHash={self.hash}";
selectLib = (builtins.getFlake "{select_source()}?narHash={select_hash}").lib; selectLib = (builtins.getFlake "{select_source()}?narHash={select_hash}").lib;
nixpkgs = flake.inputs.nixpkgs or (builtins.getFlake "{nixpkgs_source()}?narHash={fallback_nixpkgs_hash}");
in in
flake.inputs.nixpkgs.legacyPackages.{config["system"]}.writeText "clan-flake-select" ( nixpkgs.legacyPackages.{config["system"]}.writeText "clan-flake-select" (
builtins.toJSON [ {" ".join([f"(selectLib.applySelectors (builtins.fromJSON ''{attr}'') flake)" for attr in str_selectors])} ] builtins.toJSON [ {" ".join([f"(selectLib.applySelectors (builtins.fromJSON ''{attr}'') flake)" for attr in str_selectors])} ]
) )
""" """

View File

@@ -1,10 +1,10 @@
import logging import logging
import os
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import Any, Literal, NewType, TypedDict, cast from typing import Any, Literal, NewType, TypedDict, cast
from clan_cli.cmd import run from clan_cli.cmd import run
from clan_cli.dirs import clan_templates
from clan_cli.errors import ClanCmdError, ClanError from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.flake import Flake from clan_cli.flake import Flake
@@ -83,13 +83,8 @@ def get_clan_nix_attrset(clan_dir: Flake | None = None) -> ClanExports:
Get the clan nix attrset from a flake, with fallback structure applied. Get the clan nix attrset from a flake, with fallback structure applied.
Path inside the attrsets have NOT YET been realized in the nix store. Path inside the attrsets have NOT YET been realized in the nix store.
""" """
# Check if the clan directory is provided, otherwise use the environment variable
if not clan_dir: if not clan_dir:
clan_core_path = os.environ.get("CLAN_CORE_PATH") clan_dir = Flake(str(clan_templates()))
if not clan_core_path:
msg = "Environment var CLAN_CORE_PATH is not set, this shouldn't happen"
raise ClanError(msg)
clan_dir = Flake(clan_core_path)
log.debug(f"Evaluating flake {clan_dir} for Clan attrsets") log.debug(f"Evaluating flake {clan_dir} for Clan attrsets")
@@ -231,11 +226,7 @@ def get_template(
""" """
if not clan_dir: if not clan_dir:
clan_core_path = os.environ.get("CLAN_CORE_PATH") clan_dir = Flake(str(clan_templates()))
if not clan_core_path:
msg = "Environment var CLAN_CORE_PATH is not set, this shouldn't happen"
raise ClanError(msg)
clan_dir = Flake(clan_core_path)
log.info(f"Get template in {clan_dir}") log.info(f"Get template in {clan_dir}")

View File

@@ -66,6 +66,7 @@ let
rm -f $out/clan_cli/nixpkgs rm -f $out/clan_cli/nixpkgs
substituteInPlace $out/clan_cli/flake.py \ substituteInPlace $out/clan_cli/flake.py \
--replace-fail '@fallback_nixpkgs_hash@' "$(jq -r '.nodes.nixpkgs.locked.narHash' ${nixpkgs'}/flake.lock)" \
--replace-fail '@select_hash@' "$(jq -r '.nodes."nix-select".locked.narHash' ${../../flake.lock})" --replace-fail '@select_hash@' "$(jq -r '.nodes."nix-select".locked.narHash' ${../../flake.lock})"
ln -sf ${nixpkgs'} $out/clan_cli/nixpkgs ln -sf ${nixpkgs'} $out/clan_cli/nixpkgs
ln -sf ${nix-select} $out/clan_cli/select ln -sf ${nix-select} $out/clan_cli/select
@@ -114,11 +115,6 @@ pythonRuntime.pkgs.buildPythonApplication {
":" ":"
(lib.makeBinPath (lib.attrValues bundledRuntimeDependenciesMap)) (lib.makeBinPath (lib.attrValues bundledRuntimeDependenciesMap))
# We need this for templates to work
"--set"
"CLAN_CORE_PATH"
clan-core-path
"--set" "--set"
"CLAN_PROVIDED_PACKAGES" "CLAN_PROVIDED_PACKAGES"
(lib.concatStringsSep ":" (lib.attrNames bundledRuntimeDependenciesMap)) (lib.concatStringsSep ":" (lib.attrNames bundledRuntimeDependenciesMap))

View File

@@ -1,43 +1,7 @@
{ self, inputs, ... }: { self, inputs, ... }:
{ {
clan.templates = { clan = {
disko = { inherit (((import ./flake.nix).outputs { }).clan) templates;
single-disk = {
description = "A simple ext4 disk with a single partition";
path = ./disk/single-disk;
};
};
machine = {
flash-installer = {
description = "Initialize a new flash-installer machine";
path = ./machine/flash-installer;
};
new-machine = {
description = "Initialize a new machine";
path = ./machine/new-machine;
};
};
clan = {
default = {
description = "Initialize a new clan flake";
path = ./clan/new-clan;
};
minimal = {
description = "for clans managed via (G)UI";
path = ./clan/minimal;
};
flake-parts = {
description = "Flake-parts";
path = ./clan/flake-parts;
};
minimal-flake-parts = {
description = "Minimal flake-parts clan template";
path = ./clan/minimal-flake-parts;
};
};
}; };
flake = { flake = {

View File

@@ -2,26 +2,43 @@
outputs = outputs =
{ ... }: { ... }:
{ {
templates = { clan.templates = {
default = { disko = {
description = "Initialize a new clan flake"; single-disk = {
path = ./clan/new-clan; description = "A simple ext4 disk with a single partition";
path = ./disk/single-disk;
};
}; };
minimal = {
description = "for clans managed via (G)UI"; machine = {
path = ./clan/minimal; flash-installer = {
description = "Initialize a new flash-installer machine";
path = ./machine/flash-installer;
};
new-machine = {
description = "Initialize a new machine";
path = ./machine/new-machine;
};
}; };
flake-parts = {
description = "Flake-parts"; clan = {
path = ./clan/flake-parts; default = {
}; description = "Initialize a new clan flake";
minimal-flake-parts = { path = ./clan/new-clan;
description = "Minimal flake-parts clan template"; };
path = ./clan/minimal-flake-parts; minimal = {
}; description = "for clans managed via (G)UI";
machineTemplates = { path = ./clan/minimal;
description = "Machine templates"; };
path = ./machine; flake-parts = {
description = "Flake-parts";
path = ./clan/flake-parts;
};
minimal-flake-parts = {
description = "Minimal flake-parts clan template";
path = ./clan/minimal-flake-parts;
};
}; };
}; };
}; };