diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index 5c8d89129e..8d69f91d5d 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -1,18 +1,30 @@ use indexmap::IndexMap; use nu::{ - serve_plugin, Args, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess, + serve_plugin, Args, CommandConfig, NamedType, Plugin, PositionalType, Primitive, ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value, }; struct Inc { field: Option, + major: bool, + minor: bool, + patch: bool, } impl Inc { fn new() -> Inc { - Inc { field: None } + Inc { + field: None, + major: false, + minor: false, + patch: false, + } } - fn inc(value: Spanned, field: &Option) -> Result, ShellError> { + fn inc( + &self, + value: Spanned, + field: &Option, + ) -> Result, ShellError> { match value.item { Value::Primitive(Primitive::Int(i)) => Ok(Value::int(i + 1).spanned(value.span)), Value::Primitive(Primitive::Bytes(b)) => { @@ -24,6 +36,19 @@ impl Inc { item: Value::string(format!("{}", i + 1)), span: value.span, }) + } else if let Ok(mut ver) = semver::Version::parse(&s) { + if self.major { + ver.increment_major(); + } else if self.minor { + ver.increment_minor(); + } else { + self.patch; + ver.increment_patch(); + } + Ok(Spanned { + item: Value::string(ver.to_string()), + span: value.span, + }) } else { Err(ShellError::string("string could not be incremented")) } @@ -31,7 +56,7 @@ impl Inc { Value::Object(_) => match field { Some(f) => { let replacement = match value.item.get_data_by_path(value.span, f) { - Some(result) => Inc::inc(result.map(|x| x.clone()), &None)?, + Some(result) => self.inc(result.map(|x| x.clone()), &None)?, None => { return Err(ShellError::string("inc could not find field to replace")) } @@ -60,16 +85,31 @@ impl Inc { impl Plugin for Inc { fn config(&mut self) -> Result { + let mut named = IndexMap::new(); + named.insert("major".to_string(), NamedType::Switch); + named.insert("minor".to_string(), NamedType::Switch); + named.insert("patch".to_string(), NamedType::Switch); + Ok(CommandConfig { name: "inc".to_string(), positional: vec![PositionalType::optional_any("Field")], is_filter: true, is_sink: false, - named: IndexMap::new(), + named, rest_positional: true, }) } fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> { + if args.has("major") { + self.major = true; + } + if args.has("minor") { + self.minor = true; + } + if args.has("patch") { + self.patch = true; + } + if let Some(args) = args.positional { for arg in args { match arg { @@ -93,7 +133,7 @@ impl Plugin for Inc { } fn filter(&mut self, input: Spanned) -> Result, ShellError> { - Ok(vec![ReturnSuccess::value(Inc::inc(input, &self.field)?)]) + Ok(vec![ReturnSuccess::value(self.inc(input, &self.field)?)]) } }