meta_commit 0.1.0.alpha → 0.2.0.pre.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CONTRIBUTING.md +61 -0
  4. data/README.md +36 -5
  5. data/Rakefile +7 -1
  6. data/config/default.yml +11 -0
  7. data/exe/meta_commit +5 -1
  8. data/lib/meta_commit/changelog/adapters/changelog.rb +94 -0
  9. data/lib/meta_commit/changelog/commands/commit_diff_examiner.rb +50 -0
  10. data/lib/meta_commit/changelog/formatters/keep_a_changelog_ver_report_builder.rb +123 -0
  11. data/lib/meta_commit/cli.rb +71 -17
  12. data/lib/meta_commit/configuration.rb +45 -0
  13. data/lib/meta_commit/configuration_store.rb +27 -0
  14. data/lib/meta_commit/container.rb +80 -0
  15. data/lib/meta_commit/errors.rb +12 -0
  16. data/lib/meta_commit/factories/contextual_ast_node_factory.rb +61 -0
  17. data/lib/meta_commit/factories/diff_factory.rb +37 -0
  18. data/lib/meta_commit/factories/parser_factory.rb +30 -0
  19. data/lib/meta_commit/git/repo.rb +124 -2
  20. data/lib/meta_commit/index/adapters/git_notes.rb +34 -0
  21. data/lib/meta_commit/index/commands/diff_examiner.rb +58 -0
  22. data/lib/meta_commit/message/commands/diff_index_examiner.rb +48 -0
  23. data/lib/meta_commit/message/formatters/commit_message_builder.rb +16 -0
  24. data/lib/meta_commit/models/changes/commit.rb +24 -0
  25. data/lib/meta_commit/models/changes/repository.rb +12 -0
  26. data/lib/meta_commit/models/contextual_ast_node.rb +9 -0
  27. data/lib/meta_commit/models/diffs/diff.rb +31 -3
  28. data/lib/meta_commit/services/change_saver.rb +3 -26
  29. data/lib/meta_commit/services/parse.rb +21 -0
  30. data/lib/meta_commit/version.rb +1 -1
  31. data/lib/meta_commit.rb +34 -27
  32. data/meta_commit.gemspec +5 -0
  33. metadata +90 -23
  34. data/lib/meta_commit/adapters/dump.rb +0 -31
  35. data/lib/meta_commit/adapters/git_notes.rb +0 -28
  36. data/lib/meta_commit/models/ast_path.rb +0 -111
  37. data/lib/meta_commit/models/changes/file.rb +0 -27
  38. data/lib/meta_commit/models/diffs/addition.rb +0 -34
  39. data/lib/meta_commit/models/diffs/changes_in_method.rb +0 -14
  40. data/lib/meta_commit/models/diffs/class_creation.rb +0 -20
  41. data/lib/meta_commit/models/diffs/class_deletion.rb +0 -16
  42. data/lib/meta_commit/models/diffs/class_rename.rb +0 -11
  43. data/lib/meta_commit/models/diffs/deletion.rb +0 -37
  44. data/lib/meta_commit/models/diffs/method_creation.rb +0 -22
  45. data/lib/meta_commit/models/diffs/method_deletion.rb +0 -22
  46. data/lib/meta_commit/models/diffs/module_creation.rb +0 -14
  47. data/lib/meta_commit/models/diffs/module_deletion.rb +0 -14
  48. data/lib/meta_commit/models/diffs/module_rename.rb +0 -11
  49. data/lib/meta_commit/models/diffs/replacement.rb +0 -19
  50. data/lib/meta_commit/models/factories/ast_path_factory.rb +0 -40
  51. data/lib/meta_commit/models/factories/diff_factory.rb +0 -39
  52. data/lib/meta_commit/services/commit_message_builder.rb +0 -23
  53. data/lib/meta_commit/services/diff_examiner.rb +0 -121
  54. data/lib/meta_commit/services/diff_index_examiner.rb +0 -112
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a91401c347971a081402085e903f5f38e481dec2
4
- data.tar.gz: e3baa26014b744d0f3a0f3bf65bef1096588d6ff
3
+ metadata.gz: 2fcc0c263c146decf38b057cba6b6afb68307237
4
+ data.tar.gz: 065807ac6a1848a434c586893173a4edf3e97ab8
5
5
  SHA512:
