twine 0.10.1 → 1.0
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 +4 -4
- data/README.md +43 -53
- data/lib/twine/cli.rb +14 -12
- data/lib/twine/formatters/android.rb +23 -7
- data/lib/twine/formatters/apple.rb +3 -1
- data/lib/twine/formatters/django.rb +1 -1
- data/lib/twine/formatters/gettext.rb +2 -4
- data/lib/twine/placeholders.rb +1 -1
- data/lib/twine/runner.rb +9 -2
- data/lib/twine/version.rb +1 -1
- data/test/command_test.rb +2 -2
- data/test/test_cli.rb +45 -0
- data/test/test_formatters.rb +45 -4
- data/test/test_generate_localization_file.rb +18 -0
- data/test/twine_test.rb +1 -1
- metadata +33 -19
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 107f74e29483071d8a72edba115daa2dbea7d1c9
         | 
| 4 | 
            +
              data.tar.gz: 4b81eccc076aa40a7649d6779ef4ccac51fbf0dc
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3173909e712d67f0e63e2ce0dadf3c6bc39d287208d159f798ee29ed220ab87b69cc49692b0472a9961589eda36ce0f31f2d402aab67c736ab4458d8beddcf4e
         | 
| 7 | 
            +
              data.tar.gz: a2d07cfa6b89a6650aed7ee25a3cb2944a83c63b8ac1b5918a64f2804e4485e91b1d26ab329e381a3f4892b38dd76902639dab73f9ecb8445c512fd74477e8f3
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,26 +1,15 @@ | |
| 1 1 | 
             
            # Twine
         | 
