Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ reqwest = { version = "0.11", default-features = false, features = ["json", "gzi
serde_json = "1.0.140"
syntect = "5.2.0"
openssl = { version = "0.10", features = ["vendored"] }
indicatif = "0.17.12"
indicatif = "0.17.11"
73 changes: 0 additions & 73 deletions scripts/install_issue_template.sh

This file was deleted.

81 changes: 81 additions & 0 deletions src/commands/issue/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use std::path::Path;
use std::time::Duration;

use indicatif::{ProgressBar, ProgressStyle};

use super::{GITHUB_API_BASE, GITHUB_RAW_BASE};
use crate::utils::remote::Fetcher;

const OUTPUT_BASE_PATH: &str = ".github";
const OUTPUT: &str = "ISSUE_TEMPLATE";

pub fn add(args: &[String]) -> anyhow::Result<()> {
let fetcher = Fetcher::new();

if args.is_empty() {
return Err(anyhow::anyhow!(
"No issue template specified. Use --all to download all templates."
));
}

// Check if --all flag is provided
if args.contains(&"--all".to_string()) {
let pb = ProgressBar::new_spinner();
pb.set_style(
ProgressStyle::default_spinner()
.tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
.template("{spinner} {msg}")
.unwrap(),
);
pb.enable_steady_tick(Duration::from_millis(100));
pb.set_message("Fetching all templates...");

let url = format!("{}/issue-templates", GITHUB_API_BASE);
let entries = fetcher.fetch_json(&url)?;
let mut downloaded_templates = Vec::new();

if let Some(array) = entries.as_array() {
for entry in array {
if let Some(name) = entry.get("name").and_then(|n| n.as_str()) {
let template_name = match name.rfind('.') {
Some(idx) => &name[..idx],
None => name,
};

pb.set_message(format!("Downloading template: {}", template_name));

let url = format!("{}/issue-templates/{}", GITHUB_RAW_BASE, name);
let dest_path = Path::new(OUTPUT_BASE_PATH).join(OUTPUT).join(name);

fetcher.fetch_to_file(&url, &dest_path)?;
downloaded_templates.push(format!("{}.yml", template_name));
}
}
}
pb.finish_and_clear();
println!(
"\x1b[32m✓\x1b[0m Downloaded all issue templates to {}/{}",
OUTPUT_BASE_PATH, OUTPUT
);
for template in downloaded_templates {
println!(" \x1b[32m>\x1b[0m {}", template);
}
} else {
// Download specified templates
for template in args {
let url = format!("{}/issue-templates/{}.yml", GITHUB_RAW_BASE, template);
let dest_path = Path::new(OUTPUT_BASE_PATH)
.join(OUTPUT)
.join(format!("{}.yml", template));

fetcher.fetch_to_file(&url, &dest_path)?;

println!(
"\x1b[32m✓\x1b[0m Downloaded and added issue template: {}",
dest_path.display()
);
}
}

Ok(())
}
39 changes: 2 additions & 37 deletions src/commands/issue.rs → src/commands/issue/list.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
use std::path::Path;
use std::time::Duration;

use indicatif::{ProgressBar, ProgressStyle};

use super::{GITHUB_API_BASE, GITHUB_RAW_BASE};
use crate::utils::get_comment;
use crate::utils::pretty_print;
use crate::utils::remote::Fetcher;

const OUTPUT_BASE_PATH: &str = ".github";
const OUTPUT: &str = "ISSUE_TEMPLATE";
const GITHUB_RAW_BASE: &str =
"https://raw.githubusercontent.com/rafaeljohn9/gh-templates/main/templates";
const GITHUB_API_BASE: &str =
"https://api.github.com/repos/rafaeljohn9/gh-templates/contents/templates";

pub fn add(template: &str) -> anyhow::Result<()> {
let fetcher = Fetcher::new();
let url = format!("{}/issue-templates/{}.yml", GITHUB_RAW_BASE, template);
let dest_path = Path::new(OUTPUT_BASE_PATH)
.join(OUTPUT)
.join(format!("{}.yml", template));

fetcher.fetch_to_file(&url, &dest_path)?;

println!(
"\x1b[32m✓\x1b[0m Downloaded and added issue template: {}",
dest_path.display()
);
Ok(())
}

pub fn list() -> anyhow::Result<()> {
pub fn list(_extra_args: &[String]) -> anyhow::Result<()> {
let fetcher = Fetcher::new();

let pb = ProgressBar::new_spinner();
Expand Down Expand Up @@ -87,14 +63,3 @@ pub fn list() -> anyhow::Result<()> {
}
Ok(())
}

pub fn preview(template: &str) -> anyhow::Result<()> {
let fetcher = Fetcher::new();
let url = format!("{}/issue-templates/{}.yml", GITHUB_RAW_BASE, template);

println!("\x1b[32m✓\x1b[0m Previewing issue template: {}", template);

let content = fetcher.fetch_content(&url)?;
pretty_print::print_highlighted("yml", &content);
Ok(())
}
16 changes: 16 additions & 0 deletions src/commands/issue/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Global constants - these can stay in the main module file
const GITHUB_RAW_BASE: &str =
"https://raw.githubusercontent.com/rafaeljohn9/gh-templates/main/templates";
const GITHUB_API_BASE: &str =
"https://api.github.com/repos/rafaeljohn9/gh-templates/contents/templates";

// Re-export submodules
pub mod add;
pub mod list;
pub mod preview;

// Re-export the main functions for backward compatibility
pub use add::add;
pub use list::list;
pub use preview::preview;

14 changes: 14 additions & 0 deletions src/commands/issue/preview.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use super::GITHUB_RAW_BASE;
use crate::utils::pretty_print;
use crate::utils::remote::Fetcher;

pub fn preview(template: &str, _extra_args: &[String]) -> anyhow::Result<()> {
let fetcher = Fetcher::new();
let url = format!("{}/issue-templates/{}.yml", GITHUB_RAW_BASE, template);

println!("\x1b[32m✓\x1b[0m Previewing issue template: {}", template);

let content = fetcher.fetch_content(&url)?;
pretty_print::print_highlighted("yml", &content);
Ok(())
}
36 changes: 36 additions & 0 deletions src/commands/license/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::utils::remote::Fetcher;
use anyhow::anyhow;
use std::path::Path;

use super::GITHUB_LICENSES_API;

pub fn add(args: &[String]) -> anyhow::Result<()> {
if args.is_empty() {
return Err(anyhow!("At least one license ID is required"));
}

let fetcher = Fetcher::new();

for id in args {
let url = format!("{}/{}", GITHUB_LICENSES_API, id.to_lowercase());

let license_data = fetcher.fetch_json(&url)?;

let body = license_data
.get("body")
.and_then(|b| b.as_str())
.ok_or_else(|| anyhow!("License body not found for {}", id))?;

let filename = format!("LICENSE.{}", id.to_uppercase());
let dest_path = Path::new(&filename);

std::fs::write(dest_path, body)?;

println!(
"\x1b[32m✓\x1b[0m Downloaded and added license: {}",
dest_path.display()
);
}

Ok(())
}
39 changes: 39 additions & 0 deletions src/commands/license/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::utils::remote::Fetcher;
use indicatif::{ProgressBar, ProgressStyle};
use std::time::Duration;

use super::GITHUB_LICENSES_API;

pub fn list(_extra_args: &[String]) -> anyhow::Result<()> {
let fetcher = Fetcher::new();

let pb = ProgressBar::new_spinner();
pb.set_style(
ProgressStyle::default_spinner()
.tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
.template("{spinner} {msg}")
.unwrap(),
);
pb.enable_steady_tick(Duration::from_millis(100));
pb.set_message("Fetching license list...");

let licenses = fetcher.fetch_json(GITHUB_LICENSES_API)?;

pb.finish_with_message("Successfully fetched licenses");

if let Some(array) = licenses.as_array() {
println!("\x1b[32m✓\x1b[0m Available licenses:");
for license in array {
if let (Some(key), Some(name)) = (
license.get("key").and_then(|k| k.as_str()),
license.get("name").and_then(|n| n.as_str()),
) {
println!(" \x1b[32m>\x1b[0m {:<15} {}", key, name);
}
}
} else {
println!("No licenses found.");
}

Ok(())
}
12 changes: 12 additions & 0 deletions src/commands/license/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Global constants - these can stay in the main module file
pub const GITHUB_LICENSES_API: &str = "https://api.github.com/licenses";

// Re-export submodules
pub mod add;
pub mod list;
pub mod preview;

// Re-export the main functions for backward compatibility
pub use add::add;
pub use list::list;
pub use preview::preview;
Loading
Loading