utcd 0.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1999018864ed7a8696ffd804a3450f4d65a2fde7c888642263fda60ebd91a42f
4
+ data.tar.gz: 9572f56a6cf25e71d46d5ef8f0288df9f64fb83a4b6eeb4c4353e95085ba2dbc
5
+ SHA512:
6
+ metadata.gz: 47e0bd79c416f75f84a1490b6ee8570688f1d580b46e086a00d0476d5bf6d13b42ef2593efb5101fff9b343c0acb04abe84259fe60aa8572e47ee0805edda0e7
7
+ data.tar.gz: 21cc114231f130cea92d05b21a5de8df42619ff71a26e9c70149be6bf0c6a64b67ce6e3754ac92973dd8ea39664a356053001d213dab555f79a50943e5b0534b
data/.DS_Store ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ LocalizableFiles/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,116 @@
1
+ Style/FrozenStringLiteralComment:
2
+ Enabled: false
3
+ Gemspec/DateAssignment: # new in 1.10
4
+ Enabled: true
5
+ Gemspec/RequireMFA: # new in 1.23
6
+ Enabled: true
7
+ Layout/LineEndStringConcatenationIndentation: # new in 1.18
8
+ Enabled: true
9
+ Layout/SpaceBeforeBrackets: # new in 1.7
10
+ Enabled: true
11
+ Lint/AmbiguousAssignment: # new in 1.7
12
+ Enabled: true
13
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
14
+ Enabled: true
15
+ Lint/AmbiguousRange: # new in 1.19
16
+ Enabled: true
17
+ Lint/DeprecatedConstants: # new in 1.8
18
+ Enabled: true
19
+ Lint/DuplicateBranch: # new in 1.3
20
+ Enabled: true
21
+ Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
22
+ Enabled: true
23
+ Lint/EmptyBlock: # new in 1.1
24
+ Enabled: true
25
+ Lint/EmptyClass: # new in 1.3
26
+ Enabled: true
27
+ Lint/EmptyInPattern: # new in 1.16
28
+ Enabled: true
29
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
30
+ Enabled: true
31
+ Lint/LambdaWithoutLiteralBlock: # new in 1.8
32
+ Enabled: true
33
+ Lint/NoReturnInBeginEndBlocks: # new in 1.2
34
+ Enabled: true
35
+ Lint/NumberedParameterAssignment: # new in 1.9
36
+ Enabled: true
37
+ Lint/OrAssignmentToConstant: # new in 1.9
38
+ Enabled: true
39
+ Lint/RedundantDirGlobSort: # new in 1.8
40
+ Enabled: true
41
+ Lint/RefinementImportMethods: # new in 1.27
42
+ Enabled: true
43
+ Lint/RequireRelativeSelfPath: # new in 1.22
44
+ Enabled: true
45
+ Lint/SymbolConversion: # new in 1.9
46
+ Enabled: true
47
+ Lint/ToEnumArguments: # new in 1.1
48
+ Enabled: true
49
+ Lint/TripleQuotes: # new in 1.9
50
+ Enabled: true
51
+ Lint/UnexpectedBlockArity: # new in 1.5
52
+ Enabled: true
53
+ Lint/UnmodifiedReduceAccumulator: # new in 1.1
54
+ Enabled: true
55
+ Lint/UselessRuby2Keywords: # new in 1.23
56
+ Enabled: true
57
+ Naming/BlockForwarding: # new in 1.24
58
+ Enabled: true
59
+ Security/CompoundHash: # new in 1.28
60
+ Enabled: true
61
+ Security/IoMethods: # new in 1.22
62
+ Enabled: true
63
+ Style/ArgumentsForwarding: # new in 1.1
64
+ Enabled: true
65
+ Style/CollectionCompact: # new in 1.2
66
+ Enabled: true
67
+ Style/DocumentDynamicEvalDefinition: # new in 1.1
68
+ Enabled: true
69
+ Style/EndlessMethod: # new in 1.8
70
+ Enabled: true
71
+ Style/FetchEnvVar: # new in 1.28
72
+ Enabled: true
73
+ Style/FileRead: # new in 1.24
74
+ Enabled: true
75
+ Style/FileWrite: # new in 1.24
76
+ Enabled: true
77
+ Style/HashConversion: # new in 1.10
78
+ Enabled: true
79
+ Style/HashExcept: # new in 1.7
80
+ Enabled: true
81
+ Style/IfWithBooleanLiteralBranches: # new in 1.9
82
+ Enabled: true
83
+ Style/InPatternThen: # new in 1.16
84
+ Enabled: true
85
+ Style/MapToHash: # new in 1.24
86
+ Enabled: true
87
+ Style/MultilineInPatternThen: # new in 1.16
88
+ Enabled: true
89
+ Style/NegatedIfElseCondition: # new in 1.2
90
+ Enabled: true
91
+ Style/NestedFileDirname: # new in 1.26
92
+ Enabled: true
93
+ Style/NilLambda: # new in 1.3
94
+ Enabled: true
95
+ Style/NumberedParameters: # new in 1.22
96
+ Enabled: true
97
+ Style/NumberedParametersLimit: # new in 1.22
98
+ Enabled: true
99
+ Style/ObjectThen: # new in 1.28
100
+ Enabled: true
101
+ Style/OpenStructUse: # new in 1.23
102
+ Enabled: true
103
+ Style/QuotedSymbols: # new in 1.16
104
+ Enabled: true
105
+ Style/RedundantArgument: # new in 1.4
106
+ Enabled: true
107
+ Style/RedundantInitialize: # new in 1.27
108
+ Enabled: true
109
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
110
+ Enabled: true
111
+ Style/SelectByRegexp: # new in 1.22
112
+ Enabled: true
113
+ Style/StringChars: # new in 1.12
114
+ Enabled: true
115
+ Style/SwapValues: # new in 1.1
116
+ Enabled: true
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.4
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,16 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "type": "ruby-debug",
9
+ "request": "launch",
10
+ "name": "Launch File",
11
+ "program": "${workspaceFolder}/lib/utcd.rb",
12
+ "programArgs": [],
13
+ "useBundler": false
14
+ }
15
+ ]
16
+ }
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in utcd.gemspec
4
+ gemspec
5
+
6
+ gem 'apfel'
7
+ gem 'graphql-client'
8
+ gem 'rake', '~> 12.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'rest-client', '~> 2.0'
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ utcd (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (7.0.3)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 1.6, < 2)
12
+ minitest (>= 5.1)
13
+ tzinfo (~> 2.0)
14
+ apfel (0.0.5)
15
+ concurrent-ruby (1.1.10)
16
+ diff-lcs (1.5.0)
17
+ domain_name (0.5.20190701)
18
+ unf (>= 0.0.5, < 1.0.0)
19
+ graphql (2.0.11)
20
+ graphql-client (0.18.0)
21
+ activesupport (>= 3.0)
22
+ graphql
23
+ http-accept (1.7.0)
24
+ http-cookie (1.0.5)
25
+ domain_name (~> 0.5)
26
+ i18n (1.10.0)
27
+ concurrent-ruby (~> 1.0)
28
+ mime-types (3.4.1)
29
+ mime-types-data (~> 3.2015)
30
+ mime-types-data (3.2022.0105)
31
+ minitest (5.16.2)
32
+ netrc (0.11.0)
33
+ rake (12.3.3)
34
+ rest-client (2.1.0)
35
+ http-accept (>= 1.7.0, < 2.0)
36
+ http-cookie (>= 1.0.2, < 2.0)
37
+ mime-types (>= 1.16, < 4.0)
38
+ netrc (~> 0.8)
39
+ rspec (3.11.0)
40
+ rspec-core (~> 3.11.0)
41
+ rspec-expectations (~> 3.11.0)
42
+ rspec-mocks (~> 3.11.0)
43
+ rspec-core (3.11.0)
44
+ rspec-support (~> 3.11.0)
45
+ rspec-expectations (3.11.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.11.0)
48
+ rspec-mocks (3.11.1)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.11.0)
51
+ rspec-support (3.11.0)
52
+ tzinfo (2.0.4)
53
+ concurrent-ruby (~> 1.0)
54
+ unf (0.1.4)
55
+ unf_ext
56
+ unf_ext (0.0.8.2)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ apfel
63
+ graphql-client
64
+ rake (~> 12.0)
65
+ rest-client (~> 2.0)
66
+ rspec (~> 3.0)
67
+ utcd!
68
+
69
+ BUNDLED WITH
70
+ 2.1.4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Rodrigo
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Utcd
2
+ This gem will allow you to handle your localizable files stored and shared on a private server. Allowing anyone on your team to edit them and share them with you.
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'utcd'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle install
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install utcd
19
+
20
+ ## Usage
21
+ Search in ~/.rvm/gemsets/global.gems
22
+
23
+ ## License
24
+
25
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ task :test do
9
+ bundle exec 'rspec'
10
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'utcd'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
data/bin/rspec ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path('bundle', __dir__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require 'rubygems'
27
+ require 'bundler/setup'
28
+
29
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/api.rb ADDED
@@ -0,0 +1,59 @@
1
+ require 'graphql/client'
2
+ require 'graphql/client/http'
3
+ require_relative 'queries'
4
+ require 'rest_client'
5
+ require_relative 'tools'
6
+
7
+ module API
8
+ extend self
9
+ extend Queries
10
+ extend Tools
11
+
12
+ def check_server_locales
13
+ # Execute the query
14
+ result = Queries::Client.query(Queries::RetrieveAllLocales)
15
+ # Check for errors
16
+ raise result.errors.first.message if result.errors.any?
17
+ # Print array of locales
18
+ puts "________ LOCALES ON SERVER ________"
19
+ puts result.data.all_locales.map { |locale| "- #{locale}" }
20
+ end
21
+
22
+ def check_server_locales_for_platform(platform)
23
+ # Execute the query
24
+ result = Queries::Client.query(Queries::RetrieveAllLocalesForPlatform, variables: {platform: platform})
25
+ # Check for errors
26
+ raise result.errors.first.message if result.errors.any?
27
+ # Print array of locales
28
+ puts "________ LOCALES ON SERVER: #{platform.upcase}________"
29
+ puts result.data.all_locales_for_platform.map { |locale| "- #{locale}" }
30
+ end
31
+
32
+ def upload_server_locale_file(path, platform, locale)
33
+ url = "#{Constants::BASE_URI}/upload?folder=#{platform}/#{locale}"
34
+ response = RestClient.post url, {:file => File.new(path, "rb"), :multipart => true}
35
+ return response.gsub(/\"/, '').split('/').last
36
+ end
37
+
38
+ def download_server_locale_file(path)
39
+ url = "http://localhost:8080/files#{path}"
40
+ result = RestClient.get url
41
+ return result
42
+ end
43
+
44
+ def create_segment_on_server(file_name, locale)
45
+ # Execute the query
46
+ result = Queries::Client.query(Queries::CreateSegment, variables: {language: locale, platform: platform, fileName: file_name})
47
+ # Check for errors
48
+ raise result.errors.first.message if result.errors.any?
49
+ end
50
+
51
+ def retrieve_server_translations_for_locale(locale)
52
+ # Execute the query
53
+ result = Queries::Client.query(Queries::RetrieveTranslationsForLocale, variables: {platform: platform, locale: locale})
54
+ # Check for errors
55
+ raise result.errors.first.message if result.errors.any?
56
+ # Return array of paths
57
+ return result.data.find_translations_for_locale.map { |translation| create_path_from_segment(translation) }
58
+ end
59
+ end
data/lib/constants.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Constants
2
+ extend self
3
+ BASE_URI = 'http://localhost:8080'
4
+ end
data/lib/network.rb ADDED
@@ -0,0 +1,18 @@
1
+ require_relative 'constants'
2
+
3
+ module Network
4
+ extend self
5
+ extend Constants
6
+
7
+ HTTP = GraphQL::Client::HTTP.new("#{Constants::BASE_URI}/graphql") do
8
+ def headers(_context)
9
+ { 'User-Agent': 'My Client' }
10
+ end
11
+ end
12
+
13
+ Schema = GraphQL::Client.load_schema('./schema.json')
14
+
15
+ def create_schema
16
+ GraphQL::Client.dump_schema(Network::HTTP, './schema.json')
17
+ end
18
+ end
data/lib/queries.rb ADDED
@@ -0,0 +1,49 @@
1
+ require_relative 'network'
2
+
3
+ module Queries
4
+ extend Network
5
+ extend self
6
+
7
+ Client = GraphQL::Client.new(schema: Network::Schema, execute: Network::HTTP)
8
+
9
+ RetrieveAllLocales = Client.parse <<-'GRAPHQL'
10
+ query {
11
+ allLocales
12
+ }
13
+ GRAPHQL
14
+
15
+ RetrieveAllLocalesForPlatform = Client.parse <<-'GRAPHQL'
16
+ query($platform: String!) {
17
+ allLocalesForPlatform(input: { platform: $platform })
18
+ }
19
+ GRAPHQL
20
+
21
+ CreateSegment = Client.parse <<-'GRAPHQL'
22
+ mutation (
23
+ $language: String!
24
+ $platform: String!
25
+ $fileName: String!
26
+ ) {
27
+ createTranslation(
28
+ input: { language: $language, platform: $platform, fileName: $fileName }
29
+ ) {
30
+ id
31
+ language
32
+ platform
33
+ fileName
34
+ }
35
+ }
36
+ GRAPHQL
37
+
38
+ RetrieveTranslationsForLocale = Client.parse <<-'GRAPHQL'
39
+ query ($platform: String!, $locale: String!) {
40
+ findTranslationsForLocale(input: { platform: $platform, locale: $locale }) {
41
+ id
42
+ language
43
+ platform
44
+ fileName
45
+ }
46
+ }
47
+ GRAPHQL
48
+
49
+ end
data/lib/tools.rb ADDED
@@ -0,0 +1,64 @@
1
+ module Tools
2
+ extend self
3
+
4
+ def retrieve_localizable_folder_path
5
+ localizable_file_path = Dir.glob("#{Dir.pwd}/**/*#{platform_extension}").first
6
+ return nil if localizable_file_path.nil?
7
+
8
+ localizable_file_path.gsub(%r{/[^/]+$}, '')
9
+ end
10
+
11
+ def retrieve_files_in_locale(locale)
12
+ localizable_folder_path = retrieve_localizable_folder_path
13
+ return nil if localizable_folder_path.nil?
14
+
15
+ Dir.glob("#{localizable_folder_path}/#{locale}#{platform_extension}/*.strings")
16
+ end
17
+
18
+ def retrieve_locales
19
+ languages = Dir.glob("#{Dir.pwd}/**/*#{platform_extension}")
20
+ languages.map { |language| language.split('/').last.split('.').first }
21
+ end
22
+
23
+ def read_localizable_file(file)
24
+ Apfel.parse(file).key_values
25
+ end
26
+
27
+ def status
28
+ locales = retrieve_locales
29
+ puts 'Used locales:'
30
+ for locale in locales
31
+ files_in_locale = Dir.glob("#{retrieve_localizable_folder_path}/#{locale}.lproj/*.strings")
32
+ puts "\n_______________ #{locale.upcase} _______________"
33
+ for file in files_in_locale
34
+ puts " #{file.split('/').last}"
35
+ end
36
+ end
37
+ end
38
+
39
+ def platform
40
+ ios_folder = Dir.glob("#{Dir.pwd}/**/*#{'.lproj'}").first
41
+ unless ios_folder.nil?
42
+ return "ios"
43
+ end
44
+
45
+ android_folder = Dir.glob("#{Dir.pwd}/**/*#{'.android'}").first
46
+ unless android_folder.nil?
47
+ return "android"
48
+ end
49
+
50
+ raise Error, 'No localizable files in project' if localizable_file_path.nil?
51
+ end
52
+
53
+ def platform_extension
54
+ platform == 'ios' ? '.lproj' : '.android'
55
+ end
56
+
57
+ def create_path_from_segment(segment)
58
+ "/#{segment.platform}/#{segment.language}/#{segment.file_name}"
59
+ end
60
+
61
+ def write_to_file(path, content)
62
+ File.open(path, 'w') { |file| file.write(content) }
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module Utcd
2
+ VERSION = '0.2.0'.freeze
3
+ end
data/lib/utcd.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'utcd/version'
2
+ require_relative 'tools'
3
+ require_relative 'api'
4
+ require 'apfel'
5
+
6
+ module Utcd
7
+ extend Tools
8
+ extend API
9
+
10
+ def self.push(locale)
11
+ # 1º. Check that the locale folder is not empty
12
+ files = retrieve_files_in_locale(locale)
13
+ if files.nil? || files.empty? then
14
+ puts "No files found for locale #{locale}"
15
+ end
16
+
17
+ # 2. Upload synchronously all files in the locale folder
18
+ current_platform = platform
19
+ puts "Uploading files for locale #{locale}"
20
+ for file_path in files
21
+ file_path = upload_server_locale_file(file_path, platform, locale)
22
+ create_segment_on_server(file_path, locale)
23
+ puts "- #{file_path}"
24
+ end
25
+ end
26
+
27
+ def self.pull(locale)
28
+ # 1. Get all server files for chosen locale
29
+ server_files = retrieve_server_translations_for_locale(locale)
30
+
31
+ # 2. Download synchronously all files and swap them with local files
32
+ puts "Updating files for locale #{locale}"
33
+ for file in server_files
34
+ content = download_server_locale_file(file)
35
+ file_name = file.split('/').last
36
+ folder_path = "#{retrieve_localizable_folder_path}/#{locale}#{platform_extension}/#{file_name}"
37
+ write_to_file(folder_path, content)
38
+ puts " - #{locale}#{platform_extension}/#{file_name}"
39
+ end
40
+ end
41
+ end