summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Grunert <Sascha.Grunert@rohde-schwarz.com>2016-09-20 13:11:20 +0200
committerSascha Grunert <Sascha.Grunert@rohde-schwarz.com>2016-09-20 13:11:20 +0200
commitef84296b304cebbf039027def1d77c8acf77c4a0 (patch)
treee4e9112fc18bd444097185bde5fc26e4859ed173
parent64901becf10856b164852b299500db00b02af6a4 (diff)
Added version 0.2.00.2.0
- Added footer accumulation including templating support - Added configuration option `enable_footers` - Improved documentation about it - Improved unit tests to increase test coverage - Improved internal code structure by reorganizing traits - Changed travis to run code coverage only on nightly builds
-rw-r--r--.gitjournal.toml2
-rw-r--r--.travis.yml7
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--README.md32
-rw-r--r--src/lib.rs2
-rw-r--r--src/parser.rs85
-rw-r--r--tests/template.toml1
m---------tests/test_repo0
9 files changed, 103 insertions, 30 deletions
diff --git a/.gitjournal.toml b/.gitjournal.toml
index f22e943..8508b77 100644
--- a/.gitjournal.toml
+++ b/.gitjournal.toml
@@ -1,6 +1,6 @@
colored_output = true
enable_debug = true
-enable_footers = true
+enable_footers = false
excluded_commit_tags = []
show_prefix = false
template_prefix = "JIRA-1234"
diff --git a/.travis.yml b/.travis.yml
index e3a7e0a..74e8d15 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,13 +13,10 @@ script:
- cargo doc --no-deps
after_success:
- travis-cargo --only nightly doc-upload
- - travis-cargo coveralls --no-sudo --verify
- - ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/gitjournal*
+ - if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then travis-cargo coveralls --no-sudo --verify; fi
+ - if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/gitjournal*; fi
os:
- linux
-matrix:
- allow_failures:
- - rust: nightly
notifications:
email:
on_success: never
diff --git a/Cargo.lock b/Cargo.lock
index 8a2e288..ee29661 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
[root]
name = "git-journal"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 5a730b9..cb3eb75 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "git-journal"
-version = "0.1.0"
+version = "0.2.0"
license = "MIT"
readme = "README.md"
keywords = ["parser", "git", "log", "changelog", "journal"]
diff --git a/README.md b/README.md
index a7b8fe6..105b8f2 100644
--- a/README.md
+++ b/README.md
@@ -82,15 +82,22 @@ If you run `git journal` anywhere inside this repository, the output will be a n
- [Added] file1.txt again
- [Removed] file1.txt
+Fixes:
+#1, #2
+
# v2 (2016-09-12):
- [Added] file3.txt
+
```
All commits are sorted by time, which means that the newest elements occur at the top. The parsing of the commit message
will be done regarding [RFC0001](https://github.com/saschagrunert/git-journal/blob/master/rfc/0001-commit-msg.md), which
describes the different syntax elements within a commit message. Categories (`[Added]`, `[Fixed]`, ...) are
automatically wrapped in square brackets if available. The journal automatically lists the log from the last release and
-the unreleased entries. It is also possible to skip the unreleased entries:
+the unreleased entries.
+
+The footers of the commit messages (described in RFC0001) are automatically accumulated and printed after the changelog
+list ordered by their values. It is also possible to skip the unreleased entries:
```terminal
> git journal -u
@@ -184,6 +191,7 @@ using this template for the test repository:
name = "Section 1"
[tag1.tag2]
+footers = ["Fixes"]
```
To use such a template just use the `-t` option:
@@ -193,8 +201,16 @@ To use such a template just use the `-t` option:
[git-journal] [INFO] Skipping commit: Summary parsing: 'Merge branch 'test_branch''
[git-journal] [OKAY] Parsing done.
-# Unreleased (2016-09-18):
+# Unreleased (2016-09-20):
## default
+- [Removed] file3.txt
+- [Removed] file4.txt
+- [Removed] file5.txt
+- [Added] new .gitjournal
+- [Improved] file5.txt
+- [Fixed] this
+- [Removed] that
+- [Added] .gitjournal.toml file
- [Removed] not needed things
- [Removed] file4.txt
- [Added] file4.txt
@@ -205,9 +221,11 @@ To use such a template just use the `-t` option:
- [Added] file4 again
- This paragraph explains the change in detail
-### tag2
+## tag2
- [Fixed] multiple issues
+Fixes:
+#1, #2, #1, #2, #3, #5, #6, #7
# v2 (2016-09-12):
## default
@@ -217,8 +235,10 @@ To use such a template just use the `-t` option:
Everything which is untagged will go into the `default` section. The name of `tag1` will be mapped to `Section 1` and
`tag2` is a subtag of `tag1` (see the markdown header). This also means that it is now possible that list items are
uncategorized since the templating engine gives the possibility to split commits into multiple pieces. Parsed paragraphs
-are converted to single list items to always provide a clean markdown. The command line options like in the default
-output are available as well.
+are converted to single list items to always provide a clean markdown. The footers are specified as an toml array of
+strings which will output the selected footer keys at the correct position of the log. Please consider that the
+accumulation of the tags are related to the complete tag, not just the section where there printed. Other command line
+options like in the default output are available as well.
### Commit message preparation and verification
[prepverify]: #prepverify
@@ -307,6 +327,7 @@ repository:
* [x] Enable/Disable colored output via the command line.
* [x] Automatic wrapping of commit message categories in square brackets.
* [x] Templating support including tag and name mapping.
+ * [x] Support for accumulating footer data (also for templating engine).
* Preparation and Verification of commit messages
* [x] Automatic installation of git hooks inside the local repository.
* [x] Generation of default configuration file during setup.
@@ -316,7 +337,6 @@ repository:
## Planned features and improvements
[planned]: #planned
-* [x] Support for accumulating footer data (also for templating engine).
* [ ] Custom category support.
* [ ] Custom commit message template support, which will be used for commit preparation.
* [ ] Multiple template extensions, like custom header/footer or other different custom fields.
diff --git a/src/lib.rs b/src/lib.rs
index af52f77..1d1b437 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -642,7 +642,7 @@ mod tests {
assert_eq!(journal.config.excluded_commit_tags.len(), 0);
assert!(journal.parse_log("HEAD", "rc", &0, &true, &false).is_ok());
assert_eq!(journal.parse_result.len(), journal.tags.len() + 1);
- assert_eq!(journal.parse_result[0].commits.len(), 8);
+ assert_eq!(journal.parse_result[0].commits.len(), 11);
assert_eq!(journal.parse_result[1].commits.len(), 1);
assert_eq!(journal.parse_result[2].commits.len(), 2);
assert!(journal.print_log(false, None, Some("CHANGELOG.md")).is_ok());
diff --git a/src/parser.rs b/src/parser.rs
index 44ef6ec..3c8056b 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,10 +1,10 @@
+use chrono::{Date, UTC, Datelike};
use nom::{IResult, alpha, digit, space, rest};
use regex::{Regex, RegexBuilder};
-use chrono::{Date, UTC, Datelike};
use term;
use toml;
-use std::collections::HashMap;
+use std::collections::BTreeMap;
use std::fmt;
use std::fs::File;
use std::io::prelude::*;
@@ -14,6 +14,10 @@ use std::str;
use config::Config;
+static DEFAULT_TAG: &'static str = "default";
+static FOOTER_TAG: &'static str = "footers";
+static NAME_TAG: &'static str = "name";
+
#[derive(Debug)]
pub enum Error {
CommitMessageLength,
@@ -111,7 +115,7 @@ pub trait Print {
fn matches_default_tag(&self, tag: Option<&str>) -> bool {
match tag {
- Some(tag) => tag == "default" && self.contains_untagged_elements(),
+ Some(tag) => tag == DEFAULT_TAG && self.contains_untagged_elements(),
None => false,
}
}
@@ -211,12 +215,12 @@ impl ParsedTag {
}
trywln!(term, "");
trywln!(vec, "");
+ if !*compact && config.enable_footers {
+ try!(self.print_footers(&mut term, &mut vec, None, &config));
+ }
}
}
- if !*compact && config.enable_footers {
- try!(self.print_footers(&mut term, &mut vec, &config));
- }
Ok(())
}
@@ -231,7 +235,9 @@ impl ParsedTag {
for (tag, value) in table {
if let toml::Value::Table(ref table) = *value {
let header_lvl: String = iter::repeat('#').take(*level).collect();
- let name = match table.get("name") {
+
+ // Get the corresponding name for the section, as fallback use the tag name
+ let name = match table.get(NAME_TAG) {
Some(name_value) => name_value.as_str().unwrap_or(tag),
None => tag,
};
@@ -241,12 +247,12 @@ impl ParsedTag {
if (*compact &&
((self.commits.iter().filter(|c| c.summary.contains_tag(Some(tag))).count() > 0 &&
!config.excluded_commit_tags.contains(tag)) ||
- (tag == "default" &&
+ (tag == DEFAULT_TAG &&
self.commits.iter().filter(|c| c.summary.contains_untagged_elements()).count() > 0))) ||
(!*compact &&
((self.commits.iter().filter(|c| c.contains_tag(Some(tag))).count() > 0 &&
!config.excluded_commit_tags.contains(tag)) ||
- (tag == "default" &&
+ (tag == DEFAULT_TAG &&
self.commits.iter().filter(|c| c.contains_untagged_elements()).count() > 0))) {
@@ -272,6 +278,13 @@ impl ParsedTag {
trywln!(vec, "");
}
+ // Print footers is specified in template
+ if let Some(footers) = table.get(FOOTER_TAG) {
+ if let toml::Value::Array(ref array) = *footers {
+ try!(self.print_footers(term, vec, Some(array), config));
+ }
+ }
+
*level += 1;
try!(self.print_commits_in_table(term, vec, table, level, config, compact));
*level -= 1;
@@ -283,21 +296,63 @@ impl ParsedTag {
fn print_footers(&self,
mut term: &mut Box<term::StdoutTerminal>,
mut vec: &mut Vec<u8>,
+ footer_keys: Option<&[toml::Value]>,
config: &Config)
-> Result<(), Error> {
- let mut footer_map: HashMap<String, Vec<String>> = HashMap::new();
- for footer in self.commits.iter().flat_map(|commit| commit.footer.clone()).collect::<Vec<FooterElement>>() {
- footer_map.entry(footer.key).or_insert_with(|| vec![]).push(footer.value);
+
+ let mut footer_tree: BTreeMap<String, Vec<String>> = BTreeMap::new();
+
+ // Collect valid footer keys into one vector
+ let valid_footer_keys = match footer_keys {
+ Some(keys) => {
+ let mut vec = vec![];
+ for key in keys {
+ if let toml::Value::String(ref footer_key) = *key {
+ vec.push(footer_key.clone());
+ }
+ }
+ vec
+ }
+ None => vec![],
+ };
+
+ // Map the parsed results into a BTreeMap
+ for footer in self.commits
+ .iter()
+ .flat_map(|commit| commit.footer.clone())
+ .collect::<Vec<FooterElement>>() {
+ if valid_footer_keys.is_empty() || valid_footer_keys.contains(&footer.key) {
+ footer_tree.entry(footer.key).or_insert_with(|| vec![]).push(footer.value);
+ }
}
- for (key, values) in &footer_map {
+
+ // Sort the values by the containing strings
+ for value in footer_tree.values_mut() {
+ value.sort();
+ }
+
+ // Print the mapped footers
+ for (key, values) in &footer_tree {
if config.colored_output {
try!(term.fg(term::color::BRIGHT_RED));
}
trywln!(term, "\n{}:", key);
trywln!(vec, "\n{}:", key);
try!(term.reset());
- trywln!(term, "{}", values.join(", "));
- trywln!(vec, "{}", values.join(", "));
+ let footer_string = values.join(", ");
+ let mut char_count = 0;
+ let mut footer_lines = String::new();
+ for cur_char in footer_string.chars() {
+ if char_count > 80 && cur_char == ' ' {
+ footer_lines.push('\n');
+ char_count = 0;
+ } else {
+ footer_lines.push(cur_char);
+ char_count += 1;
+ }
+ }
+ trywln!(term, "{}", footer_lines);
+ trywln!(vec, "{}", footer_lines);
}
Ok(())
}
diff --git a/tests/template.toml b/tests/template.toml
index bbaee13..39b4997 100644
--- a/tests/template.toml
+++ b/tests/template.toml
@@ -6,3 +6,4 @@ name = "Section 1"
[tag1.subtag2]
[tag2]
+footers = ["Fixes", "Change-ID"]
diff --git a/tests/test_repo b/tests/test_repo
-Subproject 934775ec5e2bf4820228a08da227b2f1185461d
+Subproject 41c5f24580b800af6c55dcf0f3a61442e48e803