-
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
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
c7197c1
Started messing around with submodule outputs.
761a583
Added submodule macro and fixed clippy lints.
e7247ec
Added docs.
b1d0520
Started messing around with submodule outputs.
f7ad9e4
Added submodule macro and fixed clippy lints.
ea2884f
Added docs.
da3a7b4
Trying to tokenize a tuple of &str.
043f387
Finished array creation.
7f9d730
merge
0d4e1ef
Working on final quote block./
4fdaa93
Added submodule version struct to output.
30d74d2
Removed submodule version struct.
fd0925d
Updated docs.
0dd1bb5
Renamed macro and added more effective test.
111b54e
Removed submodules.
f5ba079
Removed submodule.
0e92ea6
Fixed up for projects without submodules.
dc059b8
Update git-version-macro/src/describe_submodules.rs
baxterjo b79c25b
Update git-version-macro/src/describe_submodules.rs
baxterjo c6f8ba9
Removed ignore.
386a08e
Added fallback on a per-submodule basis.
59f6c35
Corrected description of "fallback" in docs.
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
extern crate proc_macro; | ||
use crate::canonicalize_path; | ||
use crate::git_dependencies; | ||
use crate::utils::run_git; | ||
use proc_macro2::{Span, TokenStream as TokenStream2}; | ||
use quote::quote; | ||
use std::ffi::OsStr; | ||
use std::path::Path; | ||
use std::process::Command; | ||
use syn::{ | ||
bracketed, | ||
parse::{Parse, ParseStream}, | ||
punctuated::Punctuated, | ||
token::{Comma, Eq}, | ||
Ident, LitStr, | ||
}; | ||
|
||
macro_rules! error { | ||
($($args:tt)*) => { | ||
syn::Error::new(Span::call_site(), format!($($args)*)) | ||
}; | ||
} | ||
|
||
#[derive(Default)] | ||
pub(crate) struct GitModArgs { | ||
args: Option<Punctuated<LitStr, Comma>>, | ||
prefix: Option<LitStr>, | ||
suffix: Option<LitStr>, | ||
fallback: Option<LitStr>, | ||
} | ||
|
||
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() { | ||
"args" => { | ||
check_dup(result.args.is_some())?; | ||
let content; | ||
bracketed!(content in input); | ||
result.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_module_versions_impl(args: GitModArgs) -> syn::Result<TokenStream2> { | ||
let mut modules = match get_modules() { | ||
Ok(x) => x, | ||
Err(err) => return Err(error!("{}", err)), | ||
}; | ||
|
||
modules.retain(|path| !path.is_empty()); | ||
|
||
let mut describe_paths: Vec<(String, String)> = vec![]; | ||
|
||
for path in modules { | ||
let path_obj = Path::new(&path); | ||
let path_obj = canonicalize_path(path_obj)?; | ||
describe_paths.push((path, path_obj)); | ||
} | ||
|
||
let git_describe_args = args.args.map_or_else( | ||
|| vec!["--always".to_string(), "--dirty=-modified".to_string()], | ||
|list| list.iter().map(|x| x.value()).collect(), | ||
); | ||
|
||
let prefix = match args.prefix { | ||
Some(x) => x.value(), | ||
_ => "".to_string(), | ||
}; | ||
let suffix = match args.suffix { | ||
Some(x) => x.value(), | ||
_ => "".to_string(), | ||
}; | ||
let fallback = args.fallback.map(|x| x.value()); | ||
|
||
match describe_modules(describe_paths, &git_describe_args, prefix, suffix, fallback) { | ||
Ok(result) => { | ||
let dependencies = git_dependencies()?; | ||
let (paths, versions) = result; | ||
|
||
Ok(quote!({ | ||
#dependencies; | ||
|
||
[#((#paths, #versions)),*] | ||
|
||
})) | ||
} | ||
Err(e) => Err(error!("{}", e)), | ||
} | ||
} | ||
|
||
/// Run `git submodule foreach` command to discover submodules in the project. | ||
fn get_modules() -> Result<Vec<String>, String> { | ||
let mut args: Vec<String> = "submodule foreach --quiet --recursive" | ||
.to_string() | ||
.split(' ') | ||
.map(|x| x.to_string()) | ||
.collect(); | ||
|
||
args.push("echo $displaypath".to_string()); | ||
|
||
let result = run_git("git submodule", Command::new("git").args(args))?; | ||
|
||
Ok(result.split('\n').map(|x| x.to_string()).collect()) | ||
} | ||
|
||
/// Run `git describe` for each submodule to get the git version with the specified args. | ||
fn describe_modules<I, S>( | ||
paths: Vec<(String, String)>, | ||
describe_args: I, | ||
prefix: String, | ||
suffix: String, | ||
fallback: Option<String>, | ||
) -> Result<(Vec<String>, Vec<String>), String> | ||
where | ||
I: IntoIterator<Item = S> + Clone, | ||
S: AsRef<OsStr>, | ||
{ | ||
let mut paths_out: Vec<String> = vec![]; | ||
let mut versions: Vec<String> = vec![]; | ||
|
||
for (rel_path, abs_path) in paths.into_iter() { | ||
// Get the submodule version or fallback. | ||
let result = match run_git( | ||
"git describe", | ||
Command::new("git") | ||
.current_dir(abs_path) | ||
.arg("describe") | ||
.args(describe_args.clone()), | ||
) { | ||
Ok(version) => version, | ||
Err(_git_err) if fallback.is_some() => fallback.clone().unwrap(), | ||
Err(git_err) => { | ||
// If git error and no fallback provided, return error. | ||
return Err(git_err); | ||
} | ||
}; | ||
paths_out.push(rel_path); | ||
versions.push(format!("{}{}{}", prefix, result, suffix)) | ||
} | ||
|
||
Ok((paths_out, versions)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
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.
Does
echo $displaypath
work on windows though? Maybe we should parse the.gitmodules
file instead relying ongit submodule foreach
.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.
Lemme check real quick.
Edit: Yep! It works. The shell that executes the command must be implemented by git. Tested on Powershell and Command Prompt
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.
Ok :)