mirror of
https://github.com/SkyfallWasTaken/dinopkg.git
synced 2025-04-03 21:44:13 +00:00
131 lines
4.5 KiB
Rust
131 lines
4.5 KiB
Rust
use std::env;
|
|
|
|
use camino::Utf8PathBuf;
|
|
use color_eyre::eyre::eyre;
|
|
use color_eyre::Result;
|
|
use dialoguer::{theme::ColorfulTheme, Confirm, Input};
|
|
use dinopkg_package_json::PackageJson;
|
|
use gix_config::File as GitConfigFile;
|
|
use maplit::hashmap;
|
|
use owo_colors::OwoColorize;
|
|
use syntect::easy::HighlightLines;
|
|
use syntect::highlighting::{Style, ThemeSet};
|
|
use syntect::parsing::SyntaxSet;
|
|
use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings};
|
|
use tokio::fs;
|
|
|
|
pub async fn init() -> Result<()> {
|
|
// FIXME: one instance should be loaded at start
|
|
let ps = SyntaxSet::load_defaults_newlines();
|
|
let ts = ThemeSet::load_defaults();
|
|
let syntax = ps
|
|
.find_syntax_by_extension("json")
|
|
.ok_or(eyre!("failed to load json syntax"))?;
|
|
let mut h = HighlightLines::new(syntax, &ts.themes["base16-eighties.dark"]);
|
|
|
|
// Get some project/env specific info to make the defaults more relevant
|
|
let current_dir = Utf8PathBuf::try_from(env::current_dir()?)?;
|
|
let current_dir_name = current_dir.file_name().unwrap_or("package");
|
|
// FIXME: this blocks the event loop
|
|
let git_config_file = GitConfigFile::from_git_dir(current_dir.join(".git").into());
|
|
let git_repo_url = git_config_file
|
|
.map(|config| {
|
|
config
|
|
.section("remote", Some("origin".into()))
|
|
.ok()
|
|
.and_then(|remote_section| {
|
|
remote_section
|
|
.body()
|
|
.value("url")
|
|
.map(|url| url.to_string())
|
|
})
|
|
})
|
|
.ok()
|
|
.flatten()
|
|
.map(|url| url.replace("git@github.com", "https://github.com/"));
|
|
|
|
// Now, onto the questions!
|
|
let package_name: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Package name")
|
|
.default(current_dir_name.into())
|
|
.interact_text()?;
|
|
let version: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Package version")
|
|
.default("1.0.0".into())
|
|
.interact_text()?;
|
|
let private = Confirm::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Is this a private package?")
|
|
.default(true)
|
|
.interact()?;
|
|
let description: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Description")
|
|
.allow_empty(true)
|
|
.interact_text()?;
|
|
let entry_point: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Entry point")
|
|
.default("index.js".into())
|
|
.interact_text()?;
|
|
let test_command: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Test command")
|
|
.default("echo \"Error: no test specified\" && exit 1".into())
|
|
.interact_text()?;
|
|
let git_repository: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Git repository")
|
|
.default(git_repo_url.unwrap_or_default())
|
|
.interact_text()?;
|
|
let author: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Author name")
|
|
.allow_empty(true)
|
|
.interact_text()?;
|
|
let license: String = Input::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("License")
|
|
.default("MIT".into())
|
|
.interact_text()?;
|
|
|
|
let package_json = PackageJson {
|
|
name: package_name,
|
|
version,
|
|
author: Some(author),
|
|
repository: Some(git_repository),
|
|
license: Some(license),
|
|
description: Some(description),
|
|
private,
|
|
main: Some(entry_point),
|
|
|
|
scripts: Some(hashmap! {
|
|
"test".into() => test_command,
|
|
}),
|
|
|
|
dependencies: None,
|
|
dev_dependencies: None,
|
|
};
|
|
|
|
println!(
|
|
"\nI will write the following output to {}:",
|
|
"`package.json`".purple()
|
|
);
|
|
let output = serde_json::to_string_pretty(&package_json)?;
|
|
for line in LinesWithEndings::from(&output) {
|
|
let ranges: Vec<(Style, &str)> = h.highlight_line(line, &ps).unwrap();
|
|
let escaped = as_24_bit_terminal_escaped(&ranges[..], false);
|
|
print!("{escaped}");
|
|
}
|
|
println!("\x1b[0m");
|
|
|
|
let yes = Confirm::with_theme(&ColorfulTheme::default())
|
|
.with_prompt("Is this okay?")
|
|
.default(true)
|
|
.interact()?;
|
|
if yes {
|
|
fs::write("package.json", output).await?;
|
|
println!(
|
|
"Successfully wrote new {} for {}!",
|
|
"`package.json`".purple(),
|
|
package_json.name.purple()
|
|
);
|
|
} else {
|
|
println!("{}", "Cancelled.".bold().red());
|
|
}
|
|
|
|
Ok(())
|
|
}
|