meta_commit 0.1.0.alpha → 0.2.0.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
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