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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - rbx-18mode
5
+ - rbx-19mode
6
+ - 1.8.7
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
@@ -0,0 +1,7 @@
1
+ THE BEER-WARE LICENSE (Revision 42):
2
+
3
+ <pjaspers> wrote this file. As long as you retain this notice you can
4
+ do whatever you want with this stuff. If we meet some day, and you
5
+ think this stuff is worth it, you can buy me a beer in return.
6
+
7
+ Piet Jaspers
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
+ [![Build Status](https://secure.travis-ci.org/pjaspers/stringer.png?branch=master)](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,11 @@
1
+ require "stringer/version"
2
+ require "stringer/strings_file"
3
+ require "stringer/processor"
4
+
5
+ module Stringer
6
+
7
+ def self.run(locale, options = {})
8
+ Stringer::Processor.new(locale, options).run
9
+ end
10
+
11
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Stringer
2
+ VERSION = "0.0.1"
3
+ 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
@@ -0,0 +1,11 @@
1
+ require "helper"
2
+
3
+ describe Stringer do
4
+
5
+ it "should tell the processor to run :)" do
6
+ proc = mock("Stringer::Processor")
7
+ proc.expects(:run)
8
+ Stringer::Processor.expects(:new).with("en", {}).returns(proc)
9
+ Stringer.run("en")
10
+ end
11
+ 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