Skip to content

Commit 8dc54d7

Browse files
authored
Merge pull request #4 from krupa-dev/ft/manplan-2
Ft/manplan 2
2 parents bb5b4ed + dec09a8 commit 8dc54d7

File tree

6 files changed

+49
-16
lines changed

6 files changed

+49
-16
lines changed

Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "manplan"
3-
version = "0.1.3"
3+
version = "0.1.4"
44
authors = ["Gerard Krupa"]
55
edition = "2021"
66
description = "Tool for keeping sdkman candidates up-to-date"
@@ -17,6 +17,7 @@ serde = { version = "1.0", features = ["derive"] }
1717
serde_yaml = "0.9"
1818
maplit = "1.0.2"
1919
clap = { version = "4.4.6", features = ["derive"] }
20+
expect-exit = "0.5.2"
2021

2122
[profile.release]
2223
lto = "fat"

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
This tool reads a YAML manifest defining a list of SDKman candidate
44
versions and installs the latest versions that match this manifest.
55

6+
If the -f option is not provided, the default manifest
7+
(~/.sdk-rules.yaml) is used.
8+
69
Each candidate can support multiple versions and each version is
710
specified as a regular expression match and zero or more regular
811
expression exclusions (in order to, for example, filter out release
@@ -44,7 +47,7 @@ chmod +x /usr/local/bin/manplan
4447

4548
## Usage
4649

47-
`manplan -f|--file <manifest file> [-d|--dry-run] [-n|--no-uninstall]`
50+
`manplan [-f|--file <manifest file>] [-d|--dry-run] [-n|--no-uninstall]`
4851

4952
## Manifest format
5053

src/main.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::collections::HashSet;
2-
use std::fs;
2+
use std::path::Path;
3+
use std::{env, fs};
34

45
use clap::Parser;
6+
use expect_exit::Expected;
57

68
use crate::rules::{parse_rules, VersionMatch};
79
use crate::sdkman::{SdkMan, ToolManager};
@@ -14,7 +16,7 @@ pub mod sdkman;
1416
struct Args {
1517
/// Filename of the YAML config file
1618
#[arg(short, long)]
17-
file: String,
19+
file: Option<String>,
1820

1921
/// Just print out the commands that would be executed
2022
#[arg(short, long, default_value_t = false)]
@@ -25,15 +27,32 @@ struct Args {
2527
no_uninstall: bool,
2628
}
2729

30+
#[allow(clippy::needless_return)]
31+
fn get_rules_file(args: &Args) -> Option<String> {
32+
if let Some(file) = args.file.as_ref() {
33+
return Some(file.clone());
34+
} else if let Ok(home) = env::var("HOME") {
35+
let dotfile = Path::new(home.as_str()).join(".sdk-rules.yaml");
36+
if dotfile.is_file() {
37+
return Some(dotfile.to_str().unwrap().to_string());
38+
}
39+
}
40+
return None;
41+
}
42+
2843
fn main() {
2944
let args = Args::parse();
3045

3146
let sdkman = SdkMan {
3247
dry_run: args.dry_run,
3348
no_uninstall: args.no_uninstall,
3449
};
35-
let rules = parse_rules(fs::read_to_string(args.file).expect("Failed to read input file"));
36-
for (name, candidate) in rules.expect("Rules file could not be parsed").candidates {
50+
51+
let rules_file =
52+
get_rules_file(&args).or_exit_("Must specify -f or have a ~/.sdk-rules.yaml file");
53+
let rules = parse_rules(fs::read_to_string(rules_file).or_exit_("Failed to read rules file"));
54+
55+
for (name, candidate) in rules.or_exit_("Rules file could not be parsed").candidates {
3756
let installed: HashSet<_> = sdkman
3857
.installed_versions(name.clone())
3958
.into_iter()

src/rules/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use expect_exit::Expected;
12
use regex::Regex;
23
use std::collections::HashMap;
34

@@ -32,7 +33,7 @@ pub trait VersionMatch {
3233
impl VersionMatch for Version {
3334
fn get_matching(&self, name: String, available: Vec<String>) -> Option<String> {
3435
let pattern = Regex::new(self.pattern.as_str())
35-
.unwrap_or_else(|_| panic!("Invalid regex for {}: {}", name, self.pattern));
36+
.or_exit_(format!("Invalid regex for {}: {}", name, self.pattern).as_str());
3637
let mut matches: Vec<String> = available
3738
.iter()
3839
.filter(|it| pattern.is_match(it))
@@ -41,7 +42,7 @@ impl VersionMatch for Version {
4142

4243
if let Some(exclude) = self.exclude.as_ref() {
4344
let exclude_pattern = Regex::new(exclude.join("|").as_str())
44-
.unwrap_or_else(|_| panic!("Invalid regex for {}: {}", name, exclude.join("|")));
45+
.or_exit_(format!("Invalid regex for {}: {}", name, exclude.join("|")).as_str());
4546
matches.retain(|it| !exclude_pattern.is_match(it));
4647
}
4748

src/sdkman/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::sdkman::candidate::{Candidate, SdkManCandidate};
2+
use expect_exit::Expected;
23
use std::fs::read_dir;
34
use std::io::Write;
5+
use std::path::Path;
46
use std::{env, io};
57

68
mod candidate;
@@ -23,10 +25,10 @@ impl ToolManager for SdkMan {
2325
fn installed_versions(&self, candidate: String) -> Vec<String> {
2426
return match env::var("SDKMAN_DIR") {
2527
Ok(dir) => {
26-
let base = format!("{}/candidates/{}", dir, candidate);
27-
if std::path::Path::new(&base).is_dir() {
28+
let base = Path::new(dir.as_str()).join("candidates").join(candidate);
29+
if base.is_dir() {
2830
read_dir(base)
29-
.expect("Failed to read $SDKMAN_DIR")
31+
.or_exit_("Failed to read $SDKMAN_DIR")
3032
.filter(|entry| entry.as_ref().unwrap().file_type().unwrap().is_dir())
3133
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
3234
.collect()
@@ -48,7 +50,7 @@ impl ToolManager for SdkMan {
4850
.arg("-c")
4951
.arg(format!("sdk list {}", candidate))
5052
.output()
51-
.expect("Failed to run the sdk list command. Is SDKMAN installed?");
53+
.or_exit_("Failed to run the sdk list command. Is SDKMAN installed?");
5254
if output.status.success() {
5355
SdkManCandidate {
5456
name: candidate,
@@ -76,7 +78,7 @@ impl ToolManager for SdkMan {
7678
.arg("-c")
7779
.arg(cmd)
7880
.output()
79-
.expect("Error running sdk install command");
81+
.or_exit_("Error running sdk install command");
8082
if output.status.success() {
8183
println!("OK");
8284
} else {
@@ -105,7 +107,7 @@ impl ToolManager for SdkMan {
105107
.arg("-c")
106108
.arg(cmd)
107109
.output()
108-
.expect("Error running sdk install command");
110+
.or_exit_("Error running sdk install command");
109111
if output.status.success() {
110112
println!("OK");
111113
} else {
@@ -132,7 +134,7 @@ impl ToolManager for SdkMan {
132134
.arg("-c")
133135
.arg(cmd)
134136
.output()
135-
.expect("Error running sdk install command");
137+
.or_exit_("Error running sdk install command");
136138
if output.status.success() {
137139
println!("OK");
138140
} else {

0 commit comments

Comments
 (0)