-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support for Submodule Versioning #23
Changes from 9 commits
c7197c1
761a583
e7247ec
b1d0520
f7ad9e4
ea2884f
da3a7b4
043f387
7f9d730
0d4e1ef
4fdaa93
30d74d2
fd0925d
0dd1bb5
111b54e
f5ba079
0e92ea6
dc059b8
b79c25b
c6f8ba9
386a08e
59f6c35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[submodule "test-child-repo"] | ||
path = test-child-repo | ||
url = [email protected]:baxterjo/test-child-repo.git | ||
[submodule "test_outer_directory/test-child-repo"] | ||
path = test_outer_directory/test-child-repo | ||
url = [email protected]:baxterjo/test-child-repo.git |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
extern crate proc_macro; | ||
use crate::git_dependencies; | ||
use crate::utils::describe_modules; | ||
use proc_macro2::{Span, TokenStream as TokenStream2}; | ||
use quote::{quote, ToTokens}; | ||
use syn::{ | ||
bracketed, | ||
parse::{Parse, ParseStream}, | ||
punctuated::Punctuated, | ||
token::{Comma, Eq}, | ||
Expr, Ident, LitStr, | ||
}; | ||
|
||
macro_rules! error { | ||
($($args:tt)*) => { | ||
syn::Error::new(Span::call_site(), format!($($args)*)) | ||
}; | ||
} | ||
|
||
#[derive(Default)] | ||
pub(crate) struct GitModArgs { | ||
describe_args: Option<Punctuated<LitStr, Comma>>, | ||
foreach_args: Option<Punctuated<LitStr, Comma>>, | ||
prefix: Option<LitStr>, | ||
suffix: Option<LitStr>, | ||
fallback: Option<Expr>, | ||
} | ||
|
||
impl Parse for GitModArgs { | ||
fn parse(input: ParseStream) -> syn::Result<Self> { | ||
let mut result = GitModArgs::default(); | ||
loop { | ||
if input.is_empty() { | ||
break; | ||
} | ||
let ident: Ident = input.parse()?; | ||
let _: Eq = input.parse()?; | ||
let check_dup = |dup: bool| { | ||
if dup { | ||
Err(error!("`{} = ` can only appear once", ident)) | ||
} else { | ||
Ok(()) | ||
} | ||
}; | ||
match ident.to_string().as_str() { | ||
"describe_args" => { | ||
check_dup(result.describe_args.is_some())?; | ||
let content; | ||
bracketed!(content in input); | ||
result.describe_args = Some(Punctuated::parse_terminated(&content)?); | ||
} | ||
"foreach_args" => { | ||
check_dup(result.foreach_args.is_some())?; | ||
let content; | ||
bracketed!(content in input); | ||
result.foreach_args = Some(Punctuated::parse_terminated(&content)?); | ||
} | ||
"prefix" => { | ||
check_dup(result.prefix.is_some())?; | ||
result.prefix = Some(input.parse()?); | ||
} | ||
"suffix" => { | ||
check_dup(result.suffix.is_some())?; | ||
result.suffix = Some(input.parse()?); | ||
} | ||
"fallback" => { | ||
check_dup(result.fallback.is_some())?; | ||
result.fallback = Some(input.parse()?); | ||
} | ||
x => Err(error!("Unexpected argument name `{}`", x))?, | ||
} | ||
if input.is_empty() { | ||
break; | ||
} | ||
let _: Comma = input.parse()?; | ||
} | ||
Ok(result) | ||
} | ||
} | ||
|
||
pub(crate) fn git_version_modules_impl(args: GitModArgs) -> syn::Result<TokenStream2> { | ||
let git_describe_args = args.describe_args.map_or_else( | ||
|| vec!["--always".to_string(), "--dirty=-modified".to_string()], | ||
|list| list.iter().map(|x| x.value()).collect(), | ||
); | ||
|
||
let mut git_foreach_args = args.foreach_args.map_or_else( | ||
|| vec!["--quiet".to_string(), "--recursive".to_string()], | ||
|list| list.iter().map(|x| x.value()).collect(), | ||
); | ||
|
||
if !git_foreach_args.contains(&"--quiet".to_string()) { | ||
git_foreach_args.push("--quiet".to_string()) | ||
} | ||
|
||
let prefix = match args.prefix { | ||
Some(x) => x.value(), | ||
_ => "".to_string(), | ||
}; | ||
let suffix = match args.suffix { | ||
Some(x) => x.value(), | ||
_ => "".to_string(), | ||
}; | ||
|
||
let descibe_args = format!("echo $displaypath:`git describe {}`", git_describe_args.join(" ")); | ||
|
||
let mut git_args: Vec<String> = vec!["submodule".to_string(), "foreach".to_string()]; | ||
git_args.append(&mut git_foreach_args); | ||
git_args.push(descibe_args); | ||
|
||
match describe_modules(&git_args) { | ||
Ok(version) => { | ||
let dependencies = git_dependencies()?; | ||
|
||
let mut output: Vec<Vec<String>> = vec![]; | ||
let newline_split = version.split('\n'); | ||
|
||
for line in newline_split { | ||
let line = line.to_string(); | ||
let line_split: Vec<&str> = line.split(':').collect(); | ||
assert!( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The proc macro should never panic. This should be a compile error instead. But I also think the check should probably be removed. If people use colons in their tags, it should still just work. But maybe we shouldn't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed, and removed foreach args. Also renamed |
||
line_split.len() == 2, | ||
// NOTE: I Don't love this split, but I think I have protected against weirdness | ||
// by adding the only arbitrary text allowed (prefix, suffix) after the split happens. | ||
// so unless people are using colons in their tag names, it should be fine. | ||
"Found an unexpected colon ':' in git describe output - {}", | ||
version | ||
); | ||
output.push(vec![line_split[0].to_string(), format!("{}{}{}", prefix, line_split[1], suffix)]) | ||
} | ||
|
||
Ok(quote!({ | ||
#dependencies; | ||
[#([#(#output),*]),*] | ||
})) | ||
} | ||
Err(_) if args.fallback.is_some() => Ok(args.fallback.to_token_stream()), | ||
Err(e) => Err(error!("{}", e)), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to set up a custom testing repo for this instead of adding submodules. But I will take care of this part, since I also think they should be in the same organization :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed submodules and added more effective test. Also fixed some issues that popped up when this macro is ran in a project with no submodules.