helix/dna/cmd/
migrate.rs

1use clap::{Args, Subcommand, Parser};
2use std::path::PathBuf;
3use crate::mds::migrate;
4
5#[derive(Parser, Debug)]
6pub struct MigrateArgs {
7    #[command(subcommand)]
8    pub command: MigrateCommands,
9}
10
11#[derive(Subcommand, Debug)]
12pub enum MigrateCommands {
13    /// Migrate a file from one format to another
14    File(FileArgs),
15    /// Migrate a directory of files
16    Dir(DirArgs),
17}
18
19#[derive(Args, Debug)]
20pub struct FileArgs {
21    /// Input file to migrate
22    #[arg(short, long)]
23    pub input: PathBuf,
24    /// Output file (optional)
25    #[arg(short, long)]
26    pub output: Option<PathBuf>,
27    /// Enable verbose output
28    #[arg(long, default_value_t = false)]
29    pub verbose: bool,
30}
31
32#[derive(Args, Debug)]
33pub struct DirArgs {
34    /// Input directory to migrate
35    #[arg(short, long)]
36    pub input_dir: PathBuf,
37    /// Output directory (optional)
38    #[arg(short, long)]
39    pub output_dir: Option<PathBuf>,
40    /// File extension filter (e.g. json, toml, yaml)
41    #[arg(short, long)]
42    pub extension: Option<String>,
43    /// Enable verbose output
44    #[arg(long, default_value_t = false)]
45    pub verbose: bool,
46}
47
48pub async fn run(args: MigrateArgs) -> anyhow::Result<()> {
49    match args.command {
50        MigrateCommands::File(file_args) => {
51            let migrator = migrate::Migrator::new().verbose(file_args.verbose);
52            migrator.migrate_file(&file_args.input, file_args.output.as_ref()).map_err(|e| anyhow::anyhow!("Migration failed: {}", e))?;
53            Ok(())
54        }
55        MigrateCommands::Dir(dir_args) => {
56            let migrator = migrate::Migrator::new().verbose(dir_args.verbose);
57            let input_dir = &dir_args.input_dir;
58            let output_dir = dir_args.output_dir.as_ref();
59            let ext_filter = dir_args.extension.as_deref();
60            for entry in std::fs::read_dir(input_dir)? {
61                let entry = entry?;
62                let path = entry.path();
63                if path.is_file() {
64                    if let Some(ext) = ext_filter {
65                        if path.extension().and_then(|e| e.to_str()) != Some(ext) {
66                            continue;
67                        }
68                    }
69                    let output_path = output_dir.map(|od| od.join(path.file_name().unwrap()));
70                    migrator.migrate_file(&path, output_path.as_ref())?;
71                }
72            }
73            Ok(())
74        }
75    }
76}