Skip to content

Commit

Permalink
add tests, break stuff
Browse files Browse the repository at this point in the history
+ new -y, --delete option to always delete
  • Loading branch information
marcelohdez committed Nov 15, 2023
1 parent 1eefb39 commit a638532
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 105 deletions.
129 changes: 129 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ anyhow = "1.0.75"
directories-next = "2.0.0"
clap = { version = "4.4.8", features = ["derive", "env"] }
chrono = "0.4.31"

[dev-dependencies]
assert_cmd = "2.0.12"
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ variable.
This makes testing some quick lines of code easy without having to open a new
replit or creating a new project with boilerplate yourself.

### Below is a showcase with the `$VISUAL` variable set to `nvim` for Neovim:
### Below is a showcase with the `$VISUAL` variable set to `nvim` for Neovim: (old)

[![asciicast](https://asciinema.org/a/5soMz3UBzMbXO2Nb7LQELtcsT.svg)](https://asciinema.org/a/5soMz3UBzMbXO2Nb7LQELtcsT)

Expand Down Expand Up @@ -44,8 +44,8 @@ Finally, you can create any templates you would like to use in atmpt's
may copy them over:

```bash
mkdir -p $(atmpt --template-dir)
cp -r templates/* $(atmpt --template-dir)
mkdir -p $(atmpt --list-template-dir)
cp -r templates/* $(atmpt --list-template-dir)
```

## Data Directory
Expand All @@ -56,7 +56,7 @@ Atmpt offers an option to print it out on your system (you may have seen its
output be used in the [installing] section):

```bash
atmpt --template-dir
atmpt --list-template-dir
```

_(The option could be shortened to `-d`)_
Expand Down
116 changes: 17 additions & 99 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,118 +1,36 @@
use std::{env, fs, io, path::Path, process::Command};

use anyhow::{bail, Ok};
use chrono::Local;
use clap::Parser;
use directories_next::ProjectDirs;
use templates::Templates;

pub mod templates;

pub const EDITOR_KEY: &str = "VISUAL";
pub const ALWAYS_DELETE_KEY: &str = "ATMPT_ALWAYS_DELETE";
pub const TEMPLATE_DIR_KEY: &str = "ATMPT_DATA_DIR";

#[derive(Debug, Parser)]
#[command(author, version, about)]
pub struct Atmpt {
#[command(flatten)]
required: RequiredArgs,
pub required: RequiredArgs,

#[arg(short, long, env = EDITOR_KEY, help = "Use given editor for this run")]
pub editor: Option<String>,

#[arg(short, long, env = "VISUAL", help = "Use given editor for this run")]
editor: Option<String>,
#[arg(short = 'y', long, env = ALWAYS_DELETE_KEY, help = "Autodelete project on exit")]
pub delete: bool,

#[arg(long, hide = true, env = TEMPLATE_DIR_KEY)] // override template dir
pub template_dir: Option<String>,
}

#[derive(Debug, Parser)]
#[group(required = true)]
pub struct RequiredArgs {
#[arg(group = "main")]
template: Option<String>,
pub template: Option<String>,

#[arg(
group = "main",
short = 'd',
long = "template-dir",
help = "Output template directory"
)]
list_template_dir: bool,
#[arg(group = "main", short = 'd', long, help = "Output template directory")]
pub list_template_dir: bool,

#[arg(group = "main", short, long, help = "List available templates")]
list_templates: bool,
}

impl Atmpt {
pub fn parse_with(dirs: &ProjectDirs) -> anyhow::Result<()> {
let args = Self::parse();
let req = args.required;
let data_dir = dirs.data_dir();

if let Some(template) = req.template {
let Some(editor) = args.editor else {
bail!("No editor to use!"); // really should not happen
};

try_template(&template, &editor, data_dir)?;
} else if req.list_template_dir {
println!("{}", data_dir.display());
} else {
println!("{}", Templates::try_from(data_dir)?);
}

Ok(())
}
}

fn try_template(template: &str, editor: &str, data_dir: &Path) -> anyhow::Result<()> {
let templates = Templates::try_from(data_dir)?;
let wanted_dir = templates.find(template)?;

let time = Local::now().format("%Y_%m_%d-%H_%M_%S");
let tmp_dir = env::temp_dir()
.join("atmpt") // store tmp projects in folder
.join(format!("{template}_{time}"));
copy_dir_recursively(wanted_dir, &tmp_dir)?;

std::env::set_current_dir(&tmp_dir).expect("Could not change to temp directory!");
Command::new(editor)
.arg(&tmp_dir)
.spawn()?
.wait()
.expect("Could not launch editor!");

if ask_y_n("Would you like to delete this project?")? {
fs::remove_dir_all(&tmp_dir)?;
println!("Deleted.")
} else {
println!("Saved as {tmp_dir:?}.");
}

Ok(())
}

fn ask_y_n(question: &str) -> anyhow::Result<bool> {
println!("{question} (Y/n)");

let mut input = String::new();
io::stdin().read_line(&mut input)?;

match input.to_lowercase().trim() {
"" => Ok(true), // default to yes if only enter is pressed
"y" => Ok(true),
"n" => Ok(false),
_ => ask_y_n(question),
}
}

// modified from https://stackoverflow.com/a/65192210/15425442
fn copy_dir_recursively(from: &Path, to: &Path) -> anyhow::Result<()> {
fs::create_dir_all(to)?;

for entry in fs::read_dir(from)? {
let entry = entry?;
let path = entry.path();

if path.is_dir() {
copy_dir_recursively(&path, &to.join(entry.file_name()))?;
} else {
fs::copy(path, to.join(entry.file_name()))?;
}
}

Ok(())
pub list_templates: bool,
}
Loading

0 comments on commit a638532

Please sign in to comment.