add init command

This commit is contained in:
Qyriad 2026-04-01 14:51:15 +02:00
parent 264700c9fd
commit b0fc0debc9
5 changed files with 92 additions and 6 deletions

16
Cargo.lock generated
View file

@ -339,6 +339,7 @@ dependencies = [
"fs-err",
"humantime",
"iddqd",
"indoc",
"itertools",
"libc",
"mio",
@ -685,6 +686,15 @@ dependencies = [
"serde_core",
]
[[package]]
name = "indoc"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
dependencies = [
"rustversion",
]
[[package]]
name = "is-terminal"
version = "0.4.17"
@ -1045,6 +1055,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.23"

View file

@ -35,6 +35,7 @@ displaydoc = "0.2.5"
fs-err = "3.2.2"
humantime = "2.3.0"
iddqd = "0.3.17"
indoc = "2.0.7"
itertools = "0.14.0"
libc = { version = "0.2.180", features = ["extra_traits"] }
#macro_rules_attribute = { version = "0.2.2", features = ["better-docs", "verbose-expansions"] }

View file

@ -32,9 +32,18 @@ pub struct DaemonCmd {
pub bind: SocketAddr,
}
#[derive(Debug, Clone, PartialEq, clap::Parser)]
#[command(long_about = None)]
pub struct InitCmd {
/// Overwrite existing files.
#[arg(long)]
pub force: bool,
}
#[derive(Debug, Clone, PartialEq, clap::Subcommand)]
pub enum Subcommand {
Append(AppendCmd),
Init(InitCmd),
Daemon(DaemonCmd),
OpenApiDocs,
}

View file

@ -49,7 +49,7 @@ pub mod prelude {
use prelude::*;
pub mod args;
pub use args::{AppendCmd, Args};
pub use args::{AppendCmd, Args, InitCmd};
mod boxext;
mod color;
pub use color::{_CLI_ENABLE_COLOR, SHOULD_COLOR};
@ -107,11 +107,6 @@ pub(crate) fn open_source_file(path: Arc<Path>) -> Result<SourceFile, IoError> {
.tap_err(|e| error!("couldn't open source file at {}: {e}", path.display()))
}
pub(crate) fn get_line_to_insert() -> SourceLine {
//
todo!();
}
#[tracing::instrument(level = "debug")]
pub fn do_append(args: Arc<Args>, append_args: AppendCmd) -> Result<(), BoxDynError> {
let filepath = &args.file;
@ -165,6 +160,70 @@ pub fn do_daemon(args: Arc<Args>, daemon_args: DaemonCmd) -> Result<(), BoxDynEr
Ok(())
}
const DYNAMIC_NIX_INIT: &str = indoc::indoc! {"
/** GENERATED BY DYNIX */
{ lib, ... }:
{
imports = [
./configuration.nix
];
config = lib.mkMerge [
];
}
"};
fn open_for_init(path: &Path, init_args: &InitCmd) -> Result<File, IoError> {
let mut opts = File::options();
opts.write(true).create_new(true);
let file = match opts.open(path) {
Ok(file) => file,
Err(e) if e.kind() == IoErrorKind::AlreadyExists => {
if !init_args.force {
error!(
"Refusing to overwrite existing file at '{}' without --force",
path.display(),
);
return Err(e);
}
info!("Overwriting existing file at '{}'", path.display());
File::options()
.write(true)
.create(true)
.open(path)
.inspect_err(|e| {
error!(
"Failed to open path at '{}' for overwriting: {e}",
path.display(),
)
})?
},
Err(e) => {
error!(
"Failed to open path at '{}' for creation: {e}",
path.display()
);
return Err(e);
},
};
Ok(file)
}
pub fn do_init(args: Arc<Args>, init_args: InitCmd) -> Result<(), BoxDynError> {
let path = &*args.file;
let mut file = open_for_init(path, &init_args)?;
write!(&mut file, "{}", DYNAMIC_NIX_INIT)
.inspect_err(|e| error!("Failed to write to file at '{}': {e}", path.display()))?;
file.flush()
.inspect_err(|e| warn!("Failed to flush file at '{}': {e}", path.display()))?;
info!("Initialized Dynix file at '{}'", path.display());
Ok(())
}
#[derive(Debug, Clone, PartialEq, Hash, Serialize, Deserialize)]
pub struct DefinitionWithLocation {
pub file: Box<Path>,

View file

@ -44,6 +44,7 @@ fn main_wrapped() -> Result<(), Box<dyn StdError + Send + Sync + 'static>> {
match &args.subcommand {
Append(append_args) => dynix::do_append(args.clone(), append_args.clone())?,
Daemon(daemon_args) => dynix::do_daemon(args.clone(), daemon_args.clone())?,
Init(init_args) => dynix::do_init(args.clone(), init_args.clone())?,
OpenApiDocs => {
//let api = dynix::ApiDoc::openapi();
//dbg!(api);