rosette-core 1.0.1

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 (158) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +26 -0
  3. data/History.txt +3 -0
  4. data/README.md +94 -0
  5. data/Rakefile +18 -0
  6. data/lib/rosette/core.rb +110 -0
  7. data/lib/rosette/core/branch_utils.rb +152 -0
  8. data/lib/rosette/core/commands.rb +139 -0
  9. data/lib/rosette/core/commands/errors.rb +17 -0
  10. data/lib/rosette/core/commands/git/commit_command.rb +65 -0
  11. data/lib/rosette/core/commands/git/diff_base_command.rb +301 -0
  12. data/lib/rosette/core/commands/git/diff_command.rb +188 -0
  13. data/lib/rosette/core/commands/git/diff_entry.rb +44 -0
  14. data/lib/rosette/core/commands/git/fetch_command.rb +27 -0
  15. data/lib/rosette/core/commands/git/repo_snapshot_command.rb +40 -0
  16. data/lib/rosette/core/commands/git/show_command.rb +70 -0
  17. data/lib/rosette/core/commands/git/snapshot_command.rb +50 -0
  18. data/lib/rosette/core/commands/git/status_command.rb +128 -0
  19. data/lib/rosette/core/commands/git/with_non_merge_ref.rb +48 -0
  20. data/lib/rosette/core/commands/git/with_ref.rb +92 -0
  21. data/lib/rosette/core/commands/git/with_refs.rb +92 -0
  22. data/lib/rosette/core/commands/git/with_repo_name.rb +50 -0
  23. data/lib/rosette/core/commands/git/with_snapshots.rb +45 -0
  24. data/lib/rosette/core/commands/queuing/enqueue_commit_command.rb +37 -0
  25. data/lib/rosette/core/commands/queuing/requeue_commit_command.rb +46 -0
  26. data/lib/rosette/core/commands/translations/export_command.rb +257 -0
  27. data/lib/rosette/core/commands/translations/translation_lookup_command.rb +66 -0
  28. data/lib/rosette/core/commands/translations/with_locale.rb +47 -0
  29. data/lib/rosette/core/configurator.rb +160 -0
  30. data/lib/rosette/core/error_reporters/buffered_error_reporter.rb +96 -0
  31. data/lib/rosette/core/error_reporters/error_reporter.rb +31 -0
  32. data/lib/rosette/core/error_reporters/nil_error_reporter.rb +25 -0
  33. data/lib/rosette/core/error_reporters/printing_error_reporter.rb +58 -0
  34. data/lib/rosette/core/error_reporters/raising_error_reporter.rb +27 -0
  35. data/lib/rosette/core/errors.rb +93 -0
  36. data/lib/rosette/core/extractor/commit_log.rb +33 -0
  37. data/lib/rosette/core/extractor/commit_log_status.rb +57 -0
  38. data/lib/rosette/core/extractor/commit_processor.rb +109 -0
  39. data/lib/rosette/core/extractor/extractor.rb +72 -0
  40. data/lib/rosette/core/extractor/extractor_config.rb +74 -0
  41. data/lib/rosette/core/extractor/locale.rb +118 -0
  42. data/lib/rosette/core/extractor/phrase.rb +76 -0
  43. data/lib/rosette/core/extractor/phrase/phrase_index_policy.rb +108 -0
  44. data/lib/rosette/core/extractor/phrase/phrase_to_hash.rb +33 -0
  45. data/lib/rosette/core/extractor/repo_config.rb +339 -0
  46. data/lib/rosette/core/extractor/serializer_config.rb +55 -0
  47. data/lib/rosette/core/extractor/static_extractor.rb +44 -0
  48. data/lib/rosette/core/extractor/translation.rb +44 -0
  49. data/lib/rosette/core/extractor/translation/translation_to_hash.rb +28 -0
  50. data/lib/rosette/core/git/diff_finder.rb +131 -0
  51. data/lib/rosette/core/git/ref.rb +116 -0
  52. data/lib/rosette/core/git/repo.rb +378 -0
  53. data/lib/rosette/core/path_matcher_factory.rb +330 -0
  54. data/lib/rosette/core/resolvers/extractor_id.rb +37 -0
  55. data/lib/rosette/core/resolvers/integration_id.rb +37 -0
  56. data/lib/rosette/core/resolvers/preprocessor_id.rb +38 -0
  57. data/lib/rosette/core/resolvers/resolver.rb +115 -0
  58. data/lib/rosette/core/resolvers/serializer_id.rb +37 -0
  59. data/lib/rosette/core/snapshots/cached_head_snapshot_factory.rb +51 -0
  60. data/lib/rosette/core/snapshots/cached_snapshot_factory.rb +67 -0
  61. data/lib/rosette/core/snapshots/head_snapshot_factory.rb +58 -0
  62. data/lib/rosette/core/snapshots/repo_config_path_filter.rb +83 -0
  63. data/lib/rosette/core/snapshots/snapshot_factory.rb +184 -0
  64. data/lib/rosette/core/string_utils.rb +23 -0
  65. data/lib/rosette/core/translation_status.rb +81 -0
  66. data/lib/rosette/core/validators.rb +18 -0
  67. data/lib/rosette/core/validators/commit_validator.rb +62 -0
  68. data/lib/rosette/core/validators/commits_validator.rb +32 -0
  69. data/lib/rosette/core/validators/encoding_validator.rb +32 -0
  70. data/lib/rosette/core/validators/locale_validator.rb +37 -0
  71. data/lib/rosette/core/validators/repo_validator.rb +33 -0
  72. data/lib/rosette/core/validators/serializer_validator.rb +37 -0
  73. data/lib/rosette/core/validators/validator.rb +31 -0
  74. data/lib/rosette/core/version.rb +8 -0
  75. data/lib/rosette/data_stores.rb +11 -0
  76. data/lib/rosette/data_stores/errors.rb +26 -0
  77. data/lib/rosette/data_stores/phrase_status.rb +59 -0
  78. data/lib/rosette/integrations.rb +12 -0
  79. data/lib/rosette/integrations/errors.rb +15 -0
  80. data/lib/rosette/integrations/integratable.rb +58 -0
  81. data/lib/rosette/integrations/integration.rb +23 -0
  82. data/lib/rosette/preprocessors.rb +11 -0
  83. data/lib/rosette/preprocessors/errors.rb +14 -0
  84. data/lib/rosette/preprocessors/preprocessor.rb +48 -0
  85. data/lib/rosette/queuing.rb +14 -0
  86. data/lib/rosette/queuing/commits.rb +19 -0
  87. data/lib/rosette/queuing/commits/commit_conductor.rb +90 -0
  88. data/lib/rosette/queuing/commits/commit_job.rb +93 -0
  89. data/lib/rosette/queuing/commits/commits_queue_configurator.rb +60 -0
  90. data/lib/rosette/queuing/commits/extract_stage.rb +46 -0
  91. data/lib/rosette/queuing/commits/fetch_stage.rb +51 -0
  92. data/lib/rosette/queuing/commits/finalize_stage.rb +76 -0
  93. data/lib/rosette/queuing/commits/phrase_storage_granularity.rb +20 -0
  94. data/lib/rosette/queuing/commits/push_stage.rb +91 -0
  95. data/lib/rosette/queuing/commits/stage.rb +96 -0
  96. data/lib/rosette/queuing/job.rb +74 -0
  97. data/lib/rosette/queuing/queue.rb +28 -0
  98. data/lib/rosette/queuing/queue_configurator.rb +76 -0
  99. data/lib/rosette/queuing/worker.rb +30 -0
  100. data/lib/rosette/serializers.rb +10 -0
  101. data/lib/rosette/serializers/serializer.rb +98 -0
  102. data/lib/rosette/tms.rb +9 -0
  103. data/lib/rosette/tms/repository.rb +95 -0
  104. data/rosette-core.gemspec +24 -0
  105. data/spec/core/branch_utils_spec.rb +110 -0
  106. data/spec/core/commands/git/commit_command_spec.rb +60 -0
  107. data/spec/core/commands/git/diff_command_spec.rb +263 -0
  108. data/spec/core/commands/git/fetch_command_spec.rb +61 -0
  109. data/spec/core/commands/git/repo_snapshot_command_spec.rb +72 -0
  110. data/spec/core/commands/git/show_command_spec.rb +128 -0
  111. data/spec/core/commands/git/snapshot_command_spec.rb +86 -0
  112. data/spec/core/commands/git/status_command_spec.rb +154 -0
  113. data/spec/core/commands/queuing/enqueue_commit_command_spec.rb +34 -0
  114. data/spec/core/commands/queuing/requeue_commit_command_spec.rb +46 -0
  115. data/spec/core/commands/translations/export_command_spec.rb +113 -0
  116. data/spec/core/commands/translations/translation_lookup_command_spec.rb +58 -0
  117. data/spec/core/configurator_spec.rb +47 -0
  118. data/spec/core/error_reporters/buffered_error_reporter_spec.rb +61 -0
  119. data/spec/core/error_reporters/nil_error_reporter_spec.rb +16 -0
  120. data/spec/core/error_reporters/printing_error_reporter_spec.rb +60 -0
  121. data/spec/core/extractor/commit_log_status_spec.rb +216 -0
  122. data/spec/core/extractor/commit_processor_spec.rb +68 -0
  123. data/spec/core/extractor/extractor_config_spec.rb +47 -0
  124. data/spec/core/extractor/extractor_spec.rb +26 -0
  125. data/spec/core/extractor/locale_spec.rb +92 -0
  126. data/spec/core/extractor/phrase/phrase_index_policy_spec.rb +116 -0
  127. data/spec/core/extractor/phrase/phrase_to_hash_spec.rb +18 -0
  128. data/spec/core/extractor/repo_config_spec.rb +147 -0
  129. data/spec/core/extractor/translation/translation_to_hash_spec.rb +25 -0
  130. data/spec/core/git/diff_finder_spec.rb +74 -0
  131. data/spec/core/git/ref_spec.rb +118 -0
  132. data/spec/core/git/repo_spec.rb +216 -0
  133. data/spec/core/path_matcher_factory_spec.rb +139 -0
  134. data/spec/core/resolvers/extractor_id_spec.rb +47 -0
  135. data/spec/core/resolvers/integration_id_spec.rb +47 -0
  136. data/spec/core/resolvers/preprocessor_id_spec.rb +47 -0
  137. data/spec/core/resolvers/serializer_id_spec.rb +47 -0
  138. data/spec/core/snapshots/snapshot_factory_spec.rb +145 -0
  139. data/spec/core/string_utils_spec.rb +19 -0
  140. data/spec/core/translation_status_spec.rb +91 -0
  141. data/spec/core/validators/commit_validator_spec.rb +40 -0
  142. data/spec/core/validators/encoding_validator_spec.rb +30 -0
  143. data/spec/core/validators/locale_validator_spec.rb +31 -0
  144. data/spec/core/validators/repo_validator_spec.rb +30 -0
  145. data/spec/core/validators/serializer_validator_spec.rb +31 -0
  146. data/spec/integrations/integratable_spec.rb +58 -0
  147. data/spec/queuing/commits/commit_conductor_spec.rb +71 -0
  148. data/spec/queuing/commits/commit_job_spec.rb +87 -0
  149. data/spec/queuing/commits/extract_stage_spec.rb +68 -0
  150. data/spec/queuing/commits/fetch_stage_spec.rb +101 -0
  151. data/spec/queuing/commits/finalize_stage_spec.rb +88 -0
  152. data/spec/queuing/commits/push_stage_spec.rb +145 -0
  153. data/spec/queuing/commits/stage_spec.rb +80 -0
  154. data/spec/queuing/job_spec.rb +33 -0
  155. data/spec/queuing/queue_configurator_spec.rb +44 -0
  156. data/spec/spec_helper.rb +90 -0
  157. data/spec/test_helpers/fake_commit_stage.rb +17 -0
  158. metadata +257 -0
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+ module Commands
6
+
7
+ # Represents an added, removed, or changed phrase.
8
+ #
9
+ # @!attribute [r] phrase
10
+ # @return [Rosette::Core::Phrase] the added/removed/modified phrase.
11
+ # @!attribute [r] state
12
+ # @return [Symbol] one of +:added+, +:removed+, or +:modified+.
13
+ # @!attribute [r] old_phrase
14
+ # @return [Rosette::Core::Phrase] +phrase+ before it was modified.
15
+ # This value is generally only set if +state+ is set to +:modified+.
16
+ class DiffEntry
17
+ attr_reader :phrase, :state, :old_phrase
18
+
19
+ # Creates a new {DiffEntry}.
20
+ #
21
+ # @param [Rosette::Core::Phrase] phrase The added/removed/modified phrase.
22
+ # @param [Symbol] state One of +:added+, +:removed+, or +:modified+.
23
+ # @param [Rosette::Core::Phrase] old_phrase +phrase+ before it was modified.
24
+ # This argument is usually only included if +state+ is +:modified+.
25
+ def initialize(phrase, state, old_phrase = nil)
26
+ @phrase = phrase
27
+ @state = state
28
+ @old_phrase = old_phrase
29
+ end
30
+
31
+ # Serializes the attributes of this entry into a hash.
32
+ #
33
+ # @return [Hash] the attributes of the phrase. If +state+ is set to +:modified+,
34
+ # the key of the old phrase is included as +:old_key+.
35
+ def to_h
36
+ phrase.to_h.tap do |hash|
37
+ hash[:old_key] = old_phrase.key if old_phrase
38
+ end
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+ module Commands
6
+
7
+ # Performs a git fetch on a repository. New branches and commits will
8
+ # be downloaded from the remote server (often called "origin") and
9
+ # become part of the local copy.
10
+ #
11
+ # @example
12
+ # FetchCommand.new(configuration)
13
+ # .set_repo_name('my_repo')
14
+ # .execute
15
+ class FetchCommand < GitCommand
16
+ include WithRepoName
17
+
18
+ # Perform the fetch operation.
19
+ # @return [Java::OrgEclipseJgitTransport::FetchResult]
20
+ def execute
21
+ get_repo(repo_name).repo.fetch
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+ module Commands
6
+
7
+ # Takes a snapshot of a repository and returns the snapshot hash. Snapshots
8
+ # are simple hashes that map file paths to git commit ids. The commit ids
9
+ # indicate in which commit the corresponding file last changed.
10
+ #
11
+ # @!attribute [Array] paths
12
+ # @return [Array] the paths to consider when taking the snapshot. Any paths
13
+ # that do not exist in this array will not appear in the snapshot.
14
+ class RepoSnapshotCommand < GitCommand
15
+ attr_reader :paths
16
+
17
+ include WithSnapshots
18
+ include WithRepoName
19
+ include WithRef
20
+
21
+ # Set the paths that will be included in the snapshot.
22
+ #
23
+ # @param [Array] paths The paths to include in the snapshot.
24
+ # @return [self]
25
+ def set_paths(paths)
26
+ @paths = paths
27
+ self
28
+ end
29
+
30
+ # Take the snapshot.
31
+ #
32
+ # @return [Hash] the snapshot hash (file path to commit id pairs).
33
+ def execute
34
+ take_snapshot(get_repo(repo_name), commit_id, paths)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: UTF-8
2
+
3
+ java_import 'org.eclipse.jgit.revwalk.RevWalk'
4
+
5
+ module Rosette
6
+ module Core
7
+ module Commands
8
+
9
+ # Show the phrases that were added, removed, or modified directly by
10
+ # the given commit. Essentially this means a diff against the parent.
11
+ #
12
+ # @example
13
+ # cmd = ShowCommand.new(configuration)
14
+ # .set_repo_name('my_repo')
15
+ # .set_ref('my_branch')
16
+ #
17
+ # cmd.execute
18
+ # # {
19
+ # # added: [
20
+ # # { key: 'Foo', ... },
21
+ # # ],
22
+ # # removed: [
23
+ # # { key: 'I got deleted', ... }
24
+ # # ],
25
+ # # modified: [
26
+ # # { key: 'New value', old_key: 'Old value', ... }
27
+ # # ]
28
+ # # }
29
+ class ShowCommand < DiffBaseCommand
30
+ include WithRepoName
31
+ include WithRef
32
+
33
+ # Computes the show (i.e. parent diff).
34
+ # @return [Hash] a hash of differences, grouped by added/removed/modified keys. Each
35
+ # value is an array of phrases. For added and removed phrases, the phrase hashes
36
+ # will contain normal phrase attributes. For changed phrases, the phrase hashes
37
+ # will contain normal phrase attributes plus a special +old_key+ attribute that
38
+ # contains the previous key of the phrase. See the example above for a visual
39
+ # representation of the diff hash.
40
+ def execute
41
+ parent_commit_ids = build_parent_commit_list
42
+ phrase_diff = diff_between(commit_id, parent_commit_ids)
43
+ filter_phrase_diff(commit_id, parent_commit_ids, phrase_diff)
44
+ end
45
+
46
+ protected
47
+
48
+ def filter_phrase_diff(commit_id, parent_commit_ids, phrase_diff)
49
+ phrase_diff.each_with_object({}) do |(state, diff_entries), ret|
50
+ ret[state] = diff_entries.select do |diff_entry|
51
+ diff_entry.phrase.commit_id == commit_id ||
52
+ diff_entry.state == :removed
53
+ end
54
+ end
55
+ end
56
+
57
+ def build_parent_commit_list
58
+ repo.parents_of(repo.get_rev_commit(commit_id)).map do |parent|
59
+ if strict?
60
+ parent.getId.name
61
+ else
62
+ get_closest_processed_parent(parent.getId.name)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+ module Commands
6
+
7
+ # Takes a snapshot and returns a list of phrases. This is different from
8
+ # {RepoSnapshotCommand} in that it doesn't return the snapshot hash itself,
9
+ # but instead the phrases contained in the snapshot's commits.
10
+ #
11
+ # @example
12
+ # cmd = SnapshotCommand.new(configuration)
13
+ # .set_repo_name('my_repo')
14
+ # .set_ref('master')
15
+ #
16
+ # cmd.execute
17
+ # # => [<Phrase #ba012cd key: 'foobar'>, ...]
18
+ #
19
+ # @!attribute [Array] paths
20
+ # @return [Array] the paths to consider when taking the snapshot. Any paths
21
+ # that do not exist in this array will not appear in the snapshot.
22
+ class SnapshotCommand < GitCommand
23
+ attr_reader :paths
24
+
25
+ include WithSnapshots
26
+ include WithRepoName
27
+ include WithRef
28
+
29
+ # Set the paths that will be included in the snapshot.
30
+ #
31
+ # @param [Array] paths The paths to include in the snapshot.
32
+ # @return [self]
33
+ def set_paths(paths)
34
+ @paths = paths
35
+ self
36
+ end
37
+
38
+ # Take the snapshot.
39
+ #
40
+ # @return [Array<Rosette::Core::Phrase>] the list of phrases from the
41
+ # snapshot.
42
+ def execute
43
+ snapshot = take_snapshot(get_repo(repo_name), commit_id, paths)
44
+ datastore.phrases_by_commits(repo_name, snapshot).to_a
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,128 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+ module Commands
6
+
7
+ # Computes the status of a git ref. Statuses contain the number of
8
+ # translations per locale as well as the state of the commit (pending,
9
+ # untranslated, or translated).
10
+ #
11
+ # @see Rosette::DataStores::PhraseStatus
12
+ #
13
+ # @example
14
+ # cmd = StatusCommand.new(configuration)
15
+ # .set_repo_name('my_repo')
16
+ # .set_ref('master')
17
+ #
18
+ # cmd.execute
19
+ # # =>
20
+ # # {
21
+ # # commit_id: "5756196042a3a307b43fd1a7092ecc6710eec42a",
22
+ # # status: "PENDING",
23
+ # # phrase_count: 100,
24
+ # # locales: [{
25
+ # # locale: 'fr-FR',
26
+ # # percent_translated: 0.5,
27
+ # # translated_count: 50
28
+ # # }, ... ]
29
+ # # }
30
+ class StatusCommand < GitCommand
31
+ include WithRepoName
32
+ include WithRef
33
+
34
+ # Computes the status for the configured repository and git ref. The
35
+ # status is computed by identifying the branch the ref belongs to, then
36
+ # examining and merging the statuses of all commits that belong to
37
+ # that branch.
38
+ #
39
+ # @see Rosette::DataStores::PhraseStatus
40
+ #
41
+ # @return [Hash] a hash of status information for the ref:
42
+ # * +commit_id+: the commit id of the ref the status came from.
43
+ # * +status+: One of +"FETCHED"+, +"EXTRACTED"+, +"PUSHED"+,
44
+ # +"FINALIZED"+, or +"NOT_FOUND"+.
45
+ # * +phrase_count+: The number of phrases found in the commit.
46
+ # * +locales+: A hash of locale codes to locale statuses having these
47
+ # entries:
48
+ # * +percent_translated+: The percentage of +phrase_count+ phrases
49
+ # that are currently translated in +locale+ for this commit.
50
+ # In other words, +translated_count+ +/+ +phrase_count+.
51
+ # * +translated_count+: The number of translated phrases in +locale+
52
+ # for this commit.
53
+ def execute
54
+ repo_config = get_repo(repo_name)
55
+ rev_walk = RevWalk.new(repo_config.repo.jgit_repo)
56
+ all_refs = repo_config.repo.all_refs.values
57
+ refs = repo_config.repo.refs_containing(
58
+ commit_id, rev_walk, all_refs
59
+ )
60
+
61
+ commit_logs = commit_logs_for(
62
+ refs.map(&:getName), repo_config, rev_walk, all_refs
63
+ )
64
+
65
+ status, phrase_count, locale_statuses = derive(
66
+ refs, commit_logs, repo_config
67
+ )
68
+
69
+ rev_walk.dispose
70
+
71
+ {
72
+ status: status,
73
+ commit_id: commit_id,
74
+ phrase_count: phrase_count,
75
+ locales: locale_statuses
76
+ }
77
+ end
78
+
79
+ protected
80
+
81
+ def derive(refs, commit_logs, repo_config)
82
+ status = derive_status(refs, commit_logs)
83
+ phrase_count = BranchUtils.derive_phrase_count_from(commit_logs)
84
+ locale_statuses = BranchUtils.derive_locale_statuses_from(
85
+ commit_logs, repo_name, datastore, phrase_count
86
+ )
87
+
88
+ [
89
+ status, phrase_count,
90
+ BranchUtils.fill_in_missing_locales(
91
+ repo_config.locales, locale_statuses
92
+ )
93
+ ]
94
+ end
95
+
96
+ def derive_status(refs, commit_logs)
97
+ if all_refs_exist?(refs)
98
+ BranchUtils.derive_status_from(commit_logs)
99
+ else
100
+ Rosette::DataStores::PhraseStatus::NOT_FOUND
101
+ end
102
+ end
103
+
104
+ def all_refs_exist?(refs)
105
+ refs.all? do |ref|
106
+ datastore.commit_log_exists?(repo_name, ref.getObjectId.name)
107
+ end
108
+ end
109
+
110
+ def commit_logs_for(branch_names, repo_config, rev_walk, all_refs)
111
+ statuses = Rosette::DataStores::PhraseStatus.incomplete
112
+ commit_logs = datastore.each_commit_log_with_status(repo_name, statuses)
113
+
114
+ commit_logs.each_with_object([]) do |commit_log, ret|
115
+ refs = repo_config.repo.refs_containing(
116
+ commit_log.commit_id, rev_walk, all_refs
117
+ )
118
+
119
+ if refs.any? { |ref| branch_names.include?(ref.getName) }
120
+ ret << commit_log
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+ module Commands
6
+
7
+ # Mixin that handles configuration and validation of a git ref or commit id.
8
+ # This module is similar to {Rosette::Core::Commands::WithRef} except that
9
+ # it will fail to validate merge refs. It is meant to be mixed into the classes
10
+ # in {Rosette::Core::Commands}. Required to be used in combination with
11
+ # {Rosette::Core::Commands::WithRepoName}.
12
+ #
13
+ # @see Rosette::Core::Commands::WithRef
14
+ # @see Rosette::Core::Commands::WithRepoName
15
+ #
16
+ # @example
17
+ # class MyCommand
18
+ # include WithRepoName
19
+ # include WithNonMergeRef
20
+ # end
21
+ #
22
+ # cmd = MyCommand.new
23
+ # .set_repo_name('my_repo')
24
+ # .set_ref('master')
25
+ #
26
+ # cmd.commit_str # => "master"
27
+ # cmd.commit_id # => "67f0e9a60dfe39430b346086f965e6c94a8ddd24"
28
+ #
29
+ # cmd.set_ref('non_existant_ref')
30
+ # cmd.valid? # => false
31
+ # cmd.messages # => { commit_str: ["Unable to find commit 'non_existent_ref'"] }
32
+ module WithNonMergeRef
33
+ include WithRef
34
+
35
+ protected
36
+
37
+ def self.included(base)
38
+ if base.respond_to?(:validate)
39
+ base.validate :commit_str, {
40
+ type: :commit, allow_merge_commit: false
41
+ }
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'thread'
4
+
5
+ module Rosette
6
+ module Core
7
+ module Commands
8
+
9
+ # Mixin that handles configuration and validation of a git ref or commit id.
10
+ # Meant to be mixed into the classes in {Rosette::Core::Commands}. Required
11
+ # to be used in combination with {Rosette::Core::Commands::WithRepoName}.
12
+ #
13
+ # @see Rosette::Core::Commands::WithNonMergeRef
14
+ # @see Rosette::Core::Commands::WithRepoName
15
+ #
16
+ # @example
17
+ # class MyCommand < Rosette::Core::Commands::Command
18
+ # include WithRepoName
19
+ # include WithRef
20
+ # end
21
+ #
22
+ # cmd = MyCommand.new
23
+ # .set_repo_name('my_repo')
24
+ # .set_ref('master')
25
+ #
26
+ # cmd.commit_str # => "master"
27
+ # cmd.commit_id # => "67f0e9a60dfe39430b346086f965e6c94a8ddd24"
28
+ # cmd.valid? # => true
29
+ #
30
+ # cmd.set_ref('non_existant_ref')
31
+ # cmd.valid? # => false
32
+ # cmd.messages # => { commit_str: ["Unable to find commit 'non_existent_ref'"] }
33
+ #
34
+ # @!attribute [r] commit_str
35
+ # @return [String] the raw value as set by either {#set_ref} or {#set_commit_id}.
36
+ module WithRef
37
+ attr_reader :commit_str
38
+
39
+ # Set the git ref (i.e. a branch name). Calling this method after {#set_commit_id}
40
+ # will overwrite the commit id value. In other words, it's generally a good idea to
41
+ # only call one of {#set_commit_id} or {#set_ref} but not both.
42
+ #
43
+ # @param [String] ref_str The git ref.
44
+ # @return [self]
45
+ def set_ref(ref_str)
46
+ @commit_str = ref_str
47
+ self
48
+ end
49
+
50
+ # Set the git commit id. Calling this method after {#set_ref} will overwrite the ref value.
51
+ # In other words, it's generally a good idea to only call one of {#set_commit_id} or {#set_ref}
52
+ # but not both.
53
+ #
54
+ # @param [String] commit_id The commit id.
55
+ # @return [self]
56
+ def set_commit_id(commit_id)
57
+ @commit_str = commit_id
58
+ self
59
+ end
60
+
61
+ # Resolves the given git ref or commit id and returns the corresponding commit id.
62
+ # If {#set_ref} was used to set a git ref (i.e. branch name), this method looks up
63
+ # and returns the corresponding commit id. If {#set_commit_id} was used to set a
64
+ # commit id, then that commit id is validated and returned.
65
+ #
66
+ # @return [String] The commit id set via either {#set_ref} or {#set_commit_id}.
67
+ # @raise [Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException]
68
+ # If either the commit id doesn't exist or the ref can't be found.
69
+ def commit_id
70
+ @commit_id ||= begin
71
+ REV_COMMIT_MUTEX.synchronize do
72
+ get_repo(repo_name)
73
+ .repo.get_rev_commit(@commit_str)
74
+ .getId.name
75
+ end
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ REV_COMMIT_MUTEX = Mutex.new
82
+
83
+ def self.included(base)
84
+ if base.respond_to?(:validate)
85
+ base.validate :commit_str, type: :commit
86
+ end
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end