stringer 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.
- data/.gitignore +17 -0
- data/.travis.yml +6 -0
- data/Gemfile +25 -0
- data/LICENSE.txt +7 -0
- data/README.md +60 -0
- data/Rakefile +18 -0
- data/lib/stringer.rb +11 -0
- data/lib/stringer/processor.rb +90 -0
- data/lib/stringer/strings_file.rb +70 -0
- data/lib/stringer/version.rb +3 -0
- data/specs/Localizable.strings +0 -0
- data/specs/helper.rb +17 -0
- data/specs/processor_spec.rb +21 -0
- data/specs/string_file_spec.rb +35 -0
- data/specs/stringer_spec.rb +11 -0
- data/stringer.gemspec +19 -0
- metadata +72 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
# Specify your gem's dependencies in stringer.gemspec
|
|
4
|
+
gemspec
|
|
5
|
+
|
|
6
|
+
group :development do
|
|
7
|
+
# An IRB alternative and runtime developer console
|
|
8
|
+
# [pry](http://pry.github.com)
|
|
9
|
+
gem 'pry', '~> 0.9.10'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
group :test do
|
|
13
|
+
# Adding rake for Travis.
|
|
14
|
+
gem 'rake'
|
|
15
|
+
|
|
16
|
+
# minitest provides a complete suite of testing facilities...
|
|
17
|
+
# [minitest](https://github.com/seattlerb/minitest)
|
|
18
|
+
gem 'minitest', '~> 3.3.0'
|
|
19
|
+
|
|
20
|
+
# Adds color to your MiniTest output
|
|
21
|
+
gem "minitest-rg", "~> 1.0.0"
|
|
22
|
+
|
|
23
|
+
# [mocha](http://gofreerange.com/mocha/docs)
|
|
24
|
+
gem 'mocha', '~> 0.12.2'
|
|
25
|
+
end
|
data/LICENSE.txt
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Stringer
|
|
2
|
+
|
|
3
|
+
Stringer takes the sting out of `genstrings`, by making it not overwriting your `Localizations.strings` file each time you run `genstrings`.
|
|
4
|
+
|
|
5
|
+
It wraps `genstrings` and adds some basic merging capabilities (add and remove keys).
|
|
6
|
+
|
|
7
|
+
## Why?
|
|
8
|
+
|
|
9
|
+
When you run `genstrings` it goes through each of your specified `.m` files, looks for `NSLocalizedString`, parses out the key and comment, adds it to a Localizable.strings file.
|
|
10
|
+
|
|
11
|
+
Downside to this utility: it completely overwrites any changes you make to the `Localizations.strings` file (or if you give it the `-a` flag, it will at least append).
|
|
12
|
+
|
|
13
|
+
That's where `stringer` comes in, makes `genstrings` suck less.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
The easiest way to use `stringer` at the moment is to add a `Gemfile` to the root of your project and add `stringer` to it, like so:
|
|
18
|
+
|
|
19
|
+
gem 'stringer'
|
|
20
|
+
|
|
21
|
+
Then execute:
|
|
22
|
+
|
|
23
|
+
$ bundle
|
|
24
|
+
|
|
25
|
+
Now you can create a Rakefile, and add these lines:
|
|
26
|
+
|
|
27
|
+
require "stringer"
|
|
28
|
+
|
|
29
|
+
desc "Run genstrings to update the Localizable.strings files"
|
|
30
|
+
task :localize do
|
|
31
|
+
%w(en fr nl).each do |locale|
|
|
32
|
+
Stringer.run(locale)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Now you can update your `Localizations.strings` file by running:
|
|
37
|
+
|
|
38
|
+
rake localize
|
|
39
|
+
|
|
40
|
+
Which will output something like this:
|
|
41
|
+
|
|
42
|
+
Generating en.lproj
|
|
43
|
+
- Added 3 keys (die.tijd;duvels;piet...)
|
|
44
|
+
- Removed 1 key (dotter...)
|
|
45
|
+
|
|
46
|
+
## The future
|
|
47
|
+
|
|
48
|
+
`0.2.0`: Add a bin, so the Rake-file shenanigans are no longer necessary.
|
|
49
|
+
|
|
50
|
+
`0.3.0`: Ditch the dependency `genstrings` and fetch strings ourselves.
|
|
51
|
+
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
`1.0.0`: Installed by default on OSX TomCat
|
|
55
|
+
|
|
56
|
+
## Contributing
|
|
57
|
+
|
|
58
|
+
Fork it! Improve it! Test it! Rewrite it! (technology)
|
|
59
|
+
|
|
60
|
+
[](http://travis-ci.org/pjaspers/stringer)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
require "bundler/gem_tasks"
|
|
3
|
+
require 'rake/testtask'
|
|
4
|
+
|
|
5
|
+
desc 'Run the specs'
|
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
|
7
|
+
t.libs << 'lib'
|
|
8
|
+
t.libs << 'specs'
|
|
9
|
+
t.pattern = 'specs/**/*_spec.rb'
|
|
10
|
+
t.verbose = true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
task :default => :test
|
|
14
|
+
|
|
15
|
+
desc "Open an pry session with Stringer loaded"
|
|
16
|
+
task :console do
|
|
17
|
+
sh "pry -I lib -r stringer.rb"
|
|
18
|
+
end
|
data/lib/stringer.rb
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Stringer
|
|
2
|
+
class Processor
|
|
3
|
+
|
|
4
|
+
# The Processor will be doing the genstringing part of the
|
|
5
|
+
# operation.
|
|
6
|
+
#
|
|
7
|
+
# Possible options:
|
|
8
|
+
#
|
|
9
|
+
# - file_folder : Folder where `genstrings` should look for
|
|
10
|
+
# .m files. It searches this recursively.
|
|
11
|
+
# - genstrings : Location of the genstrings command
|
|
12
|
+
# - lproj_parent : Path to folder containing the `<locale>.lproj`
|
|
13
|
+
#
|
|
14
|
+
def initialize(locale, options = {})
|
|
15
|
+
options = default_options.merge(options)
|
|
16
|
+
@locale = locale
|
|
17
|
+
@files_folder = options[:files_folder]
|
|
18
|
+
@genstrings = options[:genstrings]
|
|
19
|
+
@lproj_parent = options[:lproj_parent]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Some sensible defaults in a hash
|
|
23
|
+
def default_options
|
|
24
|
+
{
|
|
25
|
+
:lproj_parent => dir_path_for_dir_with_same_name_as_parent_dir,
|
|
26
|
+
:files_folder => dir_path_for_dir_with_same_name_as_parent_dir,
|
|
27
|
+
:genstrings => "/usr/bin/genstrings"
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# If standard Xcode template is used, this is the dir where most
|
|
32
|
+
# files will be. For a project created with name "Something"
|
|
33
|
+
#
|
|
34
|
+
# Something:
|
|
35
|
+
# Something:
|
|
36
|
+
# en.lproj/
|
|
37
|
+
# *.m
|
|
38
|
+
#
|
|
39
|
+
# Returns the path
|
|
40
|
+
def dir_path_for_dir_with_same_name_as_parent_dir
|
|
41
|
+
current_dir_path = File.dirname(__FILE__)
|
|
42
|
+
current_dir_name = File.basename(current_dir_path)
|
|
43
|
+
File.join(current_dir_path, current_dir_name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def genstrings_command
|
|
47
|
+
"#{@genstrings} -q -o #{lproj_folder} #{files.join(" ")}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns an array of all files needed to be processed.
|
|
51
|
+
def files
|
|
52
|
+
`find #{@files_folder} -name \*.m`.split("\n")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def run
|
|
56
|
+
log("Generating #{@locale}.lproj")
|
|
57
|
+
original_file = StringsFile.new(strings_file_path)
|
|
58
|
+
if system(genstrings_command)
|
|
59
|
+
new_file = StringsFile.new(strings_file_path)
|
|
60
|
+
added_keys, removed_keys = original_file.apply(new_file)
|
|
61
|
+
show_changes(added_keys, "Added")
|
|
62
|
+
show_changes(removed_keys, "Removed")
|
|
63
|
+
end
|
|
64
|
+
original_file.write!
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def lproj_folder
|
|
68
|
+
File.join(@lproj_parent, "#{@locale}.lproj")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def strings_file_path
|
|
72
|
+
"#{lproj_folder}/Localizable.strings"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def log(message)
|
|
76
|
+
puts message
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def show_changes(keys, string)
|
|
80
|
+
number = keys.count
|
|
81
|
+
if number == 1
|
|
82
|
+
string = " - #{string} #{number} key"
|
|
83
|
+
else
|
|
84
|
+
string = " - #{string} #{number} keys"
|
|
85
|
+
end
|
|
86
|
+
string << " (#{keys.join(";")[0..50]}...)" unless number == 0
|
|
87
|
+
log string
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Stringer
|
|
2
|
+
class StringsFile
|
|
3
|
+
attr_accessor :lines
|
|
4
|
+
|
|
5
|
+
def initialize(path)
|
|
6
|
+
check_for_file(path)
|
|
7
|
+
@path = path
|
|
8
|
+
@lines = fetch_lines_at(path)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def check_for_file(path)
|
|
12
|
+
raise "No Localisations found at #{path}" unless File.exist?(path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fetch_lines_at(path)
|
|
16
|
+
IO.readlines(path, mode:"rb:UTF-16LE").collect do |l|
|
|
17
|
+
l.encode("UTF-8").gsub("\uFEFF", "")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def comment_lines
|
|
22
|
+
@lines.select{|l| l =~ /^\/\*/ }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def translation_lines
|
|
26
|
+
@lines.select{|l| l =~ /^"/}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def comments
|
|
30
|
+
@comments ||= comment_lines.collect do |line|
|
|
31
|
+
line.gsub("/*", "").gsub("*/", "").strip
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def translation_hash
|
|
36
|
+
return @translation_hash if @translation_hash
|
|
37
|
+
|
|
38
|
+
@translation_hash = translation_lines.inject({}) do |r,line|
|
|
39
|
+
r[key_from_line(line)] = value_from_line(line)
|
|
40
|
+
r
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def key_from_line(line)
|
|
45
|
+
line.split("=").first.gsub("\"", "").strip
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def value_from_line(line)
|
|
49
|
+
line.split("=").last.strip.gsub(";", "").gsub("\"", "")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def apply(other_string_file)
|
|
53
|
+
removed_keys = translation_hash.keys - other_string_file.translation_hash.keys
|
|
54
|
+
added_keys = other_string_file.translation_hash.keys - translation_hash.keys
|
|
55
|
+
@translation_hash = other_string_file.translation_hash.merge(translation_hash)
|
|
56
|
+
removed_keys.each {|k| @translation_hash.delete(k)}
|
|
57
|
+
[added_keys, removed_keys]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def write!
|
|
61
|
+
File.open(@path, "wb:UTF-16LE") do |file|
|
|
62
|
+
file.write("\uFEFF")
|
|
63
|
+
file.write("/* Generated */\n")
|
|
64
|
+
translation_hash.each do |key, value|
|
|
65
|
+
file.puts "\"#{key}\" = \"#{value}\";"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
Binary file
|
data/specs/helper.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "minitest/autorun"
|
|
2
|
+
require "mocha"
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
# [turn](http://rubygems.org/gems/turn)
|
|
6
|
+
require 'turn/autorun'
|
|
7
|
+
rescue LoadError
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
11
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
12
|
+
|
|
13
|
+
require 'stringer'
|
|
14
|
+
|
|
15
|
+
def locale_file_path
|
|
16
|
+
File.join(File.dirname(__FILE__), "Localizable.strings")
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "helper"
|
|
2
|
+
|
|
3
|
+
describe Stringer::Processor do
|
|
4
|
+
|
|
5
|
+
describe "creating the genstrings command" do
|
|
6
|
+
|
|
7
|
+
it "should use sensible defaults if no options given" do
|
|
8
|
+
Stringer::Processor.any_instance.stubs(:dir_path_for_dir_with_same_name_as_parent_dir).returns("path")
|
|
9
|
+
processor = Stringer::Processor.new("nl")
|
|
10
|
+
processor.stubs(:files).returns(["file_a"])
|
|
11
|
+
processor.genstrings_command.must_equal("/usr/bin/genstrings -q -o path/nl.lproj file_a")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should use the supplied options" do
|
|
15
|
+
processor = Stringer::Processor.new("nl", :files_folder => "files", :lproj_parent => "lproj_parent", :genstrings => "/opt/bin/genstrings")
|
|
16
|
+
processor.stubs(:files).returns(["file_a"])
|
|
17
|
+
processor.genstrings_command.must_equal("/opt/bin/genstrings -q -o lproj_parent/nl.lproj file_a")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "helper"
|
|
2
|
+
|
|
3
|
+
describe Stringer::StringsFile do
|
|
4
|
+
|
|
5
|
+
it "should have loaded the lines from the file" do
|
|
6
|
+
file = Stringer::StringsFile.new(locale_file_path)
|
|
7
|
+
file.lines.wont_be_empty
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should raise if no file found" do
|
|
11
|
+
-> {Stringer::StringsFile.new("404")}.must_raise RuntimeError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "transforming file to strings" do
|
|
15
|
+
before do
|
|
16
|
+
lines = ["/* A comment */",
|
|
17
|
+
"\"a.key\" = \"Translated Key\";\n"]
|
|
18
|
+
Stringer::StringsFile.any_instance.expects(:fetch_lines_at).with("path").returns(lines)
|
|
19
|
+
Stringer::StringsFile.any_instance.stubs(:check_for_file).with("path").returns(nil)
|
|
20
|
+
@file = Stringer::StringsFile.new("path")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should have transformed the comments" do
|
|
24
|
+
@file.comments.first.must_equal("A comment")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should have extracted the keys" do
|
|
28
|
+
@file.translation_hash["a.key"].wont_be_nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should have extracted the value" do
|
|
32
|
+
@file.translation_hash["a.key"].must_equal "Translated Key"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/stringer.gemspec
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'stringer/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "stringer"
|
|
8
|
+
gem.version = Stringer::VERSION
|
|
9
|
+
gem.authors = ["pjaspers"]
|
|
10
|
+
gem.email = ["piet@jaspe.rs"]
|
|
11
|
+
gem.description = %q{Stringer: a wrapper for genstrings}
|
|
12
|
+
gem.summary = %q{Stringer adds merging capabilities to genstrings}
|
|
13
|
+
gem.homepage = ""
|
|
14
|
+
|
|
15
|
+
gem.files = `git ls-files`.split($/)
|
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|specs|features)/})
|
|
18
|
+
gem.require_paths = ["lib"]
|
|
19
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: stringer
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- pjaspers
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-12-02 00:00:00.000000000 Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description: ! 'Stringer: a wrapper for genstrings'
|
|
15
|
+
email:
|
|
16
|
+
- piet@jaspe.rs
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- .gitignore
|
|
22
|
+
- .travis.yml
|
|
23
|
+
- Gemfile
|
|
24
|
+
- LICENSE.txt
|
|
25
|
+
- README.md
|
|
26
|
+
- Rakefile
|
|
27
|
+
- lib/stringer.rb
|
|
28
|
+
- lib/stringer/processor.rb
|
|
29
|
+
- lib/stringer/strings_file.rb
|
|
30
|
+
- lib/stringer/version.rb
|
|
31
|
+
- specs/Localizable.strings
|
|
32
|
+
- specs/helper.rb
|
|
33
|
+
- specs/processor_spec.rb
|
|
34
|
+
- specs/string_file_spec.rb
|
|
35
|
+
- specs/stringer_spec.rb
|
|
36
|
+
- stringer.gemspec
|
|
37
|
+
homepage: ''
|
|
38
|
+
licenses: []
|
|
39
|
+
post_install_message:
|
|
40
|
+
rdoc_options: []
|
|
41
|
+
require_paths:
|
|
42
|
+
- lib
|
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
|
+
none: false
|
|
45
|
+
requirements:
|
|
46
|
+
- - ! '>='
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
segments:
|
|
50
|
+
- 0
|
|
51
|
+
hash: 1114274200452902360
|
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
|
+
none: false
|
|
54
|
+
requirements:
|
|
55
|
+
- - ! '>='
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0'
|
|
58
|
+
segments:
|
|
59
|
+
- 0
|
|
60
|
+
hash: 1114274200452902360
|
|
61
|
+
requirements: []
|
|
62
|
+
rubyforge_project:
|
|
63
|
+
rubygems_version: 1.8.24
|
|
64
|
+
signing_key:
|
|
65
|
+
specification_version: 3
|
|
66
|
+
summary: Stringer adds merging capabilities to genstrings
|
|
67
|
+
test_files:
|
|
68
|
+
- specs/Localizable.strings
|
|
69
|
+
- specs/helper.rb
|
|
70
|
+
- specs/processor_spec.rb
|
|
71
|
+
- specs/string_file_spec.rb
|
|
72
|
+
- specs/stringer_spec.rb
|