| 2 2 |  | 
| 3 | 
            +
            [](https://circleci.com/gh/teespring/twine)
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            Twine is a command line tool for managing your strings and their translations. These are all stored in a master text file and then Twine uses this file to import and export localization files in a variety of types, including iOS and Mac OS X `.strings` files, Android `.xml` files, gettext `.po` files, and [jquery-localize][jquerylocalize] `.json` files. This allows individuals and companies to easily share translations across multiple projects, as well as export localization files in any format the user wants.
         | 
| 4 6 |  | 
| 5 7 | 
             
            ## Install
         | 
| 6 8 |  | 
| 7 | 
            -
            ### As a Gem
         | 
| 8 | 
            -
             | 
| 9 9 | 
             
            Twine is most easily installed as a Gem.
         | 
| 10 10 |  | 
| 11 11 | 
             
            	$ gem install twine
         | 
| 12 12 |  | 
| 13 | 
            -
            ### From Source
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            You can also run Twine directly from source. However, it requires [rubyzip][rubyzip] in order to create and read standard zip files.
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            	$ gem install rubyzip
         | 
| 18 | 
            -
            	$ git clone git://github.com/mobiata/twine.git
         | 
| 19 | 
            -
            	$ cd twine
         | 
| 20 | 
            -
            	$ ./twine --help
         | 
| 21 | 
            -
             | 
| 22 | 
            -
            Make sure you run the `twine` executable at the root of the project as it properly sets up your Ruby library path. The `bin/twine` executable does not.
         | 
| 23 | 
            -
             | 
| 24 13 | 
             
            ## Twine File Format
         | 
| 25 14 |  | 
| 26 15 | 
             
            Twine stores everything in a single file, the Twine data file. The format of this file is a slight variant of the [Git][git] config file format, which itself is based on the old [Windows INI file][INI] format. The entire file is broken up into sections, which are created by placing the section name between two pairs of square brackets. Sections are optional, but they are the recommended way of grouping your definitions into smaller, more manageable chunks.
         | 
| @@ -48,39 +37,39 @@ If you want a definition to inherit the values of another definition, you can us | |
| 48 37 | 
             
            ### Example
         | 
| 49 38 |  | 
| 50 39 | 
             
            ```ini
         | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 40 | 
            +
            [[General]]
         | 
| 41 | 
            +
            	[yes]
         | 
| 42 | 
            +
            		en = Yes
         | 
| 43 | 
            +
            		es = Sí
         | 
| 44 | 
            +
            		fr = Oui
         | 
| 45 | 
            +
            		ja = はい
         | 
| 46 | 
            +
            	[no]
         | 
| 47 | 
            +
            		en = No
         | 
| 48 | 
            +
            		fr = Non
         | 
| 49 | 
            +
            		ja = いいえ
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            [[Errors]]
         | 
| 52 | 
            +
            	[path_not_found_error]
         | 
| 53 | 
            +
            		en = The file '%@' could not be found.
         | 
| 54 | 
            +
            		tags = app1,app6
         | 
| 55 | 
            +
            		comment = An error describing when a path on the filesystem could not be found.
         | 
| 56 | 
            +
            	[network_unavailable_error]
         | 
| 57 | 
            +
            		en = The network is currently unavailable.
         | 
| 58 | 
            +
            		tags = app1
         | 
| 59 | 
            +
            		comment = An error describing when the device can not connect to the internet.
         | 
| 60 | 
            +
            	[dismiss_error]
         | 
| 61 | 
            +
            		ref = yes
         | 
| 62 | 
            +
            		en = Dismiss
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            [[Escaping Example]]
         | 
| 65 | 
            +
            	[list_item_separator]
         | 
| 66 | 
            +
            		en = `, `
         | 
| 67 | 
            +
            		tags = mytag
         | 
| 68 | 
            +
            		comment = A string that should be placed between multiple items in a list. For example: Red, Green, Blue
         | 
| 69 | 
            +
            	[grave_accent_quoted_string]
         | 
| 70 | 
            +
            		en = ``%@``
         | 
| 71 | 
            +
            		tags = myothertag
         | 
| 72 | 
            +
            		comment = This string will evaluate to `%@`.
         | 
| 84 73 | 
             
            ```
         | 
| 85 74 |  | 
| 86 75 | 
             
            ## Supported Output Formats
         | 
| @@ -89,6 +78,7 @@ Twine currently supports the following output formats: | |
| 89 78 |  | 
| 90 79 | 
             
            * [iOS and OS X String Resources][applestrings] (format: apple)
         | 
| 91 80 | 
             
            * [Android String Resources][androidstrings] (format: android)
         | 
| 81 | 
            +
                * Supports [basic styling][androidstyling] with \<b\>, \<i\>, \<u\> and \<a\> links. These tags will *not* be escaped. Use [`getText()`](https://developer.android.com/reference/android/content/res/Resources.html#getText(int)) to read these strings. Also tags inside `< for details.
         | 
| 92 82 | 
             
            * [Gettext PO Files][gettextpo] (format: gettext)
         | 
| 93 83 | 
             
            * [jquery-localize Language Files][jquerylocalize] (format: jquery)
         | 
| 94 84 | 
             
            * [Django PO Files][djangopo] (format: django)
         | 
| @@ -182,11 +172,11 @@ Now, whenever you build your application, Xcode will automatically invoke Twine | |
| 182 172 | 
             
            Add the following task at the top level in app/build.gradle:
         | 
| 183 173 | 
             
            ```
         | 
| 184 174 | 
             
            task generateLocalizations {
         | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 175 | 
            +
            	String script = 'if hash twine 2>/dev/null; then twine generate-localization-file twine.txt ./src/main/res/values/generated_strings.xml; fi'
         | 
| 176 | 
            +
            	exec {
         | 
| 177 | 
            +
            		executable "sh"
         | 
| 178 | 
            +
            		args '-c', script
         | 
| 179 | 
            +
            	}
         | 
| 190 180 | 
             
            }
         | 
| 191 181 | 
             
            ```
         | 
| 192 182 |  | 
| @@ -196,7 +186,6 @@ Now every time you build your app the localization files are generated from the | |
| 196 186 | 
             
            ## User Interface
         | 
| 197 187 |  | 
| 198 188 | 
             
            * [Twine TextMate 2 Bundle](https://github.com/mobiata/twine.tmbundle) — This [TextMate 2](https://github.com/textmate/textmate) bundle will make it easier for you to work with Twine files. In particular, it lets you use code folding to easily collapse and expand both definitions and sections.
         | 
| 199 | 
            -
            * [twine_ui](https://github.com/Daij-Djan/twine_ui) — A user interface for Twine written by [Dominik Pich](https://github.com/Daij-Djan/). Consider using this if you would prefer to use Twine without dropping to a command line.
         | 
| 200 189 |  | 
| 201 190 | 
             
            ## Extending Twine
         | 
| 202 191 |  | 
| @@ -224,9 +213,10 @@ Many thanks to all of the contributors to the Twine project, including: | |
| 224 213 | 
             
            [INI]: http://en.wikipedia.org/wiki/INI_file
         | 
| 225 214 | 
             
            [applestrings]: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
         | 
| 226 215 | 
             
            [androidstrings]: http://developer.android.com/guide/topics/resources/string-resource.html
         | 
| 216 | 
            +
            [androidstyling]: http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
         | 
| 227 217 | 
             
            [gettextpo]: http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html
         | 
| 228 218 | 
             
            [jquerylocalize]: https://github.com/coderifous/jquery-localize
         | 
| 229 219 | 
             
            [djangopo]: https://docs.djangoproject.com/en/dev/topics/i18n/translation/
         | 
| 230 220 | 
             
            [tizen]: https://developer.tizen.org/documentation/articles/localization
         | 
| 231 221 | 
             
            [flash]: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#getString()
         | 
| 232 | 
            -
            [printf]: https://en.wikipedia.org/wiki/Printf_format_string
         | 
| 222 | 
            +
            [printf]: https://en.wikipedia.org/wiki/Printf_format_string
         | 
    
        data/lib/twine/cli.rb
    CHANGED
    
    | @@ -22,7 +22,7 @@ module Twine | |
| 22 22 | 
             
                  create_folders: {
         | 
| 23 23 | 
             
                    switch: ['-r', '--[no-]create-folders'],
         | 
| 24 24 | 
             
                    description: <<-DESC,
         | 
| 25 | 
            -
                      This flag may be used to create output folders for all languages, if they | 
| 25 | 
            +
                      This flag may be used to create output folders for all languages, if they don't exist yet.
         | 
| 26 26 | 
             
                      As a result all languages will be exported, not only the ones where an output folder already exists.
         | 
| 27 27 | 
             
                    DESC
         | 
| 28 28 | 
             
                    boolean: true
         | 
| @@ -220,21 +220,25 @@ module Twine | |
| 220 220 | 
             
                  command = args.select { |a| a[0] != '-' }[0]
         | 
| 221 221 | 
             
                  args = args.reject { |a| a == command }
         | 
| 222 222 |  | 
| 223 | 
            +
                  if args.any? { |a| a == '--version' }
         | 
| 224 | 
            +
                    Twine::stdout.puts "Twine version #{Twine::VERSION}"
         | 
| 225 | 
            +
                    return false
         | 
| 226 | 
            +
                  end
         | 
| 227 | 
            +
             | 
| 223 228 | 
             
                  mapped_command = DEPRECATED_COMMAND_MAPPINGS[command]
         | 
| 224 229 | 
             
                  if mapped_command
         | 
| 225 | 
            -
                    Twine::stderr.puts "WARNING: Twine commands names have changed. `#{command}` is now `#{mapped_command}`. The old command is deprecated will soon stop working. For more information please check the documentation at https://github.com/mobiata/twine"
         | 
| 230 | 
            +
                    Twine::stderr.puts "WARNING: Twine commands names have changed. `#{command}` is now `#{mapped_command}`. The old command is deprecated and will soon stop working. For more information please check the documentation at https://github.com/mobiata/twine"
         | 
| 226 231 | 
             
                    command = mapped_command
         | 
| 227 232 | 
             
                  end
         | 
| 228 233 |  | 
| 229 | 
            -
                   | 
| 230 | 
            -
                    Twine::stderr.puts "Invalid command: #{command}" unless command.nil?
         | 
| 234 | 
            +
                  if command.nil?
         | 
| 231 235 | 
             
                    print_help(args)
         | 
| 232 | 
            -
                     | 
| 236 | 
            +
                    return false
         | 
| 237 | 
            +
                  elsif not COMMANDS.keys.include? command
         | 
| 238 | 
            +
                    raise Twine::Error.new "Invalid command: #{command}"
         | 
| 233 239 | 
             
                  end
         | 
| 234 240 |  | 
| 235 | 
            -
                   | 
| 236 | 
            -
             | 
| 237 | 
            -
                  return options
         | 
| 241 | 
            +
                  parse_command_options(command, args)
         | 
| 238 242 | 
             
                end
         | 
| 239 243 |  | 
| 240 244 | 
             
                private
         | 
| @@ -352,8 +356,6 @@ module Twine | |
| 352 356 | 
             
                        parser.define(*option[:switch]) do |value|
         | 
| 353 357 | 
             
                          if option[:repeated]
         | 
| 354 358 | 
             
                            result[option_name] = (result[option_name] || []) << value
         | 
| 355 | 
            -
                          elsif option[:boolean]
         | 
| 356 | 
            -
                            result[option_name] = true
         | 
| 357 359 | 
             
                          else
         | 
| 358 360 | 
             
                            result[option_name] = value
         | 
| 359 361 | 
             
                          end
         | 
| @@ -363,8 +365,8 @@ module Twine | |
| 363 365 | 
             
                  end
         | 
| 364 366 |  | 
| 365 367 | 
             
                  parser.define('-h', '--help', 'Show this message.') do
         | 
| 366 | 
            -
                    puts parser.help
         | 
| 367 | 
            -
                     | 
| 368 | 
            +
                    Twine::stdout.puts parser.help
         | 
| 369 | 
            +
                    return false
         | 
| 368 370 | 
             
                  end
         | 
| 369 371 |  | 
| 370 372 | 
             
                  parser.separator ''
         | 
| @@ -32,7 +32,7 @@ module Twine | |
| 32 32 | 
             
                        # The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase "r").
         | 
| 33 33 | 
             
                        # see http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
         | 
| 34 34 | 
             
                        match = /^values-([a-z]{2}(-r[a-z]{2})?)$/i.match(segment)
         | 
| 35 | 
            -
             | 
| 35 | 
            +
             | 
| 36 36 | 
             
                        return match[1].sub('-r', '-') if match
         | 
| 37 37 | 
             
                      end
         | 
| 38 38 | 
             
                    end
         | 
| @@ -41,7 +41,7 @@ module Twine | |
| 41 41 | 
             
                  end
         | 
| 42 42 |  | 
| 43 43 | 
             
                  def output_path_for_language(lang)
         | 
| 44 | 
            -
                    "values-#{lang}"
         | 
| 44 | 
            +
                    "values-#{lang}".gsub(/-(\p{Lu})/, '-r\1')
         | 
| 45 45 | 
             
                  end
         | 
| 46 46 |  | 
| 47 47 | 
             
                  def set_translation_for_key(key, lang, value)
         | 
| @@ -99,12 +99,28 @@ module Twine | |
| 99 99 | 
             
                    "\t<string name=\"%{key}\">%{value}</string>"
         | 
| 100 100 | 
             
                  end
         | 
| 101 101 |  | 
| 102 | 
            +
                  def gsub_unless(text, pattern, replacement)
         | 
| 103 | 
            +
                    text.gsub(pattern) do |match|
         | 
| 104 | 
            +
                      match_start_position = Regexp.last_match.offset(0)[0]
         | 
| 105 | 
            +
                      yield(text[0, match_start_position]) ? match : replacement
         | 
| 106 | 
            +
                    end
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  # http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
         | 
| 102 110 | 
             
                  def escape_value(value)
         | 
| 103 | 
            -
                    #  | 
| 104 | 
            -
                     | 
| 105 | 
            -
             | 
| 106 | 
            -
                     | 
| 107 | 
            -
                    value | 
| 111 | 
            +
                    inside_cdata = /<\!\[CDATA\[((?!\]\]>).)*$/       # opening CDATA tag ('<![CDATA[') not followed by a closing tag (']]>')
         | 
| 112 | 
            +
                    inside_opening_anchor_tag = /<a\s?((?!>).)*$/     # anchor tag start ('<a ') not followed by a '>'
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                    # escape double and single quotes and & signs
         | 
| 115 | 
            +
                    value = gsub_unless(value, '"', '\\"') { |substring| substring =~ inside_cdata || substring =~ inside_opening_anchor_tag }
         | 
| 116 | 
            +
                    value = gsub_unless(value, "'", "\\'") { |substring| substring =~ inside_cdata }
         | 
| 117 | 
            +
                    value = gsub_unless(value, /&/, '&') { |substring| substring =~ inside_cdata || substring =~ inside_opening_anchor_tag }
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                    # escape opening angle brackes unless it's a supported styling tag
         | 
| 120 | 
            +
                    # https://github.com/scelis/twine/issues/212
         | 
| 121 | 
            +
                    # https://stackoverflow.com/questions/3235131/#18199543
         | 
| 122 | 
            +
                    angle_bracket = /<(?!(\/?(b|u|i|a|\!\[CDATA)))/   # matches all `<` but <b>, <u>, <i>, <a> and <![CDATA
         | 
| 123 | 
            +
                    value = gsub_unless(value, angle_bracket, '<') { |substring| substring =~ inside_cdata }
         | 
| 108 124 |  | 
| 109 125 | 
             
                    # escape non resource identifier @ signs (http://developer.android.com/guide/topics/resources/accessing-resources.html#ResourcesFromXml)
         | 
| 110 126 | 
             
                    resource_identifier_regex = /@(?!([a-z\.]+:)?[a-z+]+\/[a-zA-Z_]+)/   # @[<package_name>:]<resource_type>/<resource_name>
         | 
| @@ -16,7 +16,7 @@ module Twine | |
| 16 16 | 
             
                  def determine_language_given_path(path)
         | 
| 17 17 | 
             
                    path_arr = path.split(File::SEPARATOR)
         | 
| 18 18 | 
             
                    path_arr.each do |segment|
         | 
| 19 | 
            -
                      match = /( | 
| 19 | 
            +
                      match = /([a-z]{2}(-[A-Za-z]{2})?)\.po$/.match(segment)
         | 
| 20 20 | 
             
                      return match[1] if match
         | 
| 21 21 | 
             
                    end
         | 
| 22 22 |  | 
| @@ -18,10 +18,8 @@ module Twine | |
| 18 18 | 
             
                  def determine_language_given_path(path)
         | 
| 19 19 | 
             
                    path_arr = path.split(File::SEPARATOR)
         | 
| 20 20 | 
             
                    path_arr.each do |segment|
         | 
| 21 | 
            -
                      match = /( | 
| 22 | 
            -
                      if match
         | 
| 23 | 
            -
                        return match[1]
         | 
| 24 | 
            -
                      end
         | 
| 21 | 
            +
                      match = /([a-z]{2}(-[A-Za-z]{2})?)\.po$/.match(segment)
         | 
| 22 | 
            +
                      return match[1] if match
         | 
| 25 23 | 
             
                    end
         | 
| 26 24 |  | 
| 27 25 | 
             
                    return
         | 
    
        data/lib/twine/placeholders.rb
    CHANGED
    
    | @@ -3,7 +3,7 @@ module Twine | |
| 3 3 | 
             
                extend self
         | 
| 4 4 |  | 
| 5 5 | 
             
                # Note: the ` ` (single space) flag is NOT supported
         | 
| 6 | 
            -
                PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH = '([-+0#])?(\d+|\*)?(\.(\d+|\*))?(hh?|ll?|L|z|j|t)?'
         | 
| 6 | 
            +
                PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH = '([-+0#])?(\d+|\*)?(\.(\d+|\*))?(hh?|ll?|L|z|j|t|q)?'
         | 
| 7 7 | 
             
                PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH = '(\d+\$)?' + PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH
         | 
| 8 8 | 
             
                PLACEHOLDER_TYPES = '[diufFeEgGxXoscpaA]'
         | 
| 9 9 |  | 
    
        data/lib/twine/runner.rb
    CHANGED
    
    | @@ -7,6 +7,8 @@ module Twine | |
| 7 7 | 
             
              class Runner
         | 
| 8 8 | 
             
                def self.run(args)
         | 
| 9 9 | 
             
                  options = CLI.parse(args)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  return unless options
         | 
| 10 12 |  | 
| 11 13 | 
             
                  twine_file = TwineFile.new
         | 
| 12 14 | 
             
                  twine_file.read options[:twine_file]
         | 
| @@ -282,8 +284,13 @@ module Twine | |
| 282 284 | 
             
                end
         | 
| 283 285 |  | 
| 284 286 | 
             
                def find_formatter(&block)
         | 
| 285 | 
            -
                   | 
| 286 | 
            -
                   | 
| 287 | 
            +
                  formatters = Formatters.formatters.select &block
         | 
| 288 | 
            +
                  if formatters.empty?
         | 
| 289 | 
            +
                    return nil
         | 
| 290 | 
            +
                  elsif formatters.size > 1
         | 
| 291 | 
            +
                    raise Twine::Error.new("Unable to determine format. Candidates are: #{formatters.map(&:format_name).join(', ')}. Please specify the format you want using '--format'")
         | 
| 292 | 
            +
                  end
         | 
| 293 | 
            +
                  formatter = formatters.first
         | 
| 287 294 | 
             
                  formatter.twine_file = @twine_file
         | 
| 288 295 | 
             
                  formatter.options = @options
         | 
| 289 296 | 
             
                  formatter
         | 
    
        data/lib/twine/version.rb
    CHANGED
    
    
    
        data/test/command_test.rb
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            require 'twine_test'
         | 
| 2 2 |  | 
| 3 3 | 
             
            class CommandTest < TwineTest
         | 
| 4 | 
            -
              def prepare_mock_formatter(formatter_class)
         | 
| 4 | 
            +
              def prepare_mock_formatter(formatter_class, clear_other_formatters = true)
         | 
| 5 5 | 
             
                twine_file = Twine::TwineFile.new
         | 
| 6 6 | 
             
                twine_file.language_codes.concat KNOWN_LANGUAGES
         | 
| 7 7 |  | 
| 8 8 | 
             
                formatter = formatter_class.new
         | 
| 9 9 | 
             
                formatter.twine_file = twine_file
         | 
| 10 | 
            -
                Twine::Formatters.formatters.clear
         | 
| 10 | 
            +
                Twine::Formatters.formatters.clear if clear_other_formatters
         | 
| 11 11 | 
             
                Twine::Formatters.formatters << formatter
         | 
| 12 12 | 
             
                formatter
         | 
| 13 13 | 
             
              end
         | 
    
        data/test/test_cli.rb
    CHANGED
    
    | @@ -17,14 +17,24 @@ class CLITest < TwineTest | |
| 17 17 | 
             
                raise "you need to implement `parse_with` in your test class"
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 | 
            +
              def assert_help
         | 
| 21 | 
            +
                parse_with '--help'
         | 
| 22 | 
            +
                assert_equal @options, false
         | 
| 23 | 
            +
                assert_match /Usage: twine.*Examples:/m, Twine::stdout.string
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 20 26 | 
             
              def assert_option_consume_all
         | 
| 21 27 | 
             
                parse_with '--consume-all'
         | 
| 22 28 | 
             
                assert @options[:consume_all]
         | 
| 29 | 
            +
                parse_with '--no-consume-all'
         | 
| 30 | 
            +
                refute @options[:consume_all]
         | 
| 23 31 | 
             
              end
         | 
| 24 32 |  | 
| 25 33 | 
             
              def assert_option_consume_comments
         | 
| 26 34 | 
             
                parse_with '--consume-comments'
         | 
| 27 35 | 
             
                assert @options[:consume_comments]
         | 
| 36 | 
            +
                parse_with '--no-consume-comments'
         | 
| 37 | 
            +
                refute @options[:consume_comments]
         | 
| 28 38 | 
             
              end
         | 
| 29 39 |  | 
| 30 40 | 
             
              def assert_option_developer_language
         | 
| @@ -99,11 +109,35 @@ class CLITest < TwineTest | |
| 99 109 | 
             
              def assert_option_untagged
         | 
| 100 110 | 
             
                parse_with '--untagged'
         | 
| 101 111 | 
             
                assert @options[:untagged]
         | 
| 112 | 
            +
                parse_with '--no-untagged'
         | 
| 113 | 
            +
                refute @options[:untagged]
         | 
| 102 114 | 
             
              end
         | 
| 103 115 |  | 
| 104 116 | 
             
              def assert_option_validate
         | 
| 105 117 | 
             
                parse_with "--validate"
         | 
| 106 118 | 
             
                assert @options[:validate]
         | 
| 119 | 
            +
                parse_with "--no-validate"
         | 
| 120 | 
            +
                refute @options[:validate]
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
            end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            class TestCLI < CLITest
         | 
| 125 | 
            +
              def test_version
         | 
| 126 | 
            +
                parse "--version"
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                assert_equal @options, false
         | 
| 129 | 
            +
                assert_equal "Twine version #{Twine::VERSION}\n", Twine::stdout.string
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              def test_help
         | 
| 133 | 
            +
                parse ""
         | 
| 134 | 
            +
                assert_match 'Usage: twine', Twine::stdout.string
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
              def test_invalid_command
         | 
| 138 | 
            +
                assert_raises Twine::Error do
         | 
| 139 | 
            +
                  parse "not a command"
         | 
| 140 | 
            +
                end
         | 
| 107 141 | 
             
              end
         | 
| 108 142 | 
             
            end
         | 
| 109 143 |  | 
| @@ -133,6 +167,7 @@ class TestGenerateLocalizationFileCLI < CLITest | |
| 133 167 | 
             
              end
         | 
| 134 168 |  | 
| 135 169 | 
             
              def test_options
         | 
| 170 | 
            +
                assert_help
         | 
| 136 171 | 
             
                assert_option_developer_language
         | 
| 137 172 | 
             
                assert_option_encoding
         | 
| 138 173 | 
             
                assert_option_format
         | 
| @@ -171,6 +206,7 @@ class TestGenerateAllLocalizationFilesCLI < CLITest | |
| 171 206 | 
             
              end
         | 
| 172 207 |  | 
| 173 208 | 
             
              def test_options
         | 
| 209 | 
            +
                assert_help
         | 
| 174 210 | 
             
                assert_option_developer_language
         | 
| 175 211 | 
             
                assert_option_encoding
         | 
| 176 212 | 
             
                assert_option_format
         | 
| @@ -183,6 +219,8 @@ class TestGenerateAllLocalizationFilesCLI < CLITest | |
| 183 219 | 
             
              def test_option_create_folders
         | 
| 184 220 | 
             
                parse_with '--create-folders'
         | 
| 185 221 | 
             
                assert @options[:create_folders]
         | 
| 222 | 
            +
                parse_with '--no-create-folders'
         | 
| 223 | 
            +
                refute @options[:create_folders]
         | 
| 186 224 | 
             
              end
         | 
| 187 225 |  | 
| 188 226 | 
             
              def test_option_file_name
         | 
| @@ -218,6 +256,7 @@ class TestGenerateLocalizationArchiveCLI < CLITest | |
| 218 256 | 
             
              end
         | 
| 219 257 |  | 
| 220 258 | 
             
              def test_options
         | 
| 259 | 
            +
                assert_help
         | 
| 221 260 | 
             
                assert_option_developer_language
         | 
| 222 261 | 
             
                assert_option_encoding
         | 
| 223 262 | 
             
                assert_option_include
         | 
| @@ -269,6 +308,7 @@ class TestConsumeLocalizationFileCLI < CLITest | |
| 269 308 | 
             
              end
         | 
| 270 309 |  | 
| 271 310 | 
             
              def test_options
         | 
| 311 | 
            +
                assert_help
         | 
| 272 312 | 
             
                assert_option_consume_all
         | 
| 273 313 | 
             
                assert_option_consume_comments
         | 
| 274 314 | 
             
                assert_option_developer_language
         | 
| @@ -307,6 +347,7 @@ class TestConsumeAllLocalizationFilesCLI < CLITest | |
| 307 347 | 
             
              end
         | 
| 308 348 |  | 
| 309 349 | 
             
              def test_options
         | 
| 350 | 
            +
                assert_help
         | 
| 310 351 | 
             
                assert_option_consume_all
         | 
| 311 352 | 
             
                assert_option_consume_comments
         | 
| 312 353 | 
             
                assert_option_developer_language
         | 
| @@ -343,6 +384,7 @@ class TestConsumeLocalizationArchiveCLI < CLITest | |
| 343 384 | 
             
              end
         | 
| 344 385 |  | 
| 345 386 | 
             
              def test_options
         | 
| 387 | 
            +
                assert_help
         | 
| 346 388 | 
             
                assert_option_consume_all
         | 
| 347 389 | 
             
                assert_option_consume_comments
         | 
| 348 390 | 
             
                assert_option_developer_language
         | 
| @@ -388,11 +430,14 @@ class TestValidateTwineFileCLI < CLITest | |
| 388 430 | 
             
              end
         | 
| 389 431 |  | 
| 390 432 | 
             
              def test_options
         | 
| 433 | 
            +
                assert_help
         | 
| 391 434 | 
             
                assert_option_developer_language
         | 
| 392 435 | 
             
              end
         | 
| 393 436 |  | 
| 394 437 | 
             
              def test_option_pedantic
         | 
| 395 438 | 
             
                parse "validate-twine-file #{@twine_file_path} --pedantic"
         | 
| 396 439 | 
             
                assert @options[:pedantic]
         | 
| 440 | 
            +
                parse "validate-twine-file #{@twine_file_path} --no-pedantic"
         | 
| 441 | 
            +
                refute @options[:pedantic]
         | 
| 397 442 | 
             
              end
         | 
| 398 443 | 
             
            end
         | 
    
        data/test/test_formatters.rb
    CHANGED
    
    | @@ -39,14 +39,33 @@ end | |
| 39 39 | 
             
            class TestAndroidFormatter < FormatterTest
         | 
| 40 40 | 
             
              def setup
         | 
| 41 41 | 
             
                super Twine::Formatters::Android
         | 
| 42 | 
            -
             | 
| 42 | 
            +
             | 
| 43 43 | 
             
                @escape_test_values = {
         | 
| 44 44 | 
             
                  'this & that'               => 'this & that',
         | 
| 45 45 | 
             
                  'this < that'               => 'this < that',
         | 
| 46 46 | 
             
                  "it's complicated"          => "it\\'s complicated",
         | 
| 47 47 | 
             
                  'a "good" way'              => 'a \"good\" way',
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  '< | 
| 48 | 
            +
             | 
| 49 | 
            +
                  '<b>bold</b>'               => '<b>bold</b>',
         | 
| 50 | 
            +
                  '<i>italic</i>'             => '<i>italic</i>',
         | 
| 51 | 
            +
                  '<u>underline</u>'          => '<u>underline</u>',
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  '<span>inline</span>'       => '<span>inline</span>',
         | 
| 54 | 
            +
                  '<p>paragraph</p>'          => '<p>paragraph</p>',
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  '<a href="target">link</a>'     => '<a href="target">link</a>',
         | 
| 57 | 
            +
                  '<a href="target">"link"</a>'   => '<a href="target">\"link\"</a>',
         | 
| 58 | 
            +
                  '<a href="target"></a>"out"'    => '<a href="target"></a>\"out\"',
         | 
| 59 | 
            +
                  '<a href="http://url.com?param=1¶m2=3¶m3=%20">link</a>'   =>   '<a href="http://url.com?param=1¶m2=3¶m3=%20">link</a>',
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  '<p>escaped</p><![CDATA[]]>'    => '<p>escaped</p><![CDATA[]]>',
         | 
| 62 | 
            +
                  '<![CDATA[]]><p>escaped</p>'    => '<![CDATA[]]><p>escaped</p>',
         | 
| 63 | 
            +
                  '<![CDATA[<p>unescaped</p>]]>'  => '<![CDATA[<p>unescaped</p>]]>',
         | 
| 64 | 
            +
                  '<![CDATA[]]><![CDATA[<p>unescaped</p>]]>'  => '<![CDATA[]]><![CDATA[<p>unescaped</p>]]>',
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  '<![CDATA[&]]>'  => '<![CDATA[&]]>',
         | 
| 67 | 
            +
                  '<![CDATA[\']]>' => '<![CDATA[\']]>',
         | 
| 68 | 
            +
                  '<![CDATA["]]>'  => '<![CDATA["]]>',
         | 
| 50 69 |  | 
| 51 70 | 
             
                  '<xliff:g></xliff:g>' => '<xliff:g></xliff:g>',
         | 
| 52 71 | 
             
                  '<xliff:g>untouched</xliff:g>' => '<xliff:g>untouched</xliff:g>',
         | 
| @@ -157,6 +176,10 @@ class TestAndroidFormatter < FormatterTest | |
| 157 176 | 
             
              def test_output_path_is_prefixed
         | 
| 158 177 | 
             
                assert_equal 'values-en', @formatter.output_path_for_language('en')
         | 
| 159 178 | 
             
              end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
              def test_output_path_with_region
         | 
| 181 | 
            +
                assert_equal 'values-en-rGB', @formatter.output_path_for_language('en-GB')
         | 
| 182 | 
            +
              end
         | 
| 160 183 | 
             
            end
         | 
| 161 184 |  | 
| 162 185 | 
             
            class TestAppleFormatter < FormatterTest
         | 
| @@ -170,6 +193,16 @@ class TestAppleFormatter < FormatterTest | |
| 170 193 | 
             
                assert_file_contents_read_correctly
         | 
| 171 194 | 
             
              end
         | 
| 172 195 |  | 
| 196 | 
            +
              def test_deducts_language_from_resource_folder
         | 
| 197 | 
            +
                language = %w(en de fr).sample
         | 
| 198 | 
            +
                assert_equal language, @formatter.determine_language_given_path("#{language}.lproj/Localizable.strings")
         | 
| 199 | 
            +
              end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
              def test_deducts_base_language_from_resource_folder
         | 
| 202 | 
            +
                @formatter.options = { consume_all: true, consume_comments: true, developer_language: 'en' }
         | 
| 203 | 
            +
                assert_equal 'en', @formatter.determine_language_given_path('Base.lproj/Localizations.strings')
         | 
| 204 | 
            +
              end
         | 
| 205 | 
            +
             | 
| 173 206 | 
             
              def test_reads_quoted_keys
         | 
| 174 207 | 
             
                @formatter.read StringIO.new('"key" = "value"'), 'en'
         | 
| 175 208 | 
             
                assert_equal 'value', @empty_twine_file.definitions_by_key['key'].translations['en']
         | 
| @@ -267,7 +300,6 @@ class TestJQueryFormatter < FormatterTest | |
| 267 300 | 
             
            end
         | 
| 268 301 |  | 
| 269 302 | 
             
            class TestGettextFormatter < FormatterTest
         | 
| 270 | 
            -
             | 
| 271 303 | 
             
              def setup
         | 
| 272 304 | 
             
                super Twine::Formatters::Gettext
         | 
| 273 305 | 
             
              end
         | 
| @@ -290,6 +322,10 @@ class TestGettextFormatter < FormatterTest | |
| 290 322 | 
             
                assert_equal content('formatter_gettext.po'), formatter.format_file('en')
         | 
| 291 323 | 
             
              end
         | 
| 292 324 |  | 
| 325 | 
            +
              def test_deducts_language_and_region
         | 
| 326 | 
            +
                language = "en-GB"
         | 
| 327 | 
            +
                assert_equal language, @formatter.determine_language_given_path("#{language}.po")
         | 
| 328 | 
            +
              end
         | 
| 293 329 | 
             
            end
         | 
| 294 330 |  | 
| 295 331 | 
             
            class TestTizenFormatter < FormatterTest
         | 
| @@ -329,6 +365,11 @@ class TestDjangoFormatter < FormatterTest | |
| 329 365 | 
             
                formatter.twine_file = @twine_file
         | 
| 330 366 | 
             
                assert_equal content('formatter_django.po'), formatter.format_file('en')
         | 
| 331 367 | 
             
              end
         | 
| 368 | 
            +
             | 
| 369 | 
            +
              def test_deducts_language_and_region
         | 
| 370 | 
            +
                language = "en-GB"
         | 
| 371 | 
            +
                assert_equal language, @formatter.determine_language_given_path("#{language}.po")
         | 
| 372 | 
            +
              end
         | 
| 332 373 | 
             
            end
         | 
| 333 374 |  | 
| 334 375 | 
             
            class TestFlashFormatter < FormatterTest
         | 
| @@ -41,6 +41,24 @@ class TestGenerateLocalizationFile < CommandTest | |
| 41 41 | 
             
                new_runner('fr', 'fr.po').generate_localization_file
         | 
| 42 42 | 
             
              end
         | 
| 43 43 |  | 
| 44 | 
            +
              def test_deducts_django_format_from_output_path
         | 
| 45 | 
            +
                prepare_mock_format_file_formatter Twine::Formatters::Django
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                new_runner('fr', 'fr.po').generate_localization_file
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def test_returns_error_for_ambiguous_output_path
         | 
| 51 | 
            +
                # both Gettext and Django use .po
         | 
| 52 | 
            +
                gettext_formatter = prepare_mock_formatter(Twine::Formatters::Gettext)
         | 
| 53 | 
            +
                gettext_formatter.stubs(:format_file).returns(true)
         | 
| 54 | 
            +
                django_formatter = prepare_mock_formatter(Twine::Formatters::Django, false)
         | 
| 55 | 
            +
                django_formatter.stubs(:format_file).returns(true)
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                assert_raises Twine::Error do
         | 
| 58 | 
            +
                  new_runner('fr', 'fr.po').generate_localization_file
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 44 62 | 
             
              def test_deducts_language_from_output_path
         | 
| 45 63 | 
             
                random_language = KNOWN_LANGUAGES.sample
         | 
| 46 64 | 
             
                formatter = prepare_mock_formatter Twine::Formatters::Android
         | 
    
        data/test/twine_test.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,83 +1,97 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: twine
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0 | 
| 4 | 
            +
              version: '1.0'
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Sebastian Celis
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017- | 
| 11 | 
            +
            date: 2017-10-16 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rubyzip
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - -  | 
| 17 | 
            +
                - - ~>
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 19 | 
             
                    version: '1.1'
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - -  | 
| 24 | 
            +
                - - ~>
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: '1.1'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: safe_yaml
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 | 
            -
                - -  | 
| 31 | 
            +
                - - ~>
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 33 | 
             
                    version: '1.0'
         | 
| 34 34 | 
             
              type: :runtime
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 | 
            -
                - -  | 
| 38 | 
            +
                - - ~>
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '1.0'
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: rake
         | 
| 43 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                requirements:
         | 
| 45 | 
            -
                - -  | 
| 45 | 
            +
                - - ~>
         | 
| 46 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 47 | 
             
                    version: '10.4'
         | 
| 48 48 | 
             
              type: :development
         | 
| 49 49 | 
             
              prerelease: false
         | 
| 50 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 | 
            -
                - -  | 
| 52 | 
            +
                - - ~>
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '10.4'
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 56 | 
             
              name: minitest
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 | 
            -
                - -  | 
| 59 | 
            +
                - - ~>
         | 
| 60 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 61 | 
             
                    version: '5.5'
         | 
| 62 62 | 
             
              type: :development
         | 
| 63 63 | 
             
              prerelease: false
         | 
| 64 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 65 | 
             
                requirements:
         | 
| 66 | 
            -
                - -  | 
| 66 | 
            +
                - - ~>
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: '5.5'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: minitest-ci
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ~>
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '3.0'
         | 
| 76 | 
            +
              type: :development
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ~>
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '3.0'
         | 
| 69 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 84 | 
             
              name: mocha
         | 
| 71 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 86 | 
             
                requirements:
         | 
| 73 | 
            -
                - -  | 
| 87 | 
            +
                - - ~>
         | 
| 74 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 89 | 
             
                    version: '1.1'
         | 
| 76 90 | 
             
              type: :development
         | 
| 77 91 | 
             
              prerelease: false
         | 
| 78 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 93 | 
             
                requirements:
         | 
| 80 | 
            -
                - -  | 
| 94 | 
            +
                - - ~>
         | 
| 81 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 96 | 
             
                    version: '1.1'
         | 
| 83 97 | 
             
            description: |2
         | 
| @@ -91,13 +105,10 @@ extensions: [] | |
| 91 105 | 
             
            extra_rdoc_files: []
         | 
| 92 106 | 
             
            files:
         | 
| 93 107 | 
             
            - Gemfile
         | 
| 94 | 
            -
            - LICENSE
         | 
| 95 108 | 
             
            - README.md
         | 
| 96 | 
            -
            -  | 
| 97 | 
            -
            - lib/twine.rb
         | 
| 109 | 
            +
            - LICENSE
         | 
| 98 110 | 
             
            - lib/twine/cli.rb
         | 
| 99 111 | 
             
            - lib/twine/encoding.rb
         | 
| 100 | 
            -
            - lib/twine/formatters.rb
         | 
| 101 112 | 
             
            - lib/twine/formatters/abstract.rb
         | 
| 102 113 | 
             
            - lib/twine/formatters/android.rb
         | 
| 103 114 | 
             
            - lib/twine/formatters/apple.rb
         | 
| @@ -106,12 +117,15 @@ files: | |
| 106 117 | 
             
            - lib/twine/formatters/gettext.rb
         | 
| 107 118 | 
             
            - lib/twine/formatters/jquery.rb
         | 
| 108 119 | 
             
            - lib/twine/formatters/tizen.rb
         | 
| 120 | 
            +
            - lib/twine/formatters.rb
         | 
| 109 121 | 
             
            - lib/twine/output_processor.rb
         | 
| 110 122 | 
             
            - lib/twine/placeholders.rb
         | 
| 111 123 | 
             
            - lib/twine/plugin.rb
         | 
| 112 124 | 
             
            - lib/twine/runner.rb
         | 
| 113 125 | 
             
            - lib/twine/twine_file.rb
         | 
| 114 126 | 
             
            - lib/twine/version.rb
         | 
| 127 | 
            +
            - lib/twine.rb
         | 
| 128 | 
            +
            - bin/twine
         | 
| 115 129 | 
             
            - test/command_test.rb
         | 
| 116 130 | 
             
            - test/fixtures/consume_localization_archive.zip
         | 
| 117 131 | 
             
            - test/fixtures/enc_utf16be.dummy
         | 
| @@ -153,17 +167,17 @@ require_paths: | |
| 153 167 | 
             
            - lib
         | 
| 154 168 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 155 169 | 
             
              requirements:
         | 
| 156 | 
            -
              - -  | 
| 170 | 
            +
              - - '>='
         | 
| 157 171 | 
             
                - !ruby/object:Gem::Version
         | 
| 158 172 | 
             
                  version: '2.0'
         | 
| 159 173 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 160 174 | 
             
              requirements:
         | 
| 161 | 
            -
              - -  | 
| 175 | 
            +
              - - '>='
         | 
| 162 176 | 
             
                - !ruby/object:Gem::Version
         | 
| 163 177 | 
             
                  version: '0'
         | 
| 164 178 | 
             
            requirements: []
         | 
| 165 179 | 
             
            rubyforge_project: 
         | 
| 166 | 
            -
            rubygems_version: 2. | 
| 180 | 
            +
            rubygems_version: 2.0.14.1
         | 
| 167 181 | 
             
            signing_key: 
         | 
| 168 182 | 
             
            specification_version: 4
         | 
| 169 183 | 
             
            summary: Manage strings and their translations for your iOS, Android and other projects.
         |