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.
- checksums.yaml +7 -0
- data/Gemfile +26 -0
- data/History.txt +3 -0
- data/README.md +94 -0
- data/Rakefile +18 -0
- data/lib/rosette/core.rb +110 -0
- data/lib/rosette/core/branch_utils.rb +152 -0
- data/lib/rosette/core/commands.rb +139 -0
- data/lib/rosette/core/commands/errors.rb +17 -0
- data/lib/rosette/core/commands/git/commit_command.rb +65 -0
- data/lib/rosette/core/commands/git/diff_base_command.rb +301 -0
- data/lib/rosette/core/commands/git/diff_command.rb +188 -0
- data/lib/rosette/core/commands/git/diff_entry.rb +44 -0
- data/lib/rosette/core/commands/git/fetch_command.rb +27 -0
- data/lib/rosette/core/commands/git/repo_snapshot_command.rb +40 -0
- data/lib/rosette/core/commands/git/show_command.rb +70 -0
- data/lib/rosette/core/commands/git/snapshot_command.rb +50 -0
- data/lib/rosette/core/commands/git/status_command.rb +128 -0
- data/lib/rosette/core/commands/git/with_non_merge_ref.rb +48 -0
- data/lib/rosette/core/commands/git/with_ref.rb +92 -0
- data/lib/rosette/core/commands/git/with_refs.rb +92 -0
- data/lib/rosette/core/commands/git/with_repo_name.rb +50 -0
- data/lib/rosette/core/commands/git/with_snapshots.rb +45 -0
- data/lib/rosette/core/commands/queuing/enqueue_commit_command.rb +37 -0
- data/lib/rosette/core/commands/queuing/requeue_commit_command.rb +46 -0
- data/lib/rosette/core/commands/translations/export_command.rb +257 -0
- data/lib/rosette/core/commands/translations/translation_lookup_command.rb +66 -0
- data/lib/rosette/core/commands/translations/with_locale.rb +47 -0
- data/lib/rosette/core/configurator.rb +160 -0
- data/lib/rosette/core/error_reporters/buffered_error_reporter.rb +96 -0
- data/lib/rosette/core/error_reporters/error_reporter.rb +31 -0
- data/lib/rosette/core/error_reporters/nil_error_reporter.rb +25 -0
- data/lib/rosette/core/error_reporters/printing_error_reporter.rb +58 -0
- data/lib/rosette/core/error_reporters/raising_error_reporter.rb +27 -0
- data/lib/rosette/core/errors.rb +93 -0
- data/lib/rosette/core/extractor/commit_log.rb +33 -0
- data/lib/rosette/core/extractor/commit_log_status.rb +57 -0
- data/lib/rosette/core/extractor/commit_processor.rb +109 -0
- data/lib/rosette/core/extractor/extractor.rb +72 -0
- data/lib/rosette/core/extractor/extractor_config.rb +74 -0
- data/lib/rosette/core/extractor/locale.rb +118 -0
- data/lib/rosette/core/extractor/phrase.rb +76 -0
- data/lib/rosette/core/extractor/phrase/phrase_index_policy.rb +108 -0
- data/lib/rosette/core/extractor/phrase/phrase_to_hash.rb +33 -0
- data/lib/rosette/core/extractor/repo_config.rb +339 -0
- data/lib/rosette/core/extractor/serializer_config.rb +55 -0
- data/lib/rosette/core/extractor/static_extractor.rb +44 -0
- data/lib/rosette/core/extractor/translation.rb +44 -0
- data/lib/rosette/core/extractor/translation/translation_to_hash.rb +28 -0
- data/lib/rosette/core/git/diff_finder.rb +131 -0
- data/lib/rosette/core/git/ref.rb +116 -0
- data/lib/rosette/core/git/repo.rb +378 -0
- data/lib/rosette/core/path_matcher_factory.rb +330 -0
- data/lib/rosette/core/resolvers/extractor_id.rb +37 -0
- data/lib/rosette/core/resolvers/integration_id.rb +37 -0
- data/lib/rosette/core/resolvers/preprocessor_id.rb +38 -0
- data/lib/rosette/core/resolvers/resolver.rb +115 -0
- data/lib/rosette/core/resolvers/serializer_id.rb +37 -0
- data/lib/rosette/core/snapshots/cached_head_snapshot_factory.rb +51 -0
- data/lib/rosette/core/snapshots/cached_snapshot_factory.rb +67 -0
- data/lib/rosette/core/snapshots/head_snapshot_factory.rb +58 -0
- data/lib/rosette/core/snapshots/repo_config_path_filter.rb +83 -0
- data/lib/rosette/core/snapshots/snapshot_factory.rb +184 -0
- data/lib/rosette/core/string_utils.rb +23 -0
- data/lib/rosette/core/translation_status.rb +81 -0
- data/lib/rosette/core/validators.rb +18 -0
- data/lib/rosette/core/validators/commit_validator.rb +62 -0
- data/lib/rosette/core/validators/commits_validator.rb +32 -0
- data/lib/rosette/core/validators/encoding_validator.rb +32 -0
- data/lib/rosette/core/validators/locale_validator.rb +37 -0
- data/lib/rosette/core/validators/repo_validator.rb +33 -0
- data/lib/rosette/core/validators/serializer_validator.rb +37 -0
- data/lib/rosette/core/validators/validator.rb +31 -0
- data/lib/rosette/core/version.rb +8 -0
- data/lib/rosette/data_stores.rb +11 -0
- data/lib/rosette/data_stores/errors.rb +26 -0
- data/lib/rosette/data_stores/phrase_status.rb +59 -0
- data/lib/rosette/integrations.rb +12 -0
- data/lib/rosette/integrations/errors.rb +15 -0
- data/lib/rosette/integrations/integratable.rb +58 -0
- data/lib/rosette/integrations/integration.rb +23 -0
- data/lib/rosette/preprocessors.rb +11 -0
- data/lib/rosette/preprocessors/errors.rb +14 -0
- data/lib/rosette/preprocessors/preprocessor.rb +48 -0
- data/lib/rosette/queuing.rb +14 -0
- data/lib/rosette/queuing/commits.rb +19 -0
- data/lib/rosette/queuing/commits/commit_conductor.rb +90 -0
- data/lib/rosette/queuing/commits/commit_job.rb +93 -0
- data/lib/rosette/queuing/commits/commits_queue_configurator.rb +60 -0
- data/lib/rosette/queuing/commits/extract_stage.rb +46 -0
- data/lib/rosette/queuing/commits/fetch_stage.rb +51 -0
- data/lib/rosette/queuing/commits/finalize_stage.rb +76 -0
- data/lib/rosette/queuing/commits/phrase_storage_granularity.rb +20 -0
- data/lib/rosette/queuing/commits/push_stage.rb +91 -0
- data/lib/rosette/queuing/commits/stage.rb +96 -0
- data/lib/rosette/queuing/job.rb +74 -0
- data/lib/rosette/queuing/queue.rb +28 -0
- data/lib/rosette/queuing/queue_configurator.rb +76 -0
- data/lib/rosette/queuing/worker.rb +30 -0
- data/lib/rosette/serializers.rb +10 -0
- data/lib/rosette/serializers/serializer.rb +98 -0
- data/lib/rosette/tms.rb +9 -0
- data/lib/rosette/tms/repository.rb +95 -0
- data/rosette-core.gemspec +24 -0
- data/spec/core/branch_utils_spec.rb +110 -0
- data/spec/core/commands/git/commit_command_spec.rb +60 -0
- data/spec/core/commands/git/diff_command_spec.rb +263 -0
- data/spec/core/commands/git/fetch_command_spec.rb +61 -0
- data/spec/core/commands/git/repo_snapshot_command_spec.rb +72 -0
- data/spec/core/commands/git/show_command_spec.rb +128 -0
- data/spec/core/commands/git/snapshot_command_spec.rb +86 -0
- data/spec/core/commands/git/status_command_spec.rb +154 -0
- data/spec/core/commands/queuing/enqueue_commit_command_spec.rb +34 -0
- data/spec/core/commands/queuing/requeue_commit_command_spec.rb +46 -0
- data/spec/core/commands/translations/export_command_spec.rb +113 -0
- data/spec/core/commands/translations/translation_lookup_command_spec.rb +58 -0
- data/spec/core/configurator_spec.rb +47 -0
- data/spec/core/error_reporters/buffered_error_reporter_spec.rb +61 -0
- data/spec/core/error_reporters/nil_error_reporter_spec.rb +16 -0
- data/spec/core/error_reporters/printing_error_reporter_spec.rb +60 -0
- data/spec/core/extractor/commit_log_status_spec.rb +216 -0
- data/spec/core/extractor/commit_processor_spec.rb +68 -0
- data/spec/core/extractor/extractor_config_spec.rb +47 -0
- data/spec/core/extractor/extractor_spec.rb +26 -0
- data/spec/core/extractor/locale_spec.rb +92 -0
- data/spec/core/extractor/phrase/phrase_index_policy_spec.rb +116 -0
- data/spec/core/extractor/phrase/phrase_to_hash_spec.rb +18 -0
- data/spec/core/extractor/repo_config_spec.rb +147 -0
- data/spec/core/extractor/translation/translation_to_hash_spec.rb +25 -0
- data/spec/core/git/diff_finder_spec.rb +74 -0
- data/spec/core/git/ref_spec.rb +118 -0
- data/spec/core/git/repo_spec.rb +216 -0
- data/spec/core/path_matcher_factory_spec.rb +139 -0
- data/spec/core/resolvers/extractor_id_spec.rb +47 -0
- data/spec/core/resolvers/integration_id_spec.rb +47 -0
- data/spec/core/resolvers/preprocessor_id_spec.rb +47 -0
- data/spec/core/resolvers/serializer_id_spec.rb +47 -0
- data/spec/core/snapshots/snapshot_factory_spec.rb +145 -0
- data/spec/core/string_utils_spec.rb +19 -0
- data/spec/core/translation_status_spec.rb +91 -0
- data/spec/core/validators/commit_validator_spec.rb +40 -0
- data/spec/core/validators/encoding_validator_spec.rb +30 -0
- data/spec/core/validators/locale_validator_spec.rb +31 -0
- data/spec/core/validators/repo_validator_spec.rb +30 -0
- data/spec/core/validators/serializer_validator_spec.rb +31 -0
- data/spec/integrations/integratable_spec.rb +58 -0
- data/spec/queuing/commits/commit_conductor_spec.rb +71 -0
- data/spec/queuing/commits/commit_job_spec.rb +87 -0
- data/spec/queuing/commits/extract_stage_spec.rb +68 -0
- data/spec/queuing/commits/fetch_stage_spec.rb +101 -0
- data/spec/queuing/commits/finalize_stage_spec.rb +88 -0
- data/spec/queuing/commits/push_stage_spec.rb +145 -0
- data/spec/queuing/commits/stage_spec.rb +80 -0
- data/spec/queuing/job_spec.rb +33 -0
- data/spec/queuing/queue_configurator_spec.rb +44 -0
- data/spec/spec_helper.rb +90 -0
- data/spec/test_helpers/fake_commit_stage.rb +17 -0
- 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
|