Skip to content

Commit

Permalink
Merge pull request #81 from siketyan/feat/additional-patterns
Browse files Browse the repository at this point in the history
feat: Support additional patterns for cloning
  • Loading branch information
siketyan authored Feb 14, 2023
2 parents 22edb62 + 32f077e commit db4e3f9
Show file tree
Hide file tree
Showing 11 changed files with 542 additions and 105 deletions.
131 changes: 129 additions & 2 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ indicatif = "0.17.1"
lazy_static = "1.4"
regex = "1.6"
serde = { version = "1.0", features = ["derive"] }
serde_regex = "1.1"
serde_with = "2.2"
tokio = { version = "1.25", features = ["macros", "rt-multi-thread"] }
toml = "0.7.2"
tracing = "0.1.37"
Expand Down
54 changes: 54 additions & 0 deletions ghr.example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# Example configuration for ghr.
#

[defaults]
# Sets the default owner of repositories.
# You can pass only repository name to 'ghr clone' when this is set.
owner = "siketyan"

[git]
# Chooses the strategy to use on Git clones.
# 'Cli' is the default. 'Git2' is also supported, but deprecated.
strategy.clone = "Cli"

[[patterns]]
# You can use additional patterns to specify where the repository is cloned from.
# For details of regular expression syntax, see https://docs.rs/regex/latest/regex/index.html .
regex = "^(?P<scheme>https)://(?P<host>git\\.kernel\\.org)/pub/scm/linux/kernel/git/(?P<owner>.+)/(?P<repo>.+)\\.git"

# You can override parameters if those are not in or different from the pattern.
vcs = "git"
scheme = "https"
user = ""
host = "git.kernel.org"
owner = "torvalds"

# Composes URL different from the input.
# This does not work when inferring is enabled.
url = "{{scheme}}://{{host}}/pub/scm/linux/kernel/git/{{owner}}/{{repo}}.{{vcs}}"

# Turn off inferring URL to use the raw input to clone.
infer = false

[profiles.work]
# Overrides Git profile using the profile.
# You need to add rule(s) to attach this profile onto a repository.
user.name = "My Working Name"
user.email = "[email protected]"

[applications.vscode]
# You can open a repository in VS Code using `ghr open <repo> vscode`.
cmd = "code"
args = ["%p"]

[[rules]]
# 'work' profile declared above is attached on this rule.
profile.name = "work"

# This rule is applied when the repository is owned by your company on GitHub.
host = "github.com"
owner = "my-company-org"

# Optionally you can apply the rule onto a specific repo.
#repo = "company-repo"
4 changes: 3 additions & 1 deletion src/cmd/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ impl Cmd {
}

fn clone(&self, root: &Root, config: &Config, repo: &str) -> Result<CloneResult> {
let url = Url::from_str(repo, config.defaults.owner.as_deref())?;
let url = Url::from_str(repo, &config.patterns, config.defaults.owner.as_deref())?;
let path = PathBuf::from(Path::resolve(root, &url));
let profile = config
.rules
.resolve(&url)
.and_then(|r| config.profiles.resolve(&r.profile));

info!("Cloning from '{}'", url.to_string());

config.git.strategy.clone.clone_repository(
url,
&path,
Expand Down
6 changes: 5 additions & 1 deletion src/cmd/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ impl Cmd {
return Ok(());
}

let url = Url::from_str(&self.repo, config.defaults.owner.as_deref())?;
let url = Url::from_str(
&self.repo,
&config.patterns,
config.defaults.owner.as_deref(),
)?;
let path = PathBuf::from(Path::resolve(&root, &url));

Spinner::new("Deleting the repository...")
Expand Down
6 changes: 5 additions & 1 deletion src/cmd/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ impl Cmd {
let root = Root::find()?;
let config = Config::load_from(&root)?;

let url = Url::from_str(&self.repo, config.defaults.owner.as_deref())?;
let url = Url::from_str(
&self.repo,
&config.patterns,
config.defaults.owner.as_deref(),
)?;
let path = Path::resolve(&root, &url);
let profile = config
.rules
Expand Down
6 changes: 5 additions & 1 deletion src/cmd/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ impl Cmd {
let root = Root::find()?;
let config = Config::load_from(&root)?;

let url = Url::from_str(&self.repo, config.defaults.owner.as_deref())?;
let url = Url::from_str(
&self.repo,
&config.patterns,
config.defaults.owner.as_deref(),
)?;
let path = PathBuf::from(Path::resolve(&root, &url));

config
Expand Down
1 change: 1 addition & 0 deletions src/cmd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl Cmd {
let path = if let Some(repo) = self.repo.as_deref() {
let url = Url::from_str(
repo,
&config.patterns,
self.owner.as_deref().or(config.defaults.owner.as_deref()),
)?;

Expand Down
24 changes: 23 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::git::Config as GitConfig;
use crate::profile::Profiles;
use crate::root::Root;
use crate::rule::Rules;
use crate::url::Patterns;

#[derive(Debug, Default, Deserialize)]
pub struct Defaults {
Expand All @@ -22,6 +23,8 @@ pub struct Config {
#[serde(default)]
pub git: GitConfig,
#[serde(default)]
pub patterns: Patterns,
#[serde(default)]
pub profiles: Profiles,
#[serde(default)]
pub applications: Applications,
Expand All @@ -43,8 +46,27 @@ impl Config {
P: AsRef<Path>,
{
Ok(match path.as_ref().exists() {
true => Some(toml::from_str(read_to_string(path)?.as_str())?),
true => Some(Self::load_from_str(read_to_string(path)?.as_str())?),
_ => None,
})
}

fn load_from_str(s: &str) -> Result<Self> {
Ok(toml::from_str::<Self>(s)?.with_defaults())
}

fn with_defaults(mut self) -> Self {
self.patterns = self.patterns.with_defaults();
self
}
}

#[cfg(test)]
mod tests {
use crate::config::Config;

#[test]
fn load_example_config() {
Config::load_from_str(include_str!("../ghr.example.toml")).unwrap();
}
}
Loading

0 comments on commit db4e3f9

Please sign in to comment.