use super::WrappedPackage;
const ECO: &str = "go";
const VERB: &str = "get";
pub fn parse(argv: &[&str]) -> Vec<WrappedPackage> {
let Some(verb_pos) = argv.iter().position(|a| *a == VERB) else {
return Vec::new();
};
let mut packages = Vec::new();
for arg in argv.iter().skip(verb_pos + 1) {
if arg.starts_with('-') {
continue;
}
if arg.is_empty() {
continue;
}
if arg.starts_with('.') || *arg == "all" {
continue;
}
let (name, version) = split_pkg_spec(arg);
packages.push(WrappedPackage::new(ECO, name, version));
}
packages
}
pub fn split_pkg_spec(spec: &str) -> (String, String) {
match spec.rsplit_once('@') {
Some((name, ver)) if !name.is_empty() && !ver.is_empty() => {
(name.to_string(), ver.to_string())
}
_ => (spec.to_string(), "latest".to_string()),
}
}
#[cfg(test)]
mod tests {
use super::*;
fn argv<'a>(args: &[&'a str]) -> Vec<&'a str> {
let mut v: Vec<&'a str> = vec!["go"];
v.extend_from_slice(args);
v
}
#[test]
fn parses_get_pinned() {
let a = argv(&["get", "github.com/sirupsen/logrus@v1.9.0"]);
let pkgs = parse(&a);
assert_eq!(
pkgs[0],
WrappedPackage::new("go", "github.com/sirupsen/logrus", "v1.9.0")
);
}
#[test]
fn parses_get_unpinned() {
let a = argv(&["get", "github.com/sirupsen/logrus"]);
let pkgs = parse(&a);
assert_eq!(pkgs[0].version, "latest");
}
#[test]
fn parses_get_at_latest() {
let a = argv(&["get", "github.com/sirupsen/logrus@latest"]);
let pkgs = parse(&a);
assert_eq!(pkgs[0].version, "latest");
}
#[test]
fn skips_relative_path() {
let a = argv(&["get", "./..."]);
assert!(parse(&a).is_empty());
}
#[test]
fn skips_all_target() {
let a = argv(&["get", "all"]);
assert!(parse(&a).is_empty());
}
#[test]
fn skips_update_flag() {
let a = argv(&["get", "-u", "github.com/sirupsen/logrus"]);
let pkgs = parse(&a);
assert_eq!(pkgs.len(), 1);
assert_eq!(pkgs[0].name, "github.com/sirupsen/logrus");
}
#[test]
fn no_get_verb_returns_empty() {
let a = argv(&["build"]);
assert!(parse(&a).is_empty());
}
}