yamlt 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 31ebdd1c019feb3155c4ea520ec2c81c6f7fc0a0
4
+ data.tar.gz: 51d7d3b140f9394a13786e6fda384181d268877d
5
+ SHA512:
6
+ metadata.gz: bbe927ff3463528669f4f6d57c4fd3bf6f66a37bde301b902079410d3d77c08f6e6b78fbfce3f924d229b71c1ef34df715fc95bd38e31149bdafe647a472323f
7
+ data.tar.gz: f074c43f9fbf5c9b0a60a290a91a4c995a99bf46afb5d9918a1dfc094c3ce0fd9184da2eccb4b38019cfa6d01e888f3008aafd4850a4117e548aae382048ece3
@@ -0,0 +1,33 @@
1
+ # ------------------------------------------------------------------------------
2
+ # @class: Yamlt::Checker::Reporter
3
+ # @description: Default checker reporter
4
+ # ------------------------------------------------------------------------------
5
+
6
+ module Yamlt
7
+ class Checker
8
+ class Reporter
9
+ def absent(key, old_value)
10
+ print " * Key is absent: #{key}, old_value: "
11
+ puts_value(old_value)
12
+ end
13
+
14
+ def unchanged(key, old_value)
15
+ puts " * Key is unchanged: #{key}, old_value: "
16
+ puts_value(old_value)
17
+ end
18
+
19
+ private
20
+
21
+ def puts_value(value)
22
+ if value.include?($/)
23
+ lines = value.split($/)
24
+ max_length = lines.map(&:length).max
25
+ puts $/ + value.split($/).map{|s|" | #{s}"} * $/
26
+ puts " `-" + "-" * max_length
27
+ else
28
+ puts value
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,58 @@
1
+ # ------------------------------------------------------------------------------
2
+ # @class: Yamlt::Checker
3
+ # @description: Makes a diff between two yaml files
4
+ # ------------------------------------------------------------------------------
5
+ require "yamlt/parser"
6
+ require "yamlt/loader"
7
+ require "yamlt/checker/reporter"
8
+
9
+ module Yamlt
10
+ class Checker
11
+ def initialize(source, target, reporter = Yamlt::Checker::Reporter.new)
12
+ @source = source
13
+ @target = target
14
+ @reporter = reporter
15
+ end
16
+
17
+ def call
18
+ check
19
+ end
20
+
21
+ def self.call(source, target, reporter)
22
+ new(source, target, reporter).()
23
+ end
24
+
25
+ private
26
+
27
+ def state
28
+ @state ||=
29
+ if @source.is_a?(String)
30
+ Yamlt::Parser.new(@source).parse
31
+ else
32
+ @source
33
+ end
34
+ end
35
+
36
+ def loader
37
+ @loader ||=
38
+ if @target.is_a?(String)
39
+ Yamlt::Loader.new(@target)
40
+ else
41
+ @target
42
+ end
43
+ end
44
+
45
+ def check
46
+ state.values.keys.each do |key|
47
+ source_value = state.values[key]
48
+ target_value = loader[key]
49
+
50
+ if target_value.nil?
51
+ @reporter.absent(key, source_value)
52
+ elsif target_value == source_value
53
+ @reporter.unchanged(key, source_value)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,15 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+
6
+ module Yamlt
7
+ class LanguagePair
8
+ def initialize(from: "en", to: "ru")
9
+ @from = from
10
+ @to = to
11
+ end
12
+
13
+ attr_reader :from, :to
14
+ end
15
+ end
@@ -0,0 +1,61 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
6
+ require "yaml"
7
+
8
+ module Yamlt
9
+ class Loader
10
+ def initialize(filepath)
11
+ @filepath = filepath
12
+ @loaded = false
13
+ end
14
+
15
+ def [](key)
16
+ path = path0(key)
17
+ value = values
18
+ path.each do |fragment|
19
+ value = value[fragment]
20
+ return nil unless value
21
+ end
22
+ value
23
+ end
24
+
25
+ def language
26
+ @locale ||=
27
+ begin
28
+ values.keys.first || @filepath[/(\w+)\.yml$/, 1]
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def path0(key)
35
+ keys = values.keys
36
+
37
+ raise Yamlt::LoaderException "Locale file should have only one root key" if keys.size != 1
38
+
39
+ key.split(".").tap do |path|
40
+ path[0] = keys.first
41
+ end
42
+ end
43
+
44
+ def values
45
+ @values ||= (load unless @loaded)
46
+ end
47
+
48
+ def load
49
+ begin
50
+ @values = YAML.load_file(@filepath)
51
+ rescue Errno::ENOENT => noent
52
+ @values = {}
53
+ end
54
+
55
+ @loaded = true
56
+ @values
57
+ end
58
+ end
59
+
60
+ class LoaderException < ::StandardError; end
61
+ end
@@ -0,0 +1,74 @@
1
+ module Yamlt
2
+ class Parser
3
+ class Line
4
+ class Serializer
5
+ def initialize(line, overrides = {})
6
+ @line = line
7
+ @overrides = overrides
8
+ end
9
+
10
+ def to_s
11
+ [ level_string,
12
+ fragment_string,
13
+ prefix_string,
14
+ value_string,
15
+ comment
16
+ ].join("")
17
+ end
18
+
19
+ private
20
+
21
+ def level_string
22
+ if @line.level
23
+ indent(@line.level)
24
+ end.to_s
25
+ end
26
+
27
+ def indent(lvl)
28
+ " " * lvl
29
+ end
30
+
31
+ def fragment_string
32
+ if fragment
33
+ "#{fragment}:"
34
+ end.to_s
35
+ end
36
+
37
+ def fragment
38
+ @overrides[:fragment] || @line.fragment
39
+ end
40
+
41
+ def comment
42
+ if @line.comment
43
+ "##{@line.comment}"
44
+ end.to_s
45
+ end
46
+
47
+ def prefix_string
48
+ @line.prefix.to_s
49
+ end
50
+
51
+ def value_string
52
+ if @line.fragment && value
53
+ if value.include?($/)
54
+ "|\n" +
55
+ value.split($/).map do |value_part|
56
+ "#{indent(@line.level + 1)}\"#{escaped(value_part)}\""
57
+ end.join($/)
58
+ else
59
+ "\"#{escaped(value)}\""
60
+ end
61
+ end.to_s
62
+ end
63
+
64
+ def value
65
+ @overrides[:value] || @line.value
66
+ end
67
+
68
+ def escaped(string)
69
+ string.gsub(/\"/, "\\\"")
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,67 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
6
+ require "yamlt/parser/line/serializer"
7
+
8
+ module Yamlt
9
+ class Parser
10
+ class Line
11
+ def initialize(text)
12
+ @text = text
13
+ parse
14
+ end
15
+
16
+ attr_reader :comment, :prefix, :fragment, :level, :multiline
17
+ attr_accessor :full_path, :value
18
+
19
+ def as_text(opts={})
20
+ serializer = Serializer.new(self, opts)
21
+ serializer.to_s
22
+ end
23
+
24
+ def empty?
25
+ !@fragment && !@value
26
+ end
27
+
28
+ private
29
+
30
+ def parse
31
+ case @text
32
+ when /^\s*$/
33
+ # do nothing
34
+ when /^(\s*)#(.*)$/; @comment = $~[2]; @prefix = $~[1]
35
+ when /^(\s*)(\w+):(\s*)(#(.*))?$/
36
+ if $~[1].length % 2 == 0
37
+ @fragment = $~[2]
38
+ @level = $~[1].length / 2
39
+ @prefix = $~[3]
40
+ @comment = $~[5]
41
+ end
42
+ when /^(\s*)(\w+):(\s*)([\'\"])(.*)\4/
43
+ if $~[1].length % 2 == 0
44
+ @fragment = $~[2]
45
+ @level = $~[1].length / 2
46
+ @prefix = $~[3]
47
+ @value = $~[5]
48
+ end
49
+ when /^(\s*)(\w+):(\s*)\|(\s*)$/
50
+ if $~[1].length % 2 == 0
51
+ @fragment = $~[2]
52
+ @level = $~[1].length / 2
53
+ @prefix = $~[3] || $~[4]
54
+ @multiline = true
55
+ end
56
+
57
+ when /^(\s*)([\'\"]?)(.*)\2\s*$/
58
+ if $~[1].length % 2 == 0
59
+ @level = $~[1].length / 2
60
+ @value = $~[3]
61
+ @multiline = true
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,87 @@
1
+ module Yamlt
2
+ class Parser
3
+ class State
4
+ def initialize
5
+ @path = []
6
+ @level = 0
7
+ @multiline = []
8
+ @line = nil
9
+
10
+ @lines = []
11
+ @values = {}
12
+
13
+ @languate = nil
14
+ end
15
+
16
+ attr_reader :path, :level, :multiline, :line, :lines, :values, :language
17
+
18
+ def apply(line)
19
+ pass_through(line) if line.empty?
20
+ apply_fragment(line) if line.fragment
21
+ apply_value(line) if !line.fragment && line.value
22
+ end
23
+
24
+ def flush
25
+ if @line && @line.multiline && !@multiline.empty?
26
+ add_value
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def pass_through(line)
33
+ @lines.push(line)
34
+ end
35
+
36
+ def apply_fragment(line)
37
+ if line.level > @level
38
+ raise StateException, "Path fragment level is too high\n#{line.as_text}"
39
+ elsif line.level < @level
40
+ if !@multiline.empty? && @line
41
+ add_value
42
+ end
43
+ end
44
+
45
+ if line.level == 0 && line.fragment
46
+ @language ||= line.fragment
47
+ end
48
+
49
+ @path = @path[0, line.level]
50
+ @path.push(line.fragment)
51
+ @level = line.level + 1
52
+
53
+ @lines.push(line)
54
+
55
+ if line.value
56
+ full_path = @path.join(".")
57
+ line.full_path = full_path
58
+ @values[full_path] = line.value
59
+ end
60
+
61
+ if line.multiline
62
+ @line = line
63
+ @multiline = []
64
+ end
65
+ end
66
+
67
+ def apply_value(line)
68
+ if line.level != @level
69
+ raise Yamlt::Parser::StateException, "Wrong identation in multiline value\n#{line.as_text}"
70
+ end
71
+ @multiline.push(line.value)
72
+ end
73
+
74
+ def add_value
75
+ full_path = @path.join(".")
76
+ value = @multiline.join($/)
77
+ @values[full_path] = value
78
+ @line.full_path = full_path
79
+ @line.value = value
80
+ @multiline = []
81
+ @line = nil
82
+ end
83
+ end
84
+
85
+ class StateException < ::StandardError; end
86
+ end
87
+ end
@@ -0,0 +1,38 @@
1
+ # ------------------------------------------------------------------------------
2
+ # @class: Yamlt::Parser
3
+ # @description: Parse yaml file structure and store it into state object
4
+ # ------------------------------------------------------------------------------
5
+ require "yamlt/parser/line"
6
+ require "yamlt/parser/state"
7
+
8
+ module Yamlt
9
+ #
10
+ #
11
+ class Parser
12
+ #
13
+ #
14
+ #
15
+ def initialize(filepath)
16
+ @filepath = filepath
17
+ @state = Yamlt::Parser::State.new
18
+ end
19
+
20
+ #
21
+ #
22
+ def parse
23
+ IO.read(@filepath).each_line do |line|
24
+ parse_line(line)
25
+ end
26
+
27
+ @state.flush
28
+
29
+ @state
30
+ end
31
+
32
+ private
33
+
34
+ def parse_line(text)
35
+ @state.apply(Yamlt::Parser::Line.new(text))
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ # ------------------------------------------------------------------------------
2
+ # @class: Yamlt::Translator
3
+ # @description: Default class for translating from lang1 to lang2
4
+ # ------------------------------------------------------------------------------
5
+
6
+ module Yamlt
7
+ class Translator
8
+ def initialize(source_lang, target_lang)
9
+ @source_lang = source_lang
10
+ @target_lang = target_lang
11
+ end
12
+
13
+ def translate(original,target = nil)
14
+ if respond_to?(:custom_translate)
15
+ self.custom_translate(original, target)
16
+ else
17
+ original
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,64 @@
1
+ # ------------------------------------------------------------------------------
2
+ # @class: Yamlt::Updater
3
+ # @description: Takes first yaml file as template and writes second file copy
4
+ # ------------------------------------------------------------------------------
5
+
6
+ require "yamlt/loader"
7
+ require "yamlt/parser"
8
+ require "yamlt/translator"
9
+
10
+ module Yamlt
11
+ class Updater
12
+ def initialize(source, target, translator_class = Yamlt::Translator)
13
+ @source = source
14
+ @target = target
15
+ @translator = translator_class.new(state.language, loader.language)
16
+ end
17
+
18
+ def call
19
+ of = File.new(target_updated, "w")
20
+
21
+ state.lines.each do |line|
22
+ of.puts format_line(line)
23
+ end
24
+
25
+ of.close
26
+ end
27
+
28
+ def rename_updated
29
+ File.rename(target_updated, target)
30
+ end
31
+
32
+ private
33
+
34
+ def state
35
+ @state ||=
36
+ if @source.is_a?(String)
37
+ Yamlt::Parser.new(@source).parse
38
+ else
39
+ @source
40
+ end
41
+ end
42
+
43
+ def loader
44
+ @loader ||= Yamlt::Loader.new(@target)
45
+ end
46
+
47
+ def target_updated
48
+ @target_updated ||=
49
+ if /\.yml$/ === @target
50
+ @target[/^(.*)\.yml$/, 1] + ".updated.yml"
51
+ else
52
+ @target + ".updated.yml"
53
+ end
54
+ end
55
+
56
+ def format_line(line)
57
+ if line.level == 0 && line.fragment
58
+ line.as_text(fragment: loader.language)
59
+ else
60
+ line.as_text
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,56 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
6
+ module Yamlt
7
+ class Writer
8
+ def initialize(state, loader,
9
+ opts = {from: "en", to: "ru"},
10
+ callback = -> (old_value, path, from_l, to_l) { old_value } )
11
+ @state = state
12
+ @loader = loader
13
+ @opts = opts
14
+ @callback = callback
15
+ end
16
+
17
+ def write(stream)
18
+ @state.lines.each do |line|
19
+ unless line.value
20
+ stream.write(line.as_text)
21
+ else
22
+ stream.write(format_line(line))
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def value_by_path(path)
30
+ value = @loader[path]
31
+
32
+ raise Yamlt::WriterException unless [String, NilClass].include?(value.class)
33
+
34
+ value
35
+ end
36
+
37
+ def format_line(line)
38
+ old_value = value_by_path(line.full_path) || line.value
39
+
40
+ new_value = @callback.(old_value, line.full_path, @opts[:from], @opts[:to])
41
+
42
+ multiline = new_value.to_s.split($/)
43
+
44
+ if multiline.size > 1
45
+ ([ " " * line.level + line.fragment + ": |" ] +
46
+ multiline.map { |str| " " * (line.level + 1) + str }) * $/
47
+ else
48
+ " " * line.level + line.fragment + ": " + escaped_value(new_value)
49
+ end
50
+ end
51
+
52
+ def escaped_value(value)
53
+ "\"" + value.gsub("\"", "\\\"") + "\""
54
+ end
55
+ end
56
+ end
data/lib/yamlt.rb ADDED
@@ -0,0 +1,8 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
6
+ require "yamlt/parser"
7
+ require "yamlt/loader"
8
+ require "yamlt/checker"
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yamlt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tangerine Cat
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Take yaml structure from locale file and apply to another one
28
+ email: kaineer@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/yamlt.rb
34
+ - lib/yamlt/checker.rb
35
+ - lib/yamlt/checker/reporter.rb
36
+ - lib/yamlt/language_pair.rb
37
+ - lib/yamlt/loader.rb
38
+ - lib/yamlt/parser.rb
39
+ - lib/yamlt/parser/line.rb
40
+ - lib/yamlt/parser/line/serializer.rb
41
+ - lib/yamlt/parser/state.rb
42
+ - lib/yamlt/translator.rb
43
+ - lib/yamlt/updater.rb
44
+ - lib/yamlt/writer.rb
45
+ homepage: http://rubygems.org/gems/yamlt
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.2.2
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Take yaml structure from locale file and apply to another one
69
+ test_files: []