summary history branches tags files
commit:d903e4adb92b298d8c8272e2bb27858926692919
author:Trevor Bentley
committer:Trevor Bentley
date:Fri Jan 13 17:29:38 2023 +0100
parents:cfc589e3b27bf405cafa3d613cf7b7b515e3f5c6
CLI options to generate and open local repositories
diff --git a/Cargo.lock b/Cargo.lock
line changes: +17/-0
index 9222487..e1f41f7
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -583,6 +583,7 @@ dependencies = [
  "chrono",
  "clap",
  "git2",
+ "open",
  "pulldown-cmark",
  "rayon",
  "serde",
@@ -782,6 +783,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "open"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8"
+dependencies = [
+ "pathdiff",
+ "windows-sys",
+]
+
+[[package]]
 name = "openssl-probe"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -816,6 +827,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "pathdiff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+
+[[package]]
 name = "percent-encoding"
 version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"

diff --git a/Cargo.toml b/Cargo.toml
line changes: +1/-0
index afdeaa3..6846fc5
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,7 @@ highlight = ["syntect/default-fancy"]
 chrono = { version = "0.4.23", features=["clock"] }
 clap = { version="4.0.32", features=["derive"] }
 git2 = "0.15.0"
+open = "3.2.0"
 pulldown-cmark = { version = "0.9.2", optional = true }
 rayon = "1.6.1"
 serde = { version = "1.0.152", features = ["derive"] }

diff --git a/src/generate.rs b/src/generate.rs
line changes: +5/-0
index a2657ed..e62500f
--- a/src/generate.rs
+++ b/src/generate.rs
@@ -700,6 +700,11 @@ impl GitsyGenerator {
             total_bytes,
             start_all.elapsed().as_secs_f32()
         );
+
+        if self.cli.should_open {
+            let _ = open::that(&format!("file://{}", self.settings.outputs.repo_list(None, None)));
+        }
+
         Ok(())
     }
 }

diff --git a/src/settings.rs b/src/settings.rs
line changes: +53/-1
index 889426c..c026929
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -18,10 +18,22 @@ use std::sync::atomic::Ordering;
 {all-args}{after-help}
 ")]
 struct CliArgs {
+    /// Path to TOML configuration file
     #[arg(short, long, value_name = "FILE")]
     config: Option<PathBuf>,
+    /// Specify path to a repository.  Overrides config TOML.  Can use multiple times.
+    #[arg(short, long)]
+    repo: Vec<PathBuf>,
+    /// Generate a site suitable for local browsing (file://)
+    #[arg(short, long)]
+    local: bool,
+    /// Open browser to repository listing after generation.
+    #[arg(short, long)]
+    open: bool,
+    /// Don't show any output, except errors and warnings
     #[arg(short, long)]
     quiet: bool,
+    /// Increase verbosity of output.  Specify up to 4 times.
     #[arg(short, long, action = clap::ArgAction::Count)]
     verbose: u8,
 }
@@ -29,6 +41,9 @@ struct CliArgs {
 pub struct GitsyCli {
     pub path: PathBuf,
     pub dir: PathBuf,
+    pub is_local: bool,
+    pub should_open: bool,
+    pub repos: Vec<PathBuf>,
 }
 
 impl GitsyCli {
@@ -61,6 +76,9 @@ impl GitsyCli {
         GitsyCli {
             path: config_path,
             dir: config_dir,
+            is_local: cli.local,
+            should_open: cli.open,
+            repos: cli.repo,
         }
     }
 }
@@ -260,7 +278,11 @@ impl GitsySettings {
     pub fn new(cli: &GitsyCli) -> (GitsySettings, GitsyRepoDescriptions) {
         // Parse the known settings directly into their struct
         let toml = read_to_string(&cli.path).expect(&format!("Configuration file not found: {}", cli.path.display()));
-        let settings: GitsySettings = toml::from_str(&toml).expect("Configuration file is invalid.");
+        let mut settings: GitsySettings = toml::from_str(&toml).expect("Configuration file is invalid.");
+        if cli.is_local {
+            // removing the site URL falls back to using the local directory
+            settings.site_url = None;
+        }
 
         // Settings are valid, so let's move into the directory with the config file
         if cli.dir.to_str().unwrap_or_default().len() > 0 {
@@ -357,6 +379,36 @@ impl GitsySettings {
             }
             _ => {}
         }
+
+        if cli.repos.len() > 0 {
+            repo_descriptions.clear();
+            for dir in &cli.repos {
+                let name: String = dir.file_name()
+                    .expect(&format!("Invalid repository path: {}", dir.display()))
+                    .to_string_lossy().to_string();
+                repo_descriptions.insert(GitsySettingsRepo {
+                    path: dir.clone(),
+                    name: Some(name),
+                    branch: settings.branch.clone(),
+                    render_markdown: settings.render_markdown.clone(),
+                    syntax_highlight: settings.syntax_highlight.clone(),
+                    syntax_highlight_theme: settings.syntax_highlight_theme.clone(),
+                    paginate_history: settings.paginate_history.clone(),
+                    paginate_branches: settings.paginate_branches.clone(),
+                    paginate_tags: settings.paginate_tags.clone(),
+                    limit_history: settings.limit_history.clone(),
+                    limit_commits: settings.limit_commits.clone(),
+                    limit_branches: settings.limit_branches.clone(),
+                    limit_tags: settings.limit_tags.clone(),
+                    limit_tree_depth: settings.limit_tree_depth.clone(),
+                    limit_file_size: settings.limit_file_size.clone(),
+                    limit_repo_size: settings.limit_repo_size.clone(),
+                    limit_total_size: settings.limit_total_size.clone(),
+                    ..Default::default()
+                });
+            }
+        }
+
         (settings, repo_descriptions)
     }