nu_command/env/config/
config_reset.rs

1use chrono::Local;
2use nu_engine::command_prelude::*;
3use nu_utils::ConfigFileKind;
4use std::{io::Write, path::PathBuf};
5
6#[derive(Clone)]
7pub struct ConfigReset;
8
9impl Command for ConfigReset {
10    fn name(&self) -> &str {
11        "config reset"
12    }
13
14    fn signature(&self) -> Signature {
15        Signature::build(self.name())
16            .switch("nu", "reset only nu config, config.nu", Some('n'))
17            .switch("env", "reset only env config, env.nu", Some('e'))
18            .switch("without-backup", "do not make a backup", Some('w'))
19            .input_output_types(vec![(Type::Nothing, Type::Nothing)])
20            .allow_variants_without_examples(true)
21            .category(Category::Env)
22    }
23
24    fn description(&self) -> &str {
25        "Reset nushell environment configurations to default, and saves old config files in the config location as oldconfig.nu and oldenv.nu."
26    }
27
28    fn examples(&self) -> Vec<Example<'_>> {
29        vec![Example {
30            description: "reset nushell configuration files",
31            example: "config reset",
32            result: None,
33        }]
34    }
35
36    fn run(
37        &self,
38        engine_state: &EngineState,
39        stack: &mut Stack,
40        call: &Call,
41        _input: PipelineData,
42    ) -> Result<PipelineData, ShellError> {
43        let only_nu = call.has_flag(engine_state, stack, "nu")?;
44        let only_env = call.has_flag(engine_state, stack, "env")?;
45        let no_backup = call.has_flag(engine_state, stack, "without-backup")?;
46        let span = call.head;
47        let Some(config_path) = nu_path::nu_config_dir() else {
48            return Err(ShellError::ConfigDirNotFound { span: call.head });
49        };
50        if !only_env {
51            let kind = ConfigFileKind::Config;
52            let mut nu_config = config_path.clone();
53            nu_config.push(kind.path());
54            let config_file = kind.scaffold();
55            if !no_backup {
56                let mut backup_path = config_path.clone();
57                backup_path.push(format!(
58                    "oldconfig-{}.nu",
59                    Local::now().format("%F-%H-%M-%S"),
60                ));
61                if let Err(err) = std::fs::rename(nu_config.clone(), &backup_path) {
62                    return Err(ShellError::Io(IoError::new_with_additional_context(
63                        err.not_found_as(NotFound::Directory),
64                        span,
65                        PathBuf::from(backup_path),
66                        "config.nu could not be backed up",
67                    )));
68                }
69            }
70            if let Ok(mut file) = std::fs::File::create(&nu_config)
71                && let Err(err) = writeln!(&mut file, "{config_file}")
72            {
73                return Err(ShellError::Io(IoError::new_with_additional_context(
74                    err.not_found_as(NotFound::File),
75                    span,
76                    PathBuf::from(nu_config),
77                    "config.nu could not be written to",
78                )));
79            }
80        }
81        if !only_nu {
82            let kind = ConfigFileKind::Env;
83            let mut env_config = config_path.clone();
84            env_config.push(kind.path());
85            let config_file = kind.scaffold();
86            if !no_backup {
87                let mut backup_path = config_path.clone();
88                backup_path.push(format!("oldenv-{}.nu", Local::now().format("%F-%H-%M-%S"),));
89                if let Err(err) = std::fs::rename(env_config.clone(), &backup_path) {
90                    return Err(ShellError::Io(IoError::new_with_additional_context(
91                        err.not_found_as(NotFound::Directory),
92                        span,
93                        PathBuf::from(backup_path),
94                        "env.nu could not be backed up",
95                    )));
96                }
97            }
98            if let Ok(mut file) = std::fs::File::create(&env_config)
99                && let Err(err) = writeln!(&mut file, "{config_file}")
100            {
101                return Err(ShellError::Io(IoError::new_with_additional_context(
102                    err.not_found_as(NotFound::File),
103                    span,
104                    PathBuf::from(env_config),
105                    "env.nu could not be written to",
106                )));
107            }
108        }
109        Ok(PipelineData::empty())
110    }
111}