nix: add module to generate nix flake

This commit is contained in:
Dmitriy Pleshevskiy 2024-04-03 23:45:23 +03:00
parent 7fbedf684e
commit b3f326286a
Signed by: pleshevskiy
GPG key ID: 17041163DA10A9A2
6 changed files with 132 additions and 17 deletions

View file

@ -10,13 +10,17 @@ use clap::Parser;
use crate::{ use crate::{
config::read_config, config::read_config,
module::{direnv::DirenvModule, gitignore::GitIgnoreModule, Module}, module::{direnv::DirenvModule, gitignore::GitIgnoreModule, nix_flake::NixFlakeModule, Module},
}; };
use self::{direnv::DirenvModuleCliArgs, gitignore::GitIgnoreModuleCliArgs}; use self::{
direnv::DirenvModuleCliArgs, gitignore::GitIgnoreModuleCliArgs,
nix_flake::NixFlakeModuleCliArgs,
};
mod direnv; mod direnv;
mod gitignore; mod gitignore;
mod nix_flake;
#[derive(Debug, Clone, clap::Args)] #[derive(Debug, Clone, clap::Args)]
struct MakeCommand { struct MakeCommand {
@ -28,6 +32,8 @@ enum AddModuleCommand {
Direnv(DirenvModuleCliArgs), Direnv(DirenvModuleCliArgs),
#[clap(name = "gitignore")] #[clap(name = "gitignore")]
GitIgnore(GitIgnoreModuleCliArgs), GitIgnore(GitIgnoreModuleCliArgs),
#[clap(name = "nix.flake")]
NixFlake(NixFlakeModuleCliArgs),
#[clap(external_subcommand)] #[clap(external_subcommand)]
External(Vec<String>), External(Vec<String>),
} }
@ -140,24 +146,27 @@ pub fn run() -> Result<(), Box<dyn std::error::Error>> {
match args.command { match args.command {
Command::Make(_make_args) => { Command::Make(_make_args) => {
let config = read_config(&current_dir)?; let config = read_config(&current_dir)?;
let mut make_files: HashMap<String, String> = HashMap::new(); let make_files: HashMap<String, String> = [
config.direnv.map(|v| DirenvModule.make(v.into())),
if let Some(cfg) = config.direnv { config.gitignore.map(|v| GitIgnoreModule.make(v.into())),
make_files.extend(DirenvModule.make(cfg.into())) config
} .nix
if let Some(cfg) = config.gitignore { .and_then(|cfg| cfg.flake.map(|v| NixFlakeModule.make(v.into()))),
make_files.extend(GitIgnoreModule.make(cfg.into())); ]
} .into_iter()
.flatten()
.fold(HashMap::new(), |mut acc, files| {
acc.extend(files);
acc
});
make(current_dir, make_files, true) make(current_dir, make_files, true)
} }
Command::Add { force, command } => { Command::Add { force, command } => {
let mut make_files: HashMap<String, String> = HashMap::new(); let make_files: HashMap<String, String> = match command {
match command { AddModuleCommand::Direnv(args) => DirenvModule.make(args.into()),
AddModuleCommand::Direnv(args) => make_files.extend(DirenvModule.make(args.into())), AddModuleCommand::GitIgnore(args) => GitIgnoreModule.make(args.into()),
AddModuleCommand::GitIgnore(args) => { AddModuleCommand::NixFlake(args) => NixFlakeModule.make(args.into()),
make_files.extend(GitIgnoreModule.make(args.into()))
}
AddModuleCommand::External(_) => { AddModuleCommand::External(_) => {
unimplemented!("external commands") unimplemented!("external commands")
} }

21
src/cli/nix_flake.rs Normal file
View file

@ -0,0 +1,21 @@
use crate::module::nix_flake::NixFlakeModuleArgs;
#[derive(Debug, Clone, clap::Args)]
pub struct NixFlakeModuleCliArgs {
#[clap(short, long)]
description: Option<String>,
#[clap(long)]
extra_inputs: Option<String>,
#[clap(long)]
extra_outputs: Option<String>,
}
impl From<NixFlakeModuleCliArgs> for NixFlakeModuleArgs {
fn from(args: NixFlakeModuleCliArgs) -> Self {
NixFlakeModuleArgs {
description: args.description,
extra_inputs: args.extra_inputs,
extra_outputs: args.extra_outputs,
}
}
}

View file

@ -1,12 +1,21 @@
use std::{fs, io, path::PathBuf}; use std::{fs, io, path::PathBuf};
use self::{direnv::DirenvModuleConfig, gitignore::GitIgnoreModuleConfig}; use self::{
direnv::DirenvModuleConfig, gitignore::GitIgnoreModuleConfig, nix_flake::NixFlakeModuleConfig,
};
mod direnv; mod direnv;
mod gitignore; mod gitignore;
mod nix_flake;
#[derive(serde::Deserialize, serde::Serialize)]
pub struct NixConfig {
pub flake: Option<NixFlakeModuleConfig>,
}
#[derive(serde::Deserialize, serde::Serialize)] #[derive(serde::Deserialize, serde::Serialize)]
pub struct Config { pub struct Config {
pub nix: Option<NixConfig>,
pub direnv: Option<DirenvModuleConfig>, pub direnv: Option<DirenvModuleConfig>,
pub gitignore: Option<GitIgnoreModuleConfig>, pub gitignore: Option<GitIgnoreModuleConfig>,
} }

18
src/config/nix_flake.rs Normal file
View file

@ -0,0 +1,18 @@
use crate::module::nix_flake::NixFlakeModuleArgs;
#[derive(Default, serde::Deserialize, serde::Serialize)]
pub struct NixFlakeModuleConfig {
description: Option<String>,
extra_inputs: Option<String>,
extra_outputs: Option<String>,
}
impl From<NixFlakeModuleConfig> for NixFlakeModuleArgs {
fn from(cfg: NixFlakeModuleConfig) -> Self {
NixFlakeModuleArgs {
description: cfg.description,
extra_inputs: cfg.extra_inputs,
extra_outputs: cfg.extra_outputs,
}
}
}

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
pub mod direnv; pub mod direnv;
pub mod gitignore; pub mod gitignore;
pub mod nix_flake;
pub trait Module { pub trait Module {
type ModuleArgs; type ModuleArgs;

57
src/module/nix_flake.rs Normal file
View file

@ -0,0 +1,57 @@
use std::collections::HashMap;
use std::io::{self, Write};
use super::Module;
pub struct NixFlakeModuleArgs {
pub description: Option<String>,
pub extra_inputs: Option<String>,
pub extra_outputs: Option<String>,
}
fn make_flakenix_content(args: NixFlakeModuleArgs) -> Result<String, io::Error> {
let mut s = Vec::new();
writeln!(s, "{{")?;
#[rustfmt::skip]
writeln!(s, " description = \"{}\";", args.description.unwrap_or_default())?;
// ----------------------
// INPUTS
writeln!(s, " inputs = {{")?;
if let Some(extra_inputs) = args.extra_inputs {
writeln!(s, "{}", extra_inputs.trim())?;
}
writeln!(s, " }};")?;
// ----------------------
// OUTPUTS
writeln!(s, " outputs =")?;
writeln!(s, " {{ self")?;
writeln!(s, " , nixpkgs")?;
writeln!(s, " , ...")?;
writeln!(s, " }} @ inputs:")?;
if let Some(extra_outputs) = args.extra_outputs {
write!(s, " ({});", extra_outputs.trim())?;
} else {
writeln!(s, " {{")?;
writeln!(s, " }};")?;
}
writeln!(s, "}}")?;
Ok(String::from_utf8(s).unwrap())
}
pub struct NixFlakeModule;
impl Module for NixFlakeModule {
type ModuleArgs = NixFlakeModuleArgs;
fn make(&self, args: Self::ModuleArgs) -> HashMap<String, String> {
HashMap::from([(
String::from("flake.nix"),
make_flakenix_content(args).unwrap(),
)])
}
}