6
- metadata.gz: e4853da029ca727831f4c6e12ce8b3daaa637ae9aed11d3a6e76f25348682a9776c15d33cade68fa3e5771ba4f08ed6199f997fdd12834825cdc5051a298a786
7
- data.tar.gz: d7321d80c6bf1377633f889d829ca7379039b019948c0931c24cf1f901b84f8402ea0a5df72e30bb7539182f3c86f6b57d8b2fefb1095de6501ba0f6dd03cd13
6
+ metadata.gz: fb11ea9ca1c203df6a264bf2e8343c003521017c0a22cc5b93a811d1f7d0515b95a2cc5134a88b9fe735359d8c9b4a16861eeab5e3fc7d02243dd8fa0a8fe81f
7
+ data.tar.gz: 4b53eb6e6a3c3d2ac0be8e556035e6e0103591692ea8e515b72c70e49a007fdac4a4ffd88fb0d92218c9f5eb8ad75ad79ae4724288d7ace91809827456099f3f
data/.travis.yml CHANGED
@@ -2,3 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - 2.2.3
4
4
  before_install: gem install bundler -v 1.10.6
5
+ script:
6
+ - rake spec
7
+ - rake features
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,61 @@
1
+ ## How to contribute to meta commit project
2
+
3
+ ### Development environment
4
+
5
+ Fork, then clone the repo:
6
+
7
+ git clone git@github.com:your-username/meta_commit.git
8
+
9
+ Set up your machine:
10
+
11
+ ./bin/setup
12
+
13
+ Make sure the tests pass:
14
+
15
+ rake
16
+
17
+ Create your feature branch
18
+
19
+ git checkout -b my-new-feature
20
+
21
+ Make your change. Add tests for your change. Make the tests pass:
22
+
23
+ rake
24
+
25
+ Push to the branch
26
+
27
+ git push origin my-new-feature
28
+
29
+ Create a new Pull Request
30
+
31
+
32
+ ### How it works
33
+
34
+ Task of meta_commit gem is to :
35
+
36
+ 1. Walk over changes presented in commit
37
+ 2. Parse content of changes using parsers from extensions
38
+ 3. Find matching diffs for parsed changes
39
+ 4. Handle diffs (print as string, save to storage or return)
40
+
41
+
42
+ ### Creating new extension
43
+
44
+ Extension is a gem that adds new parsers or diffs to core meta commit gem.
45
+
46
+ To be autoloaded by meta commit core it must follow agreements :
47
+
48
+ - Gem name matches `/^meta_commit_/` regex
49
+ - Gem has class with name `MetaCommit::Extension::#{ExtensionName}::Locator` (`ExtensionName` without `meta_commit_` prefix)
50
+ - Which returns array of parser classes on `MetaCommit::Extension::#{ExtensionName}::Locator#parsers`
51
+ - Which returns array of diff classes on `MetaCommit::Extension::#{ExtensionName}::Locator#diffs`
52
+
53
+ Meta commit uses contracts to interact with extensions, you can check this contracts [here](https://github.com/meta-commit/contracts).
54
+
55
+ To understand better how to build extension you can check [extension that adds ruby language support](https://github.com/meta-commit/ruby_support).
56
+
57
+
58
+ ---
59
+
60
+
61
+ By participating in this project, you agree to abide by the [code of conduct](https://github.com/usernam3/meta_commit/blob/master/CODE_OF_CONDUCT.md).
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
1
  # meta commit
2
+ [![Gem Version](https://badge.fury.io/rb/meta_commit.svg)](https://badge.fury.io/rb/meta_commit)
3
+ ![Travis](https://api.travis-ci.org/usernam3/meta_commit.svg?branch=master)
4
+ [![Coverage Status](https://coveralls.io/repos/github/usernam3/meta_commit/badge.svg?branch=master)](https://coveralls.io/github/usernam3/meta_commit?branch=master)
5
+ [![Inline docs](http://inch-ci.org/github/usernam3/meta_commit.svg?branch=master)](http://inch-ci.org/github/usernam3/meta_commit)
2
6
 
3
7
  > Enrich commit diffs with programing language insights
4
8
 
@@ -19,22 +23,49 @@ You can install gem with the following command in a terminal:
19
23
  $ gem install meta_commit
20
24
 
21
25
 
26
+ ## Setup
27
+
28
+ To setup ```meta_commit``` gem for your repository you need to add configuration file to root of repo.
29
+ Currently meta commit expects configuration file with name `.meta_commit.yml` of this format :
30
+
31
+ ```YAML
32
+ commands :
33
+ changelog:
34
+ adapter: file
35
+ formatter: keep_a_changelog
36
+ index:
37
+ adapter: git_notes
38
+ message:
39
+ formatter: commit_message
40
+
41
+ extensions:
42
+ - ruby_support
43
+ - extension2
44
+ - extension3
45
+ - extension4
46
+ ```
47
+
48
+ This config can be used to change gem behavior, currently it supports only `extensions` key.
49
+ Elements of `extensions` list are gem names (without `meta_commit_` prefix) that will be loaded.
50
+ [Here](https://github.com/usernam3/meta_commit/blob/master/CONTRIBUTING.md) you can get more information about how to create new extension.
51
+
52
+
22
53
  ## Usage
23
54
 
24
55
  ### Message
25
56
 
26
- ``` meta_commit message [--repo=$(pwd)] ```
57
+ meta_commit message [--repo=$(pwd)]
27
58
 
28
59
  Prints description of current changes in repository index
29
60
 
30
61
  ### Index
31
62
 
32
- ``` meta_commit index [--branch=master] [--repo=$(pwd)] ```
63
+ meta_commit index [--repo=$(pwd)]
33
64
 
34
65
  Walks over repository commits and writes meta information to git notes
35
66
 
36
- ### Changelog (NOT IMPLEMENTED)
67
+ ### Changelog
37
68
 
38
- ``` meta_commit changelog [--from] [--to] [--repo=$(pwd)] ```
69
+ meta_commit changelog [--from-tag] [--to-tag] [--directory=$(pwd)] [--filename='CHANGELOG.md']
39
70
 
40
- Walks over commits between tags ``` from ``` and ``` to ``` and writes main changes to changelog.md
71
+ Walks over commits between tags ``` from ``` and ``` to ``` and writes changes to changelog file
data/Rakefile CHANGED
@@ -1,6 +1,12 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "rubygems"
4
+ require "cucumber"
5
+ require "cucumber/rake/task"
3
6
 
4
7
  RSpec::Core::RakeTask.new(:spec)
8
+ Cucumber::Rake::Task.new(:features) do |t|
9
+ t.cucumber_opts = "features --format pretty"
10
+ end
5
11
 
6
- task :default => :spec
12
+ task :default => [:spec, :features]
@@ -0,0 +1,11 @@
1
+ commands :
2
+ changelog:
3
+ adapter: file
4
+ formatter: keep_a_changelog
5
+ index:
6
+ adapter: git_notes
7
+ message:
8
+ formatter: commit_message
9
+
10
+ extensions:
11
+ - builtin
data/exe/meta_commit CHANGED
@@ -2,4 +2,8 @@
2
2
 
3
3
  require 'meta_commit'
4
4
 
5
- MetaCommit::ApplicationInterface.start( ARGV )
5
+ begin
6
+ MetaCommit::ApplicationInterface.start( ARGV )
7
+ rescue MetaCommit::Errors::MissingRepoError => e
8
+ Thor.new.say(e.message)
9
+ end
@@ -0,0 +1,94 @@
1
+ module MetaCommit::Changelog
2
+ module Adapters
3
+ # Adapter class to write repository changes to changelog file
4
+ class Changelog
5
+ VERSION_DELIMITER="\n\n\n"
6
+ VERSION_HEADER_REGEX = /(## \[.*?\] - \d{4}-\d{2}-\d{2})/m
7
+
8
+ attr_accessor :path, :filename, :tag, :date
9
+
10
+ # @param [String] path
11
+ # @param [String] filename
12
+ # @param [String] tag version
13
+ # @param [String] date of version release
14
+ def initialize(path, filename, tag, date)
15
+ @path=path
16
+ @filename=filename
17
+ @tag=tag
18
+ @date=date
19
+ end
20
+
21
+ # Builds changelog message and adds it after description text and before latest version
22
+ # @param repo
23
+ # @param [Array<MetaCommit::Models::Diffs::Diff>] diffs
24
+ # @return [String]
25
+ def write_repository_change_chunk(repo, diffs)
26
+ message_builder = changelog_message_builder(@tag, @date)
27
+ diffs.each do |diff|
28
+ message_builder.add_to_added(diff.string_representation) if diff.type_addition?
29
+ message_builder.add_to_removed(diff.string_representation) if diff.type_deletion?
30
+ message_builder.add_to_changed(diff.string_representation) if diff.type_replace?
31
+ end
32
+ prepend_to_changelog(message_builder.build)
33
+ end
34
+
35
+ # @return [String] path to changelog file
36
+ def changelog_path
37
+ File.join(@path, @filename)
38
+ end
39
+
40
+ private :changelog_path
41
+
42
+ # @param [String] version
43
+ # @param [String] date
44
+ # @return [MetaCommit::Services::KeepAChangelogVerReportBuilder]
45
+ def changelog_message_builder(version, date)
46
+ MetaCommit::Changelog::Formatters::KeepAChangelogVerReportBuilder.new(version, date)
47
+ end
48
+
49
+ private :changelog_message_builder
50
+
51
+ # @param [String] text
52
+ # @return [String]
53
+ def prepend_to_changelog(text)
54
+ current_changelog_content = read_from_changelog
55
+ current_changelog_parts = current_changelog_content.split(VERSION_HEADER_REGEX)
56
+
57
+ if starts_with_description(current_changelog_parts)
58
+ new_changelog_parts = [current_changelog_parts[0]] + [text, "#{VERSION_DELIMITER}"] + current_changelog_parts[1..-1]
59
+ else
60
+ new_changelog_parts = [text, "#{VERSION_DELIMITER}"] + current_changelog_parts
61
+ end
62
+
63
+ write_to_changelog(new_changelog_parts.join)
64
+ end
65
+
66
+ private :prepend_to_changelog
67
+
68
+ # @return [String] changelog file content
69
+ def read_from_changelog
70
+ File.read(changelog_path)
71
+ end
72
+
73
+ private :read_from_changelog
74
+
75
+ # @param [String] text content to write to changelog file
76
+ # @return [String]
77
+ def write_to_changelog(text)
78
+ File.open(changelog_path, 'w').write(text)
79
+ text
80
+ end
81
+
82
+ private :write_to_changelog
83
+
84
+ # @param [Array<String>] changelog_parts content sections from changelog
85
+ # @return [Boolean]
86
+ def starts_with_description(changelog_parts)
87
+ return false if changelog_parts.empty?
88
+ changelog_parts[0].match(VERSION_HEADER_REGEX).nil?
89
+ end
90
+
91
+ private :starts_with_description
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,50 @@
1
+ module MetaCommit::Changelog
2
+ module Commands
3
+ class CommitDiffExaminer
4
+ # @param [MetaCommit::Services::Parse] parse_command
5
+ # @param [MetaCommit::Factories::ContextualAstNodeFactory] ast_path_factory
6
+ # @param [MetaCommit::Factories::DiffFactory] diff_factory
7
+ def initialize(parse_command, ast_path_factory, diff_factory)
8
+ @parse_command = parse_command
9
+ @ast_path_factory = ast_path_factory
10
+ @diff_factory = diff_factory
11
+ end
12
+
13
+
14
+ # Creates diff objects with meta information of changes between left and right commit
15
+ # @param [MetaCommit::Git::Repo] repo
16
+ # @param [String] left_commit commit id
17
+ # @param [String] right_commit commit id
18
+ # @return [Array<MetaCommit::Models::Diffs::Diff>]
19
+ def meta(repo, left_commit, right_commit)
20
+ diffs = []
21
+ commit_id_old = left_commit.oid
22
+ commit_id_new = right_commit.oid
23
+ repo.diff_with_optimized_lines(left_commit, right_commit) do |old_file_path, new_file_path, patch, line|
24
+ old_file_content = repo.get_blob_at(commit_id_old, old_file_path, '')
25
+ new_file_content = repo.get_blob_at(commit_id_new, new_file_path, '')
26
+
27
+ old_file_ast = @parse_command.execute(old_file_path, old_file_content)
28
+ next if old_file_ast.nil?
29
+ new_file_ast = @parse_command.execute(new_file_path, new_file_content)
30
+ next if new_file_ast.nil?
31
+
32
+ old_ast_path = @ast_path_factory.create_ast_path(old_file_ast, line.old_lineno)
33
+ new_ast_path = @ast_path_factory.create_ast_path(new_file_ast, line.new_lineno)
34
+
35
+ created_diff = @diff_factory.create_diff_of_type(line.line_origin, {
36
+ :line => line,
37
+ :commit_id_old => commit_id_old,
38
+ :commit_id_new => commit_id_new,
39
+ :old_ast_path => old_ast_path,
40
+ :new_ast_path => new_ast_path,
41
+ :old_file_path => old_file_path,
42
+ :new_file_path => new_file_path,
43
+ })
44
+ diffs.push(created_diff) unless created_diff.nil?
45
+ end
46
+ diffs
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,123 @@
1
+ module MetaCommit::Changelog
2
+ module Formatters
3
+ # Class builds messages with release changes according to [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) specification
4
+ # @attr [String] version
5
+ # @attr [String] date
6
+ # @attr [Array<String>] added_changes Changes from "Added" section
7
+ # @attr [Array<String>] changed_changes Changes from "Changed" section
8
+ # @attr [Array<String>] deprecated_changes Changes from "Deprecated" section
9
+ # @attr [Array<String>] removed_changes Changes from "Removed" section
10
+ # @attr [Array<String>] fixed_changes Changes from "Fixed" section
11
+ # @attr [Array<String>] security_changes Changes from "Security" section
12
+ class KeepAChangelogVerReportBuilder
13
+ # attr_reader :version, :date
14
+ attr_reader :added_changes, :changed_changes, :deprecated_changes, :removed_changes, :fixed_changes, :security_changes
15
+
16
+ def initialize(version, date)
17
+ @version=version
18
+ @date=date
19
+ @added_changes, @changed_changes, @deprecated_changes, @removed_changes, @fixed_changes, @security_changes = [], [], [], [], [], []
20
+ end
21
+
22
+ # @param [String] change
23
+ def add_to_added(change)
24
+ @added_changes.push(change)
25
+ end
26
+
27
+ # @param [String] change
28
+ def add_to_changed(change)
29
+ @changed_changes.push(change)
30
+ end
31
+
32
+ # @param [String] change
33
+ def add_to_deprecated(change)
34
+ @deprecated_changes.push(change)
35
+ end
36
+
37
+ # @param [String] change
38
+ def add_to_removed(change)
39
+ @removed_changes.push(change)
40
+ end
41
+
42
+ # @param [String] change
43
+ def add_to_fixed(change)
44
+ @fixed_changes.push(change)
45
+ end
46
+
47
+ # @param [String] change
48
+ def add_to_security(change)
49
+ @security_changes.push(change)
50
+ end
51
+
52
+ # @return [String] Version header
53
+ def version_entry
54
+ "## [#{@version}] - #{@date}"
55
+ end
56
+
57
+ private :version_entry
58
+
59
+ # @return [String] List of changes with type header
60
+ def changes_group_entry(type, changes)
61
+ header = ["### #{type}"]
62
+ list = changes.map { |change| "- #{change}" }
63
+ ([header] + list).join("\n")
64
+ end
65
+
66
+ private :changes_group_entry
67
+
68
+ # @return [String] List of added changes with header
69
+ def added_changes_group_entry
70
+ changes_group_entry('Added', @added_changes)
71
+ end
72
+
73
+ private :added_changes_group_entry
74
+
75
+ # @return [String] List of changed changes with header
76
+ def changed_changes_group_entry
77
+ changes_group_entry('Changed', @changed_changes)
78
+ end
79
+
80
+ private :changed_changes_group_entry
81
+
82
+ # @return [String] List of deprecated changes with header
83
+ def deprecated_changes_group_entry
84
+ changes_group_entry('Deprecated', @deprecated_changes)
85
+ end
86
+
87
+ private :deprecated_changes_group_entry
88
+
89
+ # @return [String] List of removed changes with header
90
+ def removed_changes_group_entry
91
+ changes_group_entry('Removed', @removed_changes)
92
+ end
93
+
94
+ private :removed_changes_group_entry
95
+
96
+ # @return [String] List of fixed changes with header
97
+ def fixed_changes_group_entry
98
+ changes_group_entry('Fixed', @fixed_changes)
99
+ end
100
+
101
+ private :fixed_changes_group_entry
102
+
103
+ # @return [String] List of security changes with header
104
+ def security_changes_group_entry
105
+ changes_group_entry('Security', @security_changes)
106
+ end
107
+
108
+ private :security_changes_group_entry
109
+
110
+ # @return [String] Report with version changes
111
+ def build
112
+ result = [version_entry]
113
+ result += [added_changes_group_entry] unless @added_changes.empty?
114
+ result += [changed_changes_group_entry] unless @changed_changes.empty?
115
+ result += [deprecated_changes_group_entry] unless @deprecated_changes.empty?
116
+ result += [removed_changes_group_entry] unless @removed_changes.empty?
117
+ result += [fixed_changes_group_entry] unless @fixed_changes.empty?
118
+ result += [security_changes_group_entry] unless @security_changes.empty?
119
+ result.join("\n")
120
+ end
121
+ end
122
+ end
123
+ end
@@ -2,31 +2,85 @@ require 'thor'
2
2
 
3
3
  module MetaCommit
4
4
  class ApplicationInterface < Thor
5
- desc 'message [DIRECTORY]', 'generate message with summary of changes in repo located at DIRECTORY (or current directory if argument not passed)'
6
- def message(repository_path=nil)
7
- repository_path ||= Dir.pwd
5
+
6
+ desc 'message', 'generate message with summary of changes in repo located at DIRECTORY (or current directory if argument not passed)'
7
+ option :directory, :type => :string, :default => Dir.pwd
8
+
9
+ def message
10
+ repository_path = options[:directory]
8
11
  repository = MetaCommit::Git::Repo.new(repository_path)
9
- examiner = MetaCommit::Services::DiffIndexExaminer.new(repository)
10
- meta = examiner.index_meta
11
- message_builder = MetaCommit::Services::CommitMessageBuilder.new(repository)
12
- message = message_builder.build(meta)
13
- say(message)
12
+ container = boot_container_with_config(File.join(repository_path, MetaCommit::ConfigurationStore::META_COMMIT_CONFIG_FILENAME))
13
+
14
+ examiner = MetaCommit::Message::Commands::DiffIndexExaminer.new(
15
+ container.resolve(:parse_command),
16
+ container.resolve(:contextual_ast_node_factory),
17
+ container.resolve(:diff_factory)
18
+ )
19
+
20
+ meta = examiner.index_meta(repository)
21
+
22
+ say(MetaCommit::Message::Formatters::CommitMessageBuilder.new.build(meta))
14
23
  end
15
24
 
16
- desc 'changelog', 'IS NOT IMPLEMENTED'
17
- def changelog(path=nil)
18
- raise('IS NOT IMPLEMENTED')
25
+ desc 'changelog [FROM_TAG] [TO_TAG]', 'writes all changes between git tags to changelog file'
26
+ option :directory, :type => :string, :default => Dir.pwd
27
+ option :filename, :type => :string, :default => 'CHANGELOG.md', :desc => 'Filename of changelog'
28
+
29
+ def changelog(from_tag=nil, to_tag=nil)
30
+ repository_path = options[:directory]
31
+ filename = options[:filename]
32
+ repository = MetaCommit::Git::Repo.new(repository_path)
33
+ from_tag_commit = repository.commit_of_tag(from_tag)
34
+ to_tag_commit = repository.commit_of_tag(to_tag)
35
+ container = boot_container_with_config(File.join(repository_path, MetaCommit::ConfigurationStore::META_COMMIT_CONFIG_FILENAME))
36
+
37
+ examiner = MetaCommit::Changelog::Commands::CommitDiffExaminer.new(
38
+ container.resolve(:parse_command),
39
+ container.resolve(:contextual_ast_node_factory),
40
+ container.resolve(:diff_factory)
41
+ )
42
+
43
+ meta = examiner.meta(repository, from_tag_commit, to_tag_commit)
44
+
45
+ adapter = MetaCommit::Changelog::Adapters::Changelog.new(repository.dir, filename, to_tag, to_tag_commit.time.strftime('%Y-%m-%d'))
46
+ change_saver = MetaCommit::Services::ChangeSaver.new(repository, adapter)
47
+ change_saver.store_meta(meta)
48
+ say("added version [#{to_tag}] to #{filename}")
19
49
  end
20
50
 
21
- desc 'index [DIRECTORY]', 'indexing repository located at DIRECTORY (or current directory if argument not passed)'
22
- def index(repository_path=nil)
23
- repository_path ||= Dir.pwd
51
+ desc 'index', 'indexing repository'
52
+ option :directory, :type => :string, :default => Dir.pwd
53
+
54
+ def index
55
+ repository_path = options[:directory]
24
56
  repository = MetaCommit::Git::Repo.new(repository_path)
25
- examiner = MetaCommit::Services::DiffExaminer.new(repository)
26
- meta = examiner.meta
27
- change_saver = MetaCommit::Services::ChangeSaver.new(repository)
57
+ container = boot_container_with_config(File.join(repository_path, MetaCommit::ConfigurationStore::META_COMMIT_CONFIG_FILENAME))
58
+
59
+ examiner = MetaCommit::Index::Commands::DiffExaminer.new(
60
+ container.resolve(:parse_command),
61
+ container.resolve(:contextual_ast_node_factory),
62
+ container.resolve(:diff_factory)
63
+ )
64
+
65
+ meta = examiner.meta(repository)
66
+
67
+ adapter = MetaCommit::Index::Adapters::GitNotes.new(repository.path)
68
+ change_saver = MetaCommit::Services::ChangeSaver.new(repository, adapter)
28
69
  change_saver.store_meta(meta)
29
70
  say('repository successfully indexed')
30
71
  end
72
+
73
+ no_commands do
74
+ # @param [String] configuration_path
75
+ # @return [MetaCommit::Container]
76
+ def boot_container_with_config(configuration_path)
77
+ default_configuration = MetaCommit::Configuration.new.fill_from_yaml_file(MetaCommit::ConfigurationStore::DEFAULT_FILE)
78
+ configuration_store = MetaCommit::ConfigurationStore.new(default_configuration)
79
+ configuration_store.merge(MetaCommit::Configuration.new.fill_from_yaml_file(configuration_path)) if File.exist?(configuration_path)
80
+
81
+ container = MetaCommit::Container.new
82
+ container.boot(configuration_store)
83
+ end
84
+ end
31
85
  end
32
86
  end
@@ -0,0 +1,45 @@
1
+ require 'yaml'
2
+ module MetaCommit
3
+ class Configuration < Hash
4
+ # Set the configuration key
5
+ # @param key [Symbol] configuration key
6
+ # @param value [Object] configuration value
7
+ def set(key, value)
8
+ self[key] = value
9
+ end
10
+
11
+ # Get the configuration value by key
12
+ # @param key [Symbol] configuration key
13
+ # @return [Object] configuration value
14
+ def get(key)
15
+ self[key]
16
+ end
17
+
18
+ # Fill config values from yaml file
19
+ # @param [Hash] hash
20
+ # @return [MetaCommit::Configuration]
21
+ def fill_from_hash(hash)
22
+ hash.each {|key, value| set(key.to_sym, value)}
23
+ self
24
+ end
25
+
26
+ # Fill config values from yaml file
27
+ # @param [String] path
28
+ # @return [MetaCommit::Configuration]
29
+ def fill_from_yaml_file(path)
30
+ fill_from_hash read_from_yaml(path)
31
+ end
32
+
33
+ # @param [String] path
34
+ # @return [Hash]
35
+ def read_from_yaml(path)
36
+ begin
37
+ YAML::load_file(path)
38
+ rescue Errno::ENOENT => e
39
+ raise MetaCommit::Errors::MissingConfigError
40
+ end
41
+ end
42
+
43
+ protected :read_from_yaml
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ module MetaCommit
2
+ #
3
+ # @attr [MetaCommit::Configuration] configuration
4
+ class ConfigurationStore
5
+ META_COMMIT_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
6
+ DEFAULT_FILE = File.join(META_COMMIT_HOME, 'config', 'default.yml')
7
+ META_COMMIT_CONFIG_FILENAME = '.meta_commit.yml'
8
+
9
+ # @param [MetaCommit::Configuration] configuration
10
+ def initialize(configuration)
11
+ @configuration = configuration
12
+ end
13
+
14
+ # Merges passed configuration with @configuration
15
+ # @param [MetaCommit::Configuration] configuration
16
+ # @return [MetaCommit::ConfigurationStore]
17
+ def merge(configuration)
18
+ @configuration.merge!(configuration)
19
+ end
20
+
21
+ # @param [Symbol] key
22
+ # @return [Object]
23
+ def get(key)
24
+ @configuration.get(key)
25
+ end
26
+ end
27
+ end