rosette-core 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,27 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+
6
+ # Raises errors instead of printing or logging them.
7
+ class RaisingErrorReporter < ErrorReporter
8
+ # Raises an error.
9
+ #
10
+ # @param [Exception] error The error to raise.
11
+ # @param [Hash] options A hash of associated options.
12
+ # @return [void]
13
+ def report_error(error, options = {})
14
+ raise error
15
+ end
16
+
17
+ # Does nothing.
18
+ #
19
+ # @param [Exception] error An error, but nothing is done with it.
20
+ # @param [Hash] options A hash of associated options.
21
+ # @return [void]
22
+ def report_warning(error, options = {})
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+
6
+ # Represents a generic syntax error that probably occurred when attempting
7
+ # to parse a bit of source code or other well-defined text format.
8
+ #
9
+ # @!attribute [r] message
10
+ # @return [String] the error message.
11
+ # @!attribute [r] original_exception
12
+ # @return [Exception] the original exception, probably from a parser of
13
+ # some kind.
14
+ # @!attribute [r] language
15
+ # @return [Symbol] the language that the text the parser attempted to
16
+ # parse was in when this error was generated.
17
+ class SyntaxError < StandardError
18
+ attr_reader :message, :original_exception, :language
19
+
20
+ # Creates a new syntax error object.
21
+ #
22
+ # @param [String] msg The error message text.
23
+ # @param [Exception] original_exception The original error from the
24
+ # parser or some such.
25
+ # @param [Symbol] language The source code language.
26
+ def initialize(msg, original_exception, language)
27
+ super(msg)
28
+ @message = msg
29
+ @original_exception = original_exception
30
+ @language = language
31
+ end
32
+
33
+ # A string representation of this error which combines both the original
34
+ # message as well as the language.
35
+ #
36
+ # @return [String]
37
+ def message
38
+ "#{@message} (#{language})"
39
+ end
40
+
41
+ alias :to_s :message
42
+ end
43
+
44
+ # Represents a generic syntax error generated by one of Rosette's
45
+ # extractors. Since extractors parse source code and other
46
+ # well-defined text formats, there's always the possibility that these formats
47
+ # will contain syntax errors.
48
+ #
49
+ # @!attribute [r] original_exception
50
+ # @return [Exception] the original error from the parser or some such.
51
+ # @!attribute [r] language
52
+ # @return [Symbol] the source code language.
53
+ # @!attribute [r] file
54
+ # @return [String] the file that was being parsed when the error was
55
+ # generated.
56
+ # @!attribute [r] commit_id
57
+ # @return [String] the commit id that contained the file that was being
58
+ # parsed when the error was generated.
59
+ class ExtractionSyntaxError < StandardError
60
+ attr_reader :original_exception, :language, :file, :commit_id
61
+
62
+ # Creates a new syntax error object.
63
+ #
64
+ # @param [String] msg The error message text.
65
+ # @param [Exception] original_exception The original error from the
66
+ # parser or some such.
67
+ # @param [Symbol] language The source code language.
68
+ # @param [String] file The file that was being parsed when the error
69
+ # was generated.
70
+ # @param [String] commit_id The commit id that contained the file that
71
+ # was being parsed when the error was generated.
72
+ def initialize(msg, original_exception, language, file, commit_id)
73
+ super(msg)
74
+ @message = msg
75
+ @original_exception = original_exception
76
+ @language = language
77
+ @file = file
78
+ @commit_id = commit_id
79
+ end
80
+
81
+ # A string representation of this error which includes the original
82
+ # message, the source language, the file, and the commit id.
83
+ #
84
+ # @return [String]
85
+ def message
86
+ "#{@message}: #{original_exception.message} (#{language}) in #{file} at #{commit_id}"
87
+ end
88
+
89
+ alias :to_s :message
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+
6
+ # Represents a commit log. Commit logs track the status of individual
7
+ # commits, what time the commit occurred, and how many phrases it contains.
8
+ #
9
+ # @!attribute [rw] repo_name
10
+ # @return [String] the name of the repo the commit was found in.
11
+ # @!attribute [rw] commit_id
12
+ # @return [String] the git commit id.
13
+ # @!attribute [rw] phrase_count
14
+ # @return [Fixnum] the number of phrases found in this commit.
15
+ # @!attribute [rw] status
16
+ # @return [String] the [PhraseStatus] of this commit.
17
+ # @!attribute [rw] commit_datetime
18
+ # @return [DateTime] the time this commit was made.
19
+ # @!attribute [rw] branch_name
20
+ # @return [String] the name of the branch that contains this commit.
21
+ class CommitLog
22
+ def initialize(repo_name, commit_id, phrase_count = nil, status = nil, commit_datetime = nil, branch_name = nil)
23
+ @repo_name = repo_name
24
+ @commit_id = commit_id
25
+ @phrase_count = phrase_count
26
+ @status = status
27
+ @commit_datetime = commit_datetime
28
+ @branch_name = branch_name
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'aasm'
4
+
5
+ module Rosette
6
+ module Core
7
+
8
+ # Provides a state machine for transitioning between the possible states of
9
+ # a commit log.
10
+ module CommitLogStatus
11
+ # aasm requires all states to be symbols
12
+ Rosette::DataStores::PhraseStatus.all.each do |status|
13
+ self.const_set(status, status.to_sym)
14
+ end
15
+
16
+ def self.included(base)
17
+ base.class_eval do
18
+ include AASM
19
+
20
+ aasm do
21
+ # define states from PhraseStatus constants
22
+ Rosette::DataStores::PhraseStatus.all.each do |status|
23
+ state status.to_sym
24
+ end
25
+
26
+ attribute_name :status
27
+ initial_state NOT_SEEN
28
+
29
+ event :fetch do
30
+ transitions from: NOT_SEEN, to: FETCHED
31
+ end
32
+
33
+ event :extract do
34
+ transitions from: FETCHED, to: EXTRACTED
35
+ end
36
+
37
+ event :push do
38
+ transitions from: [EXTRACTED, PUSHED], to: PUSHED
39
+ end
40
+
41
+ event :finalize do
42
+ transitions from: [EXTRACTED, PUSHED, FINALIZED], to: FINALIZED
43
+ end
44
+
45
+ # called when jgit can't find the commit
46
+ event :missing do
47
+ transitions(
48
+ from: Rosette::DataStores::PhraseStatus.statuses,
49
+ to: MISSING
50
+ )
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,109 @@
1
+ # encoding: UTF-8
2
+
3
+ java_import 'org.eclipse.jgit.revwalk.RevWalk'
4
+
5
+ module Rosette
6
+ module Core
7
+
8
+ # Extracts phrases from a git commit. Should be thread-safe.
9
+ #
10
+ # @!attribute [r] config
11
+ # @return [Configurator] the Rosette config to use.
12
+ # @!attribute [r] error_reporter
13
+ # @return [ErrorReporter] the error reporter to report syntax
14
+ # errors, etc to.
15
+ #
16
+ # @example
17
+ # processor = CommitProcessor.new(configuration)
18
+ # processor.process_each_phrase('my_repo', 'master') do |phrase|
19
+ # puts phrase.key
20
+ # end
21
+ class CommitProcessor
22
+ attr_reader :config, :error_reporter
23
+
24
+ # Creates a new processor.
25
+ #
26
+ # @param [Configurator] config The Rosette config to use.
27
+ # @param [ErrorReporter] error_reporter The error reporter to report
28
+ # syntax errors, etc to.
29
+ def initialize(config, error_reporter = NilErrorReporter.instance)
30
+ @config = config
31
+ @error_reporter = error_reporter
32
+ end
33
+
34
+ # Extracts translatable phrases from the given ref and yields them
35
+ # sequentially to the given block. If no block is given, this method
36
+ # returns an +Enumerator+.
37
+ #
38
+ # @param [String] repo_name The name of the repository to extract
39
+ # translatable phrases from. Must be configured in +config+.
40
+ # @param [String] commit_ref The git ref or commit id to extract
41
+ # translatable phrases from.
42
+ # @raise [Java::OrgEclipseJgitErrors::MissingObjectException]
43
+ # @return [void, Enumerator] either nothing if a block is given or
44
+ # an instance of +Enumerator+ if no block is given.
45
+ # @yield [phrase] a single extracted phrase.
46
+ # @yieldparam phrase [Phrase]
47
+ def process_each_phrase(repo_name, commit_ref)
48
+ if block_given?
49
+ repo_config = config.get_repo(repo_name)
50
+ rev_walk = RevWalk.new(repo_config.repo.jgit_repo)
51
+ diff_finder = DiffFinder.new(repo_config.repo.jgit_repo, rev_walk)
52
+ commit = repo_config.repo.get_rev_commit(commit_ref, rev_walk)
53
+
54
+ diff_finder.diff_with_parents(commit).each_pair do |_, diff_entries|
55
+ diff_entries.each do |diff_entry|
56
+ if diff_entry.getNewPath != '/dev/null'
57
+ process_diff_entry(diff_entry, repo_config, commit) do |phrase|
58
+ yield phrase
59
+ end
60
+ end
61
+ end
62
+ end
63
+ else
64
+ to_enum(__method__, repo_name, commit_ref)
65
+ end
66
+ end
67
+
68
+ protected
69
+
70
+ def process_diff_entry(diff_entry, repo_config, commit)
71
+ repo_config.get_extractor_configs(diff_entry.getNewPath).each do |extractor_config|
72
+ source_code = read_object_from_entry(diff_entry, repo_config, extractor_config)
73
+ line_numbers_to_author = repo_config.repo.blame(diff_entry.getNewPath, commit.getId.name)
74
+
75
+ begin
76
+ extractor_config.extractor.extract_each_from(source_code) do |phrase, line_number|
77
+ phrase.file = diff_entry.getNewPath
78
+ phrase.commit_id = commit.getId.name
79
+
80
+ if extractor_config.extractor.supports_line_numbers?
81
+ if author_identity = line_numbers_to_author[line_number - 1]
82
+ phrase.author_name = author_identity.getName
83
+ phrase.author_email = author_identity.getEmailAddress
84
+ phrase.line_number = line_number
85
+ end
86
+ end
87
+
88
+ yield phrase
89
+ end
90
+ rescue SyntaxError => e
91
+ error_reporter.report_error(
92
+ ExtractionSyntaxError.new(
93
+ e.message, e.original_exception, e.language,
94
+ diff_entry.getNewPath, commit.getId.name
95
+ )
96
+ )
97
+ end
98
+ end
99
+ end
100
+
101
+ def read_object_from_entry(diff_entry, repo_config, extractor_config)
102
+ object_reader = repo_config.repo.jgit_repo.newObjectReader
103
+ bytes = object_reader.open(diff_entry.getNewId.toObjectId).getBytes
104
+ Java::JavaLang::String.new(bytes, extractor_config.encoding.to_s).to_s
105
+ end
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+
6
+ # Base class for extractors that extract phrases from source code,
7
+ # eg. Ruby, JavaScript, HAML, etc.
8
+ #
9
+ # @!attribute [r] config
10
+ # @return [Configurator] the Rosette config to use.
11
+ class Extractor
12
+ attr_reader :config
13
+
14
+ # Creates a new extractor.
15
+ #
16
+ # @param [Configurator] config The Rosette config to use.
17
+ def initialize(config = nil)
18
+ @config = config
19
+ end
20
+
21
+ # Extracts each translatable phrase from the given source code.
22
+ # Derived classes must implement the +#each_function_call+ method
23
+ # for this to work.
24
+ #
25
+ # @param [String] source_code The source code to extract phrases
26
+ # from.
27
+ # @return [void, Enumerator] If passed a block, this method yields
28
+ # each consecutive phrase found in +source_code+. If no block is
29
+ # passed, it returns an +Enumerator+.
30
+ # @yield [phrase] a single extracted phrase.
31
+ # @yieldparam phrase [Phrase]
32
+ def extract_each_from(source_code)
33
+ if block_given?
34
+ each_function_call(source_code) do |node, line_number|
35
+ if valid_name?(node) && valid_args?(node)
36
+ yield make_phrase(get_key(node), get_meta_key(node)), line_number
37
+ end
38
+ end
39
+ else
40
+ to_enum(__method__, source_code)
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def each_function_call(source_code)
47
+ raise NotImplementedError, "#{__method__} must be implemented by derived classes."
48
+ end
49
+
50
+ def valid_name?(node)
51
+ raise NotImplementedError, "#{__method__} must be implemented by derived classes."
52
+ end
53
+
54
+ def valid_args?(node)
55
+ raise NotImplementedError, "#{__method__} must be implemented by derived classes."
56
+ end
57
+
58
+ def get_key(node)
59
+ raise NotImplementedError, "#{__method__} must be implemented by derived classes."
60
+ end
61
+
62
+ def get_meta_key(node)
63
+ nil
64
+ end
65
+
66
+ def make_phrase(key, meta_key = nil, file = nil)
67
+ Phrase.new(key, meta_key, file)
68
+ end
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rosette
4
+ module Core
5
+
6
+ # Configuration for an extractor.
7
+ #
8
+ # @example
9
+ # ex = ExtractorConfig.new(JsonExtractor::KeyValueExtractor)
10
+ # .set_encoding(Encoding::UTF_8)
11
+ # .set_conditions do |root|
12
+ # root.match_file_extension('.json').and(
13
+ # root.match_path('config/locales')
14
+ # )
15
+ # end
16
+ #
17
+ # @!attribute [r] extractor
18
+ # @return [Extractor] the extractor instance that will be used to
19
+ # extract phrases.
20
+ # @!attribute [r] encoding
21
+ # @return [String, Encoding] the encoding to expect the contents of
22
+ # source files to be in.
23
+ # @!attribute [r] root
24
+ # @return [PathMatcherFactory::Node] the root of the
25
+ # conditions tree. Only files that are matched by the conditions in
26
+ # this tree will have their phrases extracted.
27
+ class ExtractorConfig
28
+ attr_reader :extractor_id, :extractor, :encoding, :root
29
+
30
+ # Creates a new extractor configuration.
31
+ #
32
+ # @param [String] extractor_id The extractor id of +extractor_class+.
33
+ # @param [Class] extractor_class The extractor to use.
34
+ def initialize(extractor_id, extractor_class)
35
+ @extractor_id = extractor_id
36
+ @extractor = extractor_class.new(self)
37
+ @root = PathMatcherFactory.create_root
38
+ @encoding = Rosette::Core::DEFAULT_ENCODING
39
+ end
40
+
41
+ # Sets the encoding to expect the contents of source files to be in.
42
+ #
43
+ # @param [String, Encoding] new_encoding the encoding to use.
44
+ # @return [self]
45
+ def set_encoding(new_encoding)
46
+ @encoding = new_encoding
47
+ self
48
+ end
49
+
50
+ # Determines if the given path matches all the conditions in the
51
+ # conditions tree.
52
+ #
53
+ # @param [String] path The path to match.
54
+ # @return [Boolean] true if the path matches, false otherwise.
55
+ def matches?(path)
56
+ root.matches?(path)
57
+ end
58
+
59
+ # Creates and yields a node that represents the root of a conditions
60
+ # tree. Callers should use the yielded root to build up a set of
61
+ # conditions that will be used to match paths in the repository.
62
+ # Matching paths will be processed by the extractor (i.e. their
63
+ # translatable phrases will be identified and stored).
64
+ #
65
+ # @return [self]
66
+ # @yield [root] the root of the conditions tree
67
+ # @yieldparam root [PathMatcherFactory::Node]
68
+ def set_conditions
69
+ @root = yield PathMatcherFactory.create_root
70
+ self
71
+ end
72
+ end
73
+ end
74
+ end