diff --git a/crates/omnix-cli/src/command/init.rs b/crates/omnix-cli/src/command/init.rs index 46eb8e9a..e6423535 100644 --- a/crates/omnix-cli/src/command/init.rs +++ b/crates/omnix-cli/src/command/init.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, path::PathBuf, str::FromStr}; use clap::Parser; +use nix_rs::flake::url::FlakeUrl; use serde_json::Value; /// Initialize a new flake project @@ -10,12 +11,10 @@ pub struct InitCommand { #[arg(short = 'o', long = "output")] path: PathBuf, - /// The name of the template to use + /// The flake from which to initialize the template to use /// - /// If not passed, the user will presented with a list of templates to choose from. - /// - /// In future, this will support arbitrary URLs. For now, we only support builtin templates. - template: Option, + /// Defaults to builtin registry of flake templates. + flake: Option, /// Parameter values to use for the template by default. #[arg(long = "params")] @@ -30,7 +29,7 @@ impl InitCommand { pub async fn run(&self) -> anyhow::Result<()> { omnix_init::core::initialize_template( &self.path, - self.template.clone(), + self.flake.clone(), &self.params.clone().unwrap_or_default().0, self.non_interactive, ) diff --git a/crates/omnix-cli/tests/command/init.rs b/crates/omnix-cli/tests/command/init.rs index 2ab211ab..8b7135c7 100644 --- a/crates/omnix-cli/tests/command/init.rs +++ b/crates/omnix-cli/tests/command/init.rs @@ -3,6 +3,7 @@ use std::path::Path; use crate::command::core::om; use assert_cmd::Command; use nix_rs::{command::NixCmd, flake::url::FlakeUrl}; +use omnix_init::config::BUILTIN_REGISTRY; use predicates::str::contains; /// `om init` runs and successfully initializes a template @@ -17,7 +18,7 @@ async fn om_init() -> anyhow::Result<()> { fn om_init_tests() -> Vec { vec![ OmInitTest { - template_name: "haskell-template", + template_name: BUILTIN_REGISTRY.with_attr("haskell-template"), default_params: r#"{"package-name": "foo", "author": "John", "vscode": false }"#, asserts: Asserts { out_dir: PathAsserts { @@ -29,7 +30,7 @@ fn om_init_tests() -> Vec { }, }, OmInitTest { - template_name: "rust-nix-template", + template_name: BUILTIN_REGISTRY.with_attr("rust-nix-template"), default_params: r#"{"package-name": "qux", "author": "John", "author-email": "john@example.com" }"#, asserts: Asserts { out_dir: PathAsserts { @@ -46,7 +47,7 @@ fn om_init_tests() -> Vec { }, }, OmInitTest { - template_name: "nix-dev-home", + template_name: BUILTIN_REGISTRY.with_attr("nix-dev-home"), default_params: r#"{"username": "john", "git-email": "jon@ex.com", "git-name": "John", "neovim": true }"#, asserts: Asserts { out_dir: PathAsserts { @@ -66,7 +67,7 @@ fn om_init_tests() -> Vec { /// A test for a single template struct OmInitTest { /// The template name to pass to `om init` - template_name: &'static str, + template_name: FlakeUrl, /// The --default-params to pass to `om init` default_params: &'static str, /// Various assertions to make after running `om init` @@ -82,7 +83,7 @@ impl OmInitTest { "init", "-o", &temp_dir.to_string_lossy(), - self.template_name, + &self.template_name, "--non-interactive", "--params", self.default_params, diff --git a/crates/omnix-init/registry/flake.lock b/crates/omnix-init/registry/flake.lock index 29f8e9b4..664b70cf 100644 --- a/crates/omnix-init/registry/flake.lock +++ b/crates/omnix-init/registry/flake.lock @@ -93,11 +93,11 @@ "devour-flake": { "flake": false, "locked": { - "lastModified": 1709858306, - "narHash": "sha256-Vey9n9hIlWiSAZ6CCTpkrL6jt4r2JvT2ik9wa2bjeC0=", + "lastModified": 1726283167, + "narHash": "sha256-Cvc84VzvvdmehafnaIPfdPylNWJcDmv79QQh/MH/4Qk=", "owner": "srid", "repo": "devour-flake", - "rev": "17b711b9deadbbc5629cb7d2b64cf86ae72af3fa", + "rev": "9b96d31a55be119df8496ec5b7369823deec8a1c", "type": "github" }, "original": { @@ -202,11 +202,11 @@ "nixpkgs-lib": "nixpkgs-lib_2" }, "locked": { - "lastModified": 1725234343, - "narHash": "sha256-+ebgonl3NbiKD2UD0x4BszCZQ6sTfL4xioaM49o5B3Y=", + "lastModified": 1726153070, + "narHash": "sha256-HO4zgY0ekfwO5bX0QH/3kJ/h4KvUDFZg8YpkNwIbg1U=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "567b938d64d4b4112ee253b9274472dc3a346eb6", + "rev": "bcef6817a8b2aa20a5a6dbb19b43e63c5bf8619a", "type": "github" }, "original": { @@ -224,11 +224,11 @@ ] }, "locked": { - "lastModified": 1722555600, - "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=", + "lastModified": 1726153070, + "narHash": "sha256-HO4zgY0ekfwO5bX0QH/3kJ/h4KvUDFZg8YpkNwIbg1U=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "8471fe90ad337a8074e957b69ca4d0089218391d", + "rev": "bcef6817a8b2aa20a5a6dbb19b43e63c5bf8619a", "type": "github" }, "original": { @@ -363,11 +363,11 @@ ] }, "locked": { - "lastModified": 1724857454, - "narHash": "sha256-Qyl9Q4QMTLZnnBb/8OuQ9LSkzWjBU1T5l5zIzTxkkhk=", + "lastModified": 1725513492, + "narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "4509ca64f1084e73bc7a721b20c669a8d4c5ebe6", + "rev": "7570de7b9b504cfe92025dd1be797bf546f66528", "type": "github" }, "original": { @@ -401,11 +401,11 @@ }, "haskell-flake": { "locked": { - "lastModified": 1725314890, - "narHash": "sha256-jjVrhLOlPjQiZ/8pe+g6Xc5sa563WXnNZDwGXVl4PXQ=", + "lastModified": 1726772832, + "narHash": "sha256-/kSaQVrsZsw5jmvCtRRouXvYDQSdTJ4wzsthIpuXoLQ=", "owner": "srid", "repo": "haskell-flake", - "rev": "ed94388c2e622f28cb45108a4e73c9d2b2a796da", + "rev": "31d7f050935f5a543212b7624d245f918ab14275", "type": "github" }, "original": { @@ -439,11 +439,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1725587318, - "narHash": "sha256-Xll3Xeq3BSAYRyuMdU2h1HP6JTbeOUfzZk/q0eAJ5k0=", + "lastModified": 1726772456, + "narHash": "sha256-TUD+BjLARx3ZuGQ3PucNftbI3785Y5mz6N1uyPe8z58=", "owner": "srid", "repo": "haskell-template", - "rev": "7fca847acc06d4be946e56a18eeca767cc43afc7", + "rev": "5abfbedd090d37d896055a531b99264fe009fa51", "type": "github" }, "original": { @@ -460,11 +460,11 @@ ] }, "locked": { - "lastModified": 1725694918, - "narHash": "sha256-+HsjshXpqNiJHLaJaK0JnIicJ/a1NquKcfn4YZ3ILgg=", + "lastModified": 1726357542, + "narHash": "sha256-p4OrJL2weh0TRtaeu1fmNYP6+TOp/W2qdaIJxxQay4c=", "owner": "nix-community", "repo": "home-manager", - "rev": "aaebdea769a5c10f1c6e50ebdf5924c1a13f0cda", + "rev": "e524c57b1fa55d6ca9d8354c6ce1e538d2a1f47f", "type": "github" }, "original": { @@ -482,11 +482,11 @@ ] }, "locked": { - "lastModified": 1724435763, - "narHash": "sha256-UNky3lJNGQtUEXT2OY8gMxejakSWPTfWKvpFkpFlAfM=", + "lastModified": 1726308872, + "narHash": "sha256-d4vwO5N4RsLnCY7k5tY9xbdYDWQsY3RDMeUoIa4ms2A=", "owner": "nix-community", "repo": "home-manager", - "rev": "c2cd2a52e02f1dfa1c88f95abeb89298d46023be", + "rev": "6c1a461a444e6ccb3f3e42bb627b510c3a722a57", "type": "github" }, "original": { @@ -550,11 +550,11 @@ ] }, "locked": { - "lastModified": 1724561770, - "narHash": "sha256-zv8C9RNa86CIpyHwPIVO/k+5TfM8ZbjGwOOpTe1grls=", + "lastModified": 1726188813, + "narHash": "sha256-Vop/VRi6uCiScg/Ic+YlwsdIrLabWUJc57dNczp0eBc=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "ac5694a0b855a981e81b4d9f14052e3ff46ca39e", + "rev": "21fe31f26473c180390cfa81e3ea81aca0204c80", "type": "github" }, "original": { @@ -575,11 +575,11 @@ "systems": "systems_4" }, "locked": { - "lastModified": 1726269505, - "narHash": "sha256-3hfZ9PwkkupC9ts+AS62cF+9RkjcYDq4QH4PBiO/x5M=", + "lastModified": 1726772388, + "narHash": "sha256-A7nP6SaONKQrvMRigZzc3ovAHRGgoUgS5IG/xlXcTjc=", "owner": "juspay", "repo": "nix-dev-home", - "rev": "6419eb34adf320b58aa587613902179845b68dea", + "rev": "0f08119a4561d4c44edf31ffe8dca6ffe93838da", "type": "github" }, "original": { @@ -596,11 +596,11 @@ ] }, "locked": { - "lastModified": 1725161148, - "narHash": "sha256-WfAHq3Ag3vLNFfWxKHjFBFdPI6JIideWFJod9mx1eoo=", + "lastModified": 1725765290, + "narHash": "sha256-hwX53i24KyWzp2nWpQsn8lfGQNCP0JoW/bvQmcR1DPY=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "32058e9138248874773630c846563b1a78ee7a5b", + "rev": "642275444c5a9defce57219c944b3179bf2adaa9", "type": "github" }, "original": { @@ -609,6 +609,66 @@ "type": "github" } }, + "nix-systems-aarch64-darwin": { + "locked": { + "lastModified": 1680978170, + "narHash": "sha256-PHVNQ7y0EQYzujQRYoRdb96K0m1KSeAjSrbz2b75S6Q=", + "owner": "nix-systems", + "repo": "aarch64-darwin", + "rev": "75e6c6912484d28ebba5769b794ffa4aff653ba2", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "aarch64-darwin", + "type": "github" + } + }, + "nix-systems-aarch64-linux": { + "locked": { + "lastModified": 1680978097, + "narHash": "sha256-1Zp7TRYLXj4P5FLhQ8jBChrgAmQxR3iTypmWf9EFTnc=", + "owner": "nix-systems", + "repo": "aarch64-linux", + "rev": "aa1ce1b64c822dff925d63d3e771113f71ada1bb", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "aarch64-linux", + "type": "github" + } + }, + "nix-systems-x86_64-darwin": { + "locked": { + "lastModified": 1680978224, + "narHash": "sha256-+xT9B1ZbhMg/zpJqd00S06UCZb/A2URW9bqqrZ/JTOg=", + "owner": "nix-systems", + "repo": "x86_64-darwin", + "rev": "db0463cce4cd60fb791f33a83d29a1ed53edab9b", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "x86_64-darwin", + "type": "github" + } + }, + "nix-systems-x86_64-linux": { + "locked": { + "lastModified": 1680978846, + "narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=", + "owner": "nix-systems", + "repo": "x86_64-linux", + "rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "x86_64-linux", + "type": "github" + } + }, "nixos-flake": { "locked": { "lastModified": 1726266595, @@ -698,11 +758,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1725634671, - "narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=", + "lastModified": 1726062873, + "narHash": "sha256-IiA3jfbR7K/B5+9byVi9BZGWTD4VSbWe8VLpp9B/iYk=", "owner": "nixos", "repo": "nixpkgs", - "rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c", + "rev": "4f807e8940284ad7925ebd0a0993d2a1791acb2f", "type": "github" }, "original": { @@ -808,11 +868,11 @@ "treefmt-nix": "treefmt-nix_2" }, "locked": { - "lastModified": 1725744583, - "narHash": "sha256-bzJ5iUPaEjSt24fIoQihBGN+Q7mye73hd/jbubHhyZA=", + "lastModified": 1726353028, + "narHash": "sha256-vU1PB7D7FqcCAVpSjuNmx85wWTZUoU0/gQ5haauO9Xs=", "owner": "nix-community", "repo": "nixvim", - "rev": "810eacf5163b16b666ca70b6617c6a85ce412e0a", + "rev": "f1881b4e4b7007cbf22d3ff005fdb8a876bddea2", "type": "github" }, "original": { @@ -831,11 +891,11 @@ ] }, "locked": { - "lastModified": 1724584782, - "narHash": "sha256-7FfHv7b1jwMPSu9SPY9hdxStk8E6EeSwzqdvV69U4BM=", + "lastModified": 1726208959, + "narHash": "sha256-Bq2YtXyHhDpBrqDlJysQgbhvauyiYTQXt7d6xxZdRck=", "owner": "NuschtOS", "repo": "search", - "rev": "5a08d691de30b6fc28d58ce71a5e420f2694e087", + "rev": "4267d5c5b51591a9553eefbd12172da050ee3433", "type": "github" }, "original": { @@ -851,6 +911,10 @@ "devour-flake": "devour-flake", "flake-parts": "flake-parts_5", "nix": "nix", + "nix-systems-aarch64-darwin": "nix-systems-aarch64-darwin", + "nix-systems-aarch64-linux": "nix-systems-aarch64-linux", + "nix-systems-x86_64-darwin": "nix-systems-x86_64-darwin", + "nix-systems-x86_64-linux": "nix-systems-x86_64-linux", "nixpkgs": "nixpkgs_4", "process-compose-flake": "process-compose-flake", "rust-flake": "rust-flake", @@ -858,11 +922,11 @@ "treefmt-nix": "treefmt-nix_3" }, "locked": { - "lastModified": 1725590656, - "narHash": "sha256-G6D96mILdxAGG7SVItC7xIKF1y8gijGkNMCGW/3N0MU=", + "lastModified": 1726355159, + "narHash": "sha256-3bInyLELraliL8CMDE/F/cMDcMaf6o/1Vapw9lP3Glk=", "owner": "juspay", "repo": "omnix", - "rev": "c566f7a4566473fdedca6bb8d32178820be0502f", + "rev": "77ac6777aa3f8ef8c5a571f8766ab31426b15b1e", "type": "github" }, "original": { @@ -1011,11 +1075,11 @@ "treefmt-nix": "treefmt-nix_4" }, "locked": { - "lastModified": 1725926096, - "narHash": "sha256-lMtMsrP0pSh66K182FKhmH2o8onyr5Coraio2Vqz08M=", + "lastModified": 1726772904, + "narHash": "sha256-xXirR1+2Vsktmp53kof5utTuqL5dgle7h+x4AxC+jTs=", "owner": "srid", "repo": "rust-nix-template", - "rev": "f850df534e6ee784ac332bb13ded1d5f81d18751", + "rev": "92939a935091dbaab491556c62aa74f197ad374e", "type": "github" }, "original": { @@ -1176,11 +1240,11 @@ ] }, "locked": { - "lastModified": 1724833132, - "narHash": "sha256-F4djBvyNRAXGusJiNYInqR6zIMI3rvlp6WiKwsRISos=", + "lastModified": 1725271838, + "narHash": "sha256-VcqxWT0O/gMaeWTTjf1r4MOyG49NaNxW4GHTO3xuThE=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "3ffd842a5f50f435d3e603312eefa4790db46af5", + "rev": "9fb342d14b69aefdf46187f6bb80a4a0d97007cd", "type": "github" }, "original": { diff --git a/crates/omnix-init/registry/flake.nix b/crates/omnix-init/registry/flake.nix index 374cd6e4..91c975f7 100644 --- a/crates/omnix-init/registry/flake.nix +++ b/crates/omnix-init/registry/flake.nix @@ -19,129 +19,24 @@ packages.hello = pkgs.hello; # Dummy output for `om ci` }; - flake = { - # TODO: Ideally, these params should be moved to upstream module. - # But do that only as the spec stabilizes. - om.templates = { - nix-dev-home = { - template = inputs.nix-dev-home.templates.default; - params = [ - { - name = "username"; - description = "Your username as shown by `whoami`"; - placeholder = "runner"; - } - # Git - { - name = "git-name"; - description = "Your full name for use in Git config"; - placeholder = "John Doe"; - } - { - name = "git-email"; - description = "Your email for use in Git config"; - placeholder = "johndoe@example.com"; - } - # Neovim - { - name = "neovim"; - description = "Include Neovim configuration"; - paths = [ "**/neovim**" ]; - value = false; - } - { - name = "github-ci"; - description = "Include GitHub Actions workflow configuration"; - paths = [ ".github" ]; - value = false; - } - ]; - }; - - haskell-flake = { - template = inputs.haskell-flake.templates.example; - params = [ - { - name = "package-name"; - description = "Name of the Haskell package"; - placeholder = "example"; - } - ]; - }; - - haskell-template = { - template = inputs.haskell-template.templates.default; - params = [ - { - name = "author"; - description = "Author name"; - placeholder = "Sridhar Ratnakumar"; - } - { - name = "package-name"; - description = "Name of the Haskell package"; - placeholder = "haskell-template"; - } - { - name = "vscode"; - description = "Include the VSCode settings folder (./.vscode)"; - paths = [ ".vscode" ]; - value = true; - } - { - name = "github-ci"; - description = "Include GitHub Actions workflow configuration"; - paths = [ ".github" ]; - value = true; - } - { - name = "nix-template"; - description = "Keep the flake template in the project"; - paths = [ "**/template.nix" ]; - value = false; - } - ]; - }; - - rust-nix-template = { - template = inputs.rust-nix-template.templates.default; - params = [ - { - name = "package-name"; - description = "Name of the Rust package"; - placeholder = "rust-nix-template"; - } - { - name = "author"; - description = "Author name"; - placeholder = "Sridhar Ratnakumar"; - } - { - name = "author-email"; - description = "Author email"; - placeholder = "srid@srid.ca"; - } - { - name = "vscode"; - description = "Include the VSCode settings folder (./.vscode)"; - paths = [ ".vscode" ]; - value = true; - } - { - name = "github-ci"; - description = "Include GitHub Actions workflow configuration"; - paths = [ ".github" ]; - value = true; - } - { - name = "nix-template"; - description = "Keep the flake template in the project"; - paths = [ "**/template.nix" ]; - value = false; - } - ]; - }; + flake = + let + inherit (inputs.nixpkgs) lib; + # Accumulate om.templates from all inputs + inputsTemplates = + let + templateSets = lib.mapAttrsToList + (name: input: + if name == "self" + then { } + else lib.attrByPath [ "om" "templates" ] { } input + ) + inputs; + in + builtins.foldl' (acc: set: acc // set) { } templateSets; + in + { + om.templates = inputsTemplates; }; - }; }; } diff --git a/crates/omnix-init/src/config.rs b/crates/omnix-init/src/config.rs index 898780c9..6d06ad89 100644 --- a/crates/omnix-init/src/config.rs +++ b/crates/omnix-init/src/config.rs @@ -8,18 +8,18 @@ use nix_rs::{ use crate::template::Template; /// Our builtin registry of templates -static REGISTRY: LazyLock = +pub static BUILTIN_REGISTRY: LazyLock = LazyLock::new(|| PathBuf::from(env!("OM_INIT_REGISTRY")).into()); /// The `om.templates` config in flake pub type TemplatesConfig = HashMap; /// Load templates from our builtin registry `REGISTRY` -pub async fn load_templates() -> anyhow::Result { +pub async fn load_templates(url: &FlakeUrl) -> anyhow::Result { let v = nix_eval::( &NixCmd::default(), &FlakeOptions::default(), - ®ISTRY.with_attr("om.templates"), + &url.with_attr("om.templates"), ) .await?; Ok(v) diff --git a/crates/omnix-init/src/core.rs b/crates/omnix-init/src/core.rs index de3376e3..eefe04e5 100644 --- a/crates/omnix-init/src/core.rs +++ b/crates/omnix-init/src/core.rs @@ -1,7 +1,8 @@ use std::{collections::HashMap, path::Path}; -use crate::config::load_templates; +use crate::config::{load_templates, BUILTIN_REGISTRY}; use anyhow::Context; +use nix_rs::flake::url::FlakeUrl; use serde_json::Value; /// Initialize a template at the given path @@ -13,24 +14,36 @@ use serde_json::Value; /// - `non_interactive` - Whether to disable user prompts (all params must have values set) pub async fn initialize_template( path: &Path, - name: Option, + flake: Option, default_params: &HashMap, non_interactive: bool, ) -> anyhow::Result<()> { tracing::info!("Loading registry ..."); - let templates = load_templates().await?; + let registry = flake.unwrap_or(BUILTIN_REGISTRY.clone()); + let templates = load_templates(®istry).await?; - // If the name is not provided, prompt the user to select a template - let name = match name { - Some(name) => name, - None => { - let p = inquire::Select::new("Select a template", templates.keys().cloned().collect()); - p.prompt()? + // Prompt the user to select a template + let available: Vec = templates.keys().cloned().collect(); + let name: &String = if let Some(attr) = registry.get_attr().0 { + &attr.clone() + } else if available.len() < 2 { + if let Some(name) = available.first() { + tracing::info!( + "Automatically choosing the one template available: {}", + name + ); + name + } else { + return Err(anyhow::anyhow!("No templates available")); } + } else if non_interactive { + return Err(anyhow::anyhow!("Non-interactive mode requires exactly one template to be available; but {} are available. Explicit specify it in flake URL.", available.len())); + } else { + &inquire::Select::new("Select a template", available).prompt()? }; let mut template = templates - .get(&name) + .get(name) .cloned() .with_context(|| "Template not found")?; diff --git a/doc/src/history.md b/doc/src/history.md index d9cb29dd..ab36f3d1 100644 --- a/doc/src/history.md +++ b/doc/src/history.md @@ -4,6 +4,8 @@ ### Enhancements +- `om init` + - Initial working version of `om init` command - `om health` - Display Nix installer used (supports DetSys installer) - `om ci` diff --git a/doc/src/om/init.md b/doc/src/om/init.md index 70743737..9191896b 100644 --- a/doc/src/om/init.md +++ b/doc/src/om/init.md @@ -1,14 +1,21 @@ # `om init` -> [!IMPORTANT] -> `om init` is available as a beta-feature. - The `om init` command provides a better [`nix flake init`](https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-flake-init) experience. Specifically, it provides: 1. a registry of flake templates that you can choose from 2. support for template paramters that can be filled in by the user -## Available templates {#list} +To get started, run: + +```sh +om init -t ~/myproject +``` + +This will prompt you to choose a template from the builtin registry (see below section), and then initialize it in the `myproject` directory. + +## Builtin registry {#registry} + +The builtin registry contains the following templates: | Description | Command | |-------------|---------| @@ -16,12 +23,23 @@ The `om init` command provides a better [`nix flake init`](https://nix.dev/manua | [Rust project template](https://github.com/srid/rust-nix-template) | `om init rust-nix-template` | | [home-manager template](https://github.com/juspay/nix-dev-home) | `om init nix-dev-home` | -## Adding your own project templates {#custom} +## Initializing your own project templates {#custom} -In future, you would be able to directly initialize a project from a git repository, viz.: `om init `. This is explicitly not yet supported right now, because: +If your flake provides a `om.templates` output (see below section), then `om init` will recognize it. For example: + +```sh +om init -t ~/myproject github:srid/haskell-flake +``` + +Because haskell-flake has [a `om.templates` output](https://github.com/srid/haskell-flake/blob/31d7f050935f5a543212b7624d245f918ab14275/flake.nix#L16-L26), `om init` will prompt you to fill in the parameters defined in the template and initialize it. + +You can also explicitly specify the template to choose from the flake: + +```sh +om init -t ~/myproject github:srid/haskell-flake#haskell-flake +``` -> [!NOTE] -> The specification for template paramters are yet to be finalized. Until, then the relevant parameter configuration is tied to the registry in omnix repo. See [`crates/omnix-init/registry`](https://github.com/juspay/omnix/tree/main/crates/omnix-init/registry). +If there are multiple templates in the flake (as is the case with the builtin registry), omnix will the prompt the user to choose from them. ## Configuration spec {#spec}