puttext 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 823ff8ebbbb9be8b240a4f4fe20472a1ef871c5b
4
+ data.tar.gz: c8ea456d1fb5f0de5c98591f05d3c2b14ce3f8f4
5
+ SHA512:
6
+ metadata.gz: 33d5d1d97efe0ebb8e0e69192a358462739dad3879c5b58fbf7d087cff10f253d81587ddf0efa1d559bbf6b395446f32d7bd3be07dd695c191815847c79b700a
7
+ data.tar.gz: 73e68f79ad334014c5309e38550fc1d990bad7d757f888dda4285e693553692c72675c243406c5c0a7779792ae089d8a427bd0a0bffbe88042b3635d37851abe
@@ -0,0 +1,19 @@
1
+ ---
2
+ engines:
3
+ bundler-audit:
4
+ enabled: true
5
+ duplication:
6
+ enabled: true
7
+ config:
8
+ languages:
9
+ - ruby
10
+ fixme:
11
+ enabled: true
12
+ rubocop:
13
+ enabled: true
14
+ ratings:
15
+ paths:
16
+ - Gemfile.lock
17
+ - "**.rb"
18
+ exclude_paths:
19
+ - spec/
@@ -0,0 +1,17 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text eol=lf
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+
7
+ # Standard to msysgit
8
+ *.doc diff=astextplain
9
+ *.DOC diff=astextplain
10
+ *.docx diff=astextplain
11
+ *.DOCX diff=astextplain
12
+ *.dot diff=astextplain
13
+ *.DOT diff=astextplain
14
+ *.pdf diff=astextplain
15
+ *.PDF diff=astextplain
16
+ *.rtf diff=astextplain
17
+ *.RTF diff=astextplain
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,26 @@
1
+ # This is the configuration used to check the rubocop source code.
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - 'spec/fixtures/**/*'
6
+ TargetRubyVersion: 2.0
7
+
8
+ Documentation:
9
+ Enabled: false
10
+
11
+ Metrics/BlockLength:
12
+ Exclude:
13
+ - 'spec/**/*.rb'
14
+
15
+ Metrics/ClassLength:
16
+ Max: 150
17
+
18
+ Metrics/ModuleLength:
19
+ Exclude:
20
+ - 'spec/**/*.rb'
21
+
22
+ Style/EndOfLine:
23
+ Enabled: false
24
+
25
+ Style/NumericPredicate:
26
+ EnforcedStyle: comparison
@@ -0,0 +1 @@
1
+ 2.4.0
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+
3
+ addons:
4
+ code_climate:
5
+ repo_token: 2df66540ac895ba609ec19665a233e73dc7b4d3f3e0c788c4b99ed974765d4bf
6
+
7
+ after_success:
8
+ - bundle exec codeclimate-test-reporter
9
+
10
+ notifications:
11
+ email: false
12
+
13
+ rvm:
14
+ - 2.0.0
15
+ - 2.1.10
16
+ - 2.2.7
17
+ - 2.3.4
18
+ - 2.4.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in puttext.gemspec
6
+ gemspec
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ puttext (0.0.1)
5
+ parser (>= 2.4.0.0, < 3.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.3.0)
11
+ codeclimate-test-reporter (1.0.8)
12
+ simplecov (<= 0.13)
13
+ diff-lcs (1.3)
14
+ docile (1.1.5)
15
+ json (2.0.4)
16
+ parser (2.4.0.0)
17
+ ast (~> 2.2)
18
+ powerpack (0.1.1)
19
+ rainbow (2.2.1)
20
+ rake (12.0.0)
21
+ rspec (3.5.0)
22
+ rspec-core (~> 3.5.0)
23
+ rspec-expectations (~> 3.5.0)
24
+ rspec-mocks (~> 3.5.0)
25
+ rspec-core (3.5.4)
26
+ rspec-support (~> 3.5.0)
27
+ rspec-expectations (3.5.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.5.0)
30
+ rspec-mocks (3.5.0)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.5.0)
33
+ rspec-support (3.5.0)
34
+ rubocop (0.46.0)
35
+ parser (>= 2.3.1.1, < 3.0)
36
+ powerpack (~> 0.1)
37
+ rainbow (>= 1.99.1, < 3.0)
38
+ ruby-progressbar (~> 1.7)
39
+ unicode-display_width (~> 1.0, >= 1.0.1)
40
+ ruby-progressbar (1.8.1)
41
+ simplecov (0.13.0)
42
+ docile (~> 1.1.0)
43
+ json (>= 1.8, < 3)
44
+ simplecov-html (~> 0.10.0)
45
+ simplecov-html (0.10.0)
46
+ slim (3.0.7)
47
+ temple (~> 0.7.6)
48
+ tilt (>= 1.3.3, < 2.1)
49
+ temple (0.7.7)
50
+ tilt (2.0.7)
51
+ unicode-display_width (1.2.1)
52
+ unindent (1.0)
53
+
54
+ PLATFORMS
55
+ ruby
56
+
57
+ DEPENDENCIES
58
+ codeclimate-test-reporter (~> 1.0.0)
59
+ puttext!
60
+ rake
61
+ rspec (~> 3.5)
62
+ rubocop (~> 0.46.0)
63
+ simplecov
64
+ slim (~> 3.0)
65
+ unindent
66
+
67
+ BUNDLED WITH
68
+ 1.14.6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Mantas Norvaiša
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,82 @@
1
+ [![Build Status](https://travis-ci.org/mntnorv/puttext.svg)](https://travis-ci.org/mntnorv/puttext)
2
+ [![Code Climate](https://codeclimate.com/github/mntnorv/puttext/badges/gpa.svg)](https://codeclimate.com/github/mntnorv/puttext)
3
+ [![Test Coverage](https://codeclimate.com/github/mntnorv/puttext/badges/coverage.svg)](https://codeclimate.com/github/mntnorv/puttext/coverage)
4
+
5
+ # puttext
6
+
7
+ Put translatable gettext strings from your Ruby code to a `.po` or `.pot` file.
8
+
9
+ For example, if you have this `translatable.rb` file:
10
+ ```ruby
11
+ puts _('translatable string')
12
+ ```
13
+
14
+ You get this output:
15
+ ```po
16
+ #: translatable.rb:1
17
+ msgid "translatable string"
18
+ msgtxt ""
19
+ ```
20
+
21
+ ## Language support
22
+
23
+ Supports extracting strings from these types of files:
24
+ - Ruby
25
+ - Slim
26
+
27
+ ## Installation
28
+
29
+ Using RubyGems:
30
+ ```bash
31
+ $ gem install puttext
32
+ ```
33
+
34
+ Or add it to your `Gemfile` if using Bundler:
35
+ ```ruby
36
+ gem 'puttext', require: false
37
+ ```
38
+
39
+ Also, if you want additional language support beyond plain Ruby, install these gems:
40
+ - [**slim**](https://github.com/slim-template/slim) for Slim support.
41
+
42
+
43
+ ## Usage
44
+
45
+ Just run the `puttext` command line tool and point it to your Ruby project:
46
+ ```bash
47
+ $ puttext /path/to/your/project
48
+ ```
49
+
50
+ ### Options
51
+
52
+ #### `-o`, `--output`
53
+
54
+ By default `puttext` will output the extracted PO file contents to stdout. You can write the output to a file by specifying the `-o`, `--output` option.
55
+
56
+ ```bash
57
+ $ puttext /path/to/your/project -o template.pot
58
+ ```
59
+
60
+ ## Contributing
61
+
62
+ Before submitting an Issue or Pull Request always check if your issue is already being discussed or if someone has already submitted a pull request with the feature you want to add. Also, before doing bigger changes, it's always good to discuss the changes you're going to make in an Issue.
63
+
64
+ ### Code style
65
+
66
+ PutText uses RuboCop (https://github.com/bbatsov/rubocop) to check and enforce code style. Before submitting a pull request, make sure that RuboCop does not find any offenses.
67
+
68
+ #### Running RuboCop
69
+
70
+ ```bash
71
+ $ bundle exec rubocop
72
+ ```
73
+
74
+ ### Testing
75
+
76
+ PutText uses RSpec (http://rspec.info/) for testing. Pull requests with Ruby code changes must include RSpec tests that check the new functionality or changed code. Also, make sure that your changes do not break any existing tests.
77
+
78
+ #### Running RSpec
79
+
80
+ ```bash
81
+ $ bundle exec rspec
82
+ ```
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: [:spec]
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/puttext/cmdline'
5
+
6
+ PutText::Cmdline.run(ARGV)
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'puttext/extractor'
4
+
5
+ module PutText
6
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'extractor'
4
+ require 'optparse'
5
+
6
+ module PutText
7
+ class Cmdline
8
+ USAGE_TEXT = 'Usage: puttext LOCATION [options]'.freeze
9
+
10
+ # Run the commmand line tool puttext.
11
+ # @param [Array<String>] args the command line arguments.
12
+ def self.run(args)
13
+ new.run(args)
14
+ end
15
+
16
+ # Run the commmand line tool puttext.
17
+ # @param [Array<String>] args the command line arguments.
18
+ def run(args)
19
+ options = parse_args(args)
20
+ po_file = Extractor.new.extract(options[:path])
21
+
22
+ if options[:output_file]
23
+ with_output_file(options[:output_file]) { |f| po_file.write_to(f) }
24
+ else
25
+ po_file.write_to(STDOUT)
26
+ end
27
+ rescue => e
28
+ error(e)
29
+ end
30
+
31
+ private
32
+
33
+ def with_output_file(path)
34
+ File.open(path, 'w') do |f|
35
+ yield(f)
36
+ end
37
+ end
38
+
39
+ def error(exception)
40
+ puts "error: #{exception.message}"
41
+ puts exception.backtrace
42
+ exit 1
43
+ end
44
+
45
+ def parse_args(args)
46
+ args_left, options = parse_options(args)
47
+
48
+ if args_left.length != 1
49
+ puts USAGE_TEXT
50
+ exit 1
51
+ else
52
+ options[:path] = args_left[0]
53
+ options
54
+ end
55
+ end
56
+
57
+ def parse_options(args)
58
+ options = {}
59
+
60
+ args_left = OptionParser.new do |opts|
61
+ opts.banner = USAGE_TEXT
62
+
63
+ opts.on('-o', '--output PATH', 'Output file path') do |o|
64
+ options[:output_file] = o
65
+ end
66
+ end.parse!(args)
67
+
68
+ [args_left, options]
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'parser/ruby'
4
+ require_relative 'parser/slim'
5
+ require_relative 'po_file'
6
+
7
+ module PutText
8
+ class Extractor
9
+ EXTENSIONS = {
10
+ '.rb' => 'Ruby',
11
+ '.slim' => 'Slim'
12
+ }.freeze
13
+
14
+ # Thrown when a given file cannot be parsed, because its format or language
15
+ # is not supported.
16
+ class UnsupportedFileError < StandardError; end
17
+
18
+ # Thrown when the path passed to #extract does not exist.
19
+ class NoSuchFileError < StandardError; end
20
+
21
+ # Return the class of a parser by its name
22
+ # @param [String] name the name of the parser.
23
+ # @return [Class] the classof the parser
24
+ def self.parser_class_by_name(name)
25
+ PutText::Parser.const_get(name)
26
+ end
27
+
28
+ # Check if a file is supported by the parser, based on its extension.
29
+ # @return [Boolean] whether the file is supported.
30
+ def self.file_supported?(path)
31
+ EXTENSIONS.each do |ext, parser_name|
32
+ next unless path.end_with?(ext)
33
+ next unless parser_class_by_name(parser_name)
34
+ return true
35
+ end
36
+
37
+ false
38
+ end
39
+
40
+ # Extract strings from files in the given path.
41
+ # @param [String] path the path of a directory or file to extract strings
42
+ # from.
43
+ # @return [POFile] a POFile object, representing the strings extracted from
44
+ # the files or file in the specified path.
45
+ def extract(path)
46
+ files = files_in_path(path)
47
+ supported_files = filter_files(files)
48
+
49
+ parse_files(supported_files)
50
+ end
51
+
52
+ # Parse gettext strings from a file in the path.
53
+ # @param [String] path the path of the file to parse.
54
+ # @return [Array<POEntry>] an array of POEntry objects extracted
55
+ # from the given file.
56
+ def extract_from_file(path)
57
+ parser_by_path(path).strings_from_file(path)
58
+ end
59
+
60
+ private
61
+
62
+ def parser_by_name(name)
63
+ return @parsers[name] if @parsers && @parsers[name]
64
+
65
+ @parsers ||= {}
66
+ parser_class = self.class.parser_class_by_name(name)
67
+ return unless parser_class
68
+
69
+ parser = parser_class.new
70
+ @parsers[name] = parser
71
+ parser
72
+ end
73
+
74
+ def parser_by_path(path)
75
+ EXTENSIONS.each do |ext, name|
76
+ return parser_by_name(name) if path.end_with?(ext)
77
+ end
78
+
79
+ raise UnsupportedFileError, format('file not supported: %s', path)
80
+ end
81
+
82
+ def parse_files(files)
83
+ entries = []
84
+
85
+ files.each do |path|
86
+ entries += extract_from_file(path)
87
+ end
88
+
89
+ POFile.new(entries)
90
+ end
91
+
92
+ def filter_files(files)
93
+ supported_files = files.select do |file|
94
+ self.class.file_supported?(file)
95
+ end
96
+
97
+ supported_files
98
+ end
99
+
100
+ def files_in_path(path)
101
+ files = []
102
+
103
+ if File.file?(path)
104
+ files = [path]
105
+ elsif File.directory?(path)
106
+ files = Dir.glob(File.join(path, '**/*'))
107
+ else
108
+ raise NoSuchFileError, format('no such file or directory: %s', path)
109
+ end
110
+
111
+ files
112
+ end
113
+ end
114
+ end