phraseapp_updater 2.1.2 → 3.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cb9f8e20f3b078b508e5e427e98d9c62153e02e88542ecf43fc774bef05125f
4
- data.tar.gz: e5110c0c2534f4e5819007aa0209ab2efec954a6ce461c404d01ff177b6cfd91
3
+ metadata.gz: f33deb3a77a37a47abdf44c354526cbe3ad3d10256bb2a046bf48922178187fd
4
+ data.tar.gz: f22f2ceed18653b09c24be4724707cdc40c39539535c226fd028bc03338437cd
5
5
  SHA512:
6
- metadata.gz: 1a650fd825eb3f37e55388509b23f57b0cfb2a8e5a7235d275ce4b8259f8fc82c955ac54ad701bbfa1fcd7f2689ae16c796133b35a95417536d0632c1cde22a2
7
- data.tar.gz: 6108be4a1d29345d3063dd4cf94972aae52de8f67088cd70ff6fcccd4907128f587fbfe721d90f4856bf07707b7271be28ddb81c4b55162fcdc8d944580d6704
6
+ metadata.gz: 822cc67247e2e2752397127f6b4e5e0d893cdfc3c64a29f14067d2bc5b6e131f3924d5cad982960df65da4b47971c12ad43fc9caf9c9ff15e756a596a64c163e
7
+ data.tar.gz: a2e1152e1a376690722722d73c2654d4ab4e417530b66b86f7562cd0b17e54f06976a295bae601ec0d4ed1e8570a518eef9a37ff317f24001643e711c0365e6c
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
3
  # Set up a working directory
4
- working_directory=$(mktemp -d -t phraseapp.XXXXXX)
4
+ working_directory=$(mktemp -d phraseapp.XXXXXX)
5
5
 
6
6
  function cleanup_working_directory(){
7
7
  local now archive
8
8
  now="$(date "+%Y%m%d%H%M%S")"
9
9
  archive="/tmp/phraseapp-updater-$now.tar.gz"
10
- tar czf "$archive" "${working_directory}"
10
+ tar -C "$(dirname "$working_directory")" -czf "$archive" "$(basename "${working_directory}")"
11
11
  rm -rf "${working_directory}"
12
12
  echo "Working files saved to $archive"
13
13
  }
@@ -41,15 +41,15 @@ function make_tree_from_directory() {
41
41
  }
42
42
 
43
43
 
44
- function extract_commit() {
45
- extract_files "$1:${PREFIX}"
44
+ function extract_prefix_from_commit() {
45
+ extract_files "$1" "$2:${PREFIX}"
46
46
  }
47
47
 
48
48
  function extract_files() {
49
49
  local path
50
- path=$(make_temporary_directory "git.${1%%:*}")
50
+ path=$(make_temporary_directory "git.${1}.${2%%:*}")
51
51
 
52
- git archive --format=tar "$1" | tar -x -C "${path}"
52
+ git archive --format=tar "$2" | tar -x -C "${path}"
53
53
 
54
54
  echo "${path}"
55
55
  }
@@ -61,8 +61,8 @@ elif ! git merge-base --is-ancestor "${common_ancestor}" "${current_branch}"; th
61
61
  skip_ancestor_merge=t
62
62
  fi
63
63
 
64
- current_branch_path=$(extract_commit "${current_branch}")
65
- common_ancestor_path=$(extract_commit "${common_ancestor}")
64
+ current_branch_path=$(extract_prefix_from_commit current_branch "${current_branch}")
65
+ common_ancestor_path=$(extract_prefix_from_commit common_ancestor "${common_ancestor}")
66
66
 
67
67
  current_phraseapp_tree=$(make_tree_from_directory "${current_phraseapp_path}")
68
68
 
@@ -2,7 +2,8 @@
2
2
 
3
3
  require 'phraseapp_updater/locale_file'
4
4
  require 'phraseapp_updater/index_by'
5
- require 'phraseapp-ruby'
5
+ require 'uri'
6
+ require 'phrase'
6
7
  require 'parallel'
7
8
  require 'tempfile'
8
9
 
@@ -13,16 +14,24 @@ class PhraseAppUpdater
13
14
  PAGE_SIZE = 100
14
15
 
15
16
  def initialize(api_key, project_id, locale_file_class)
16
- @client = PhraseApp::Client.new(PhraseApp::Auth::Credentials.new(token: api_key))
17
+ config = Phrase::Configuration.new do |c|
18
+ c.api_key['Authorization'] = api_key
19
+ c.api_key_prefix['Authorization'] = 'token'
20
+ c.debugging = false
21
+ end
22
+
23
+ @client = Phrase::ApiClient.new(config)
17
24
  @project_id = project_id
18
25
  @locale_file_class = locale_file_class
19
26
  end
20
27
 
21
28
  def create_project(name, parent_commit)
22
- params = PhraseApp::RequestParams::ProjectParams.new(
29
+ params = Phrase::ProjectCreateParameters.new(
23
30
  name: name,
24
31
  main_format: @locale_file_class.phraseapp_type)
25
- project = phraseapp_request { @client.project_create(params) }
32
+
33
+ project = phraseapp_request(Phrase::ProjectsApi, :project_create, params)
34
+
26
35
  STDERR.puts "Created project #{name} for #{parent_commit}"
27
36
 
28
37
  @project_id = project.id
@@ -32,7 +41,8 @@ class PhraseAppUpdater
32
41
  end
33
42
 
34
43
  def lookup_project_id(name)
35
- result, = paginate_request(:projects_list, limit: 1) { |p| p.name == name }
44
+ result, = paginated_request(Phrase::ProjectsApi, :projects_list, { per_page: PAGE_SIZE }, limit: 1) { |p| p.name == name }
45
+
36
46
  raise ProjectNotFoundError.new(name) if result.nil?
37
47
 
38
48
  result.id
@@ -41,9 +51,10 @@ class PhraseAppUpdater
41
51
  # We mark projects with their parent git commit using a tag with a
42
52
  # well-known prefix. We only allow one tag with this prefix at once.
43
53
  def read_parent_commit
44
- git_tag, = paginate_request(:tags_list, @project_id, limit: 1) do |t|
54
+ git_tag, = paginated_request(Phrase::TagsApi, :tags_list, @project_id, limit: 1) do |t|
45
55
  t.name.start_with?(GIT_TAG_PREFIX)
46
56
  end
57
+
47
58
  raise MissingGitParentError.new if git_tag.nil?
48
59
 
49
60
  git_tag.name.delete_prefix(GIT_TAG_PREFIX)
@@ -51,35 +62,28 @@ class PhraseAppUpdater
51
62
 
52
63
  def update_parent_commit(commit_hash)
53
64
  previous_parent = read_parent_commit
54
- phraseapp_request do
55
- @client.tag_delete(@project_id, GIT_TAG_PREFIX + previous_parent)
56
- end
65
+ phraseapp_request(Phrase::TagsApi, :tag_delete, @project_id, GIT_TAG_PREFIX + previous_parent)
57
66
  store_parent_commit(commit_hash)
58
67
  end
59
68
 
60
69
  def fetch_locales
61
- # This is a paginated API, however the maximum page size of 100 is well
62
- # above our expected locale size, so we take the first page only for now
63
- phraseapp_request { @client.locales_list(@project_id, 1, 100) }.map do |pa_locale|
64
- Locale.new(pa_locale)
65
- end
70
+ locales = paginated_request(Phrase::LocalesApi, :locales_list, @project_id)
71
+ locales.map { |pa_locale| Locale.new(pa_locale) }
66
72
  end
67
73
 
68
74
  def create_locale(name, default: false)
69
- phraseapp_request do
70
- params = PhraseApp::RequestParams::LocaleParams.new(
71
- name: name,
72
- code: name,
73
- default: default,
74
- )
75
- @client.locale_create(@project_id, params)
76
- end
75
+ params = Phrase::LocaleCreateParameters.new(
76
+ name: name,
77
+ code: name,
78
+ default: default,
79
+ )
80
+ phraseapp_request(Phrase::LocalesApi, :locale_create, @project_id, params)
77
81
  end
78
82
 
79
83
  def download_files(locales, skip_unverified:)
80
84
  results = threaded_request(locales) do |locale|
81
85
  STDERR.puts "Downloading file for #{locale}"
82
- download_file(locale, skip_unverified)
86
+ download_locale(locale, skip_unverified)
83
87
  end
84
88
 
85
89
  locales.zip(results).map do |locale, file_contents|
@@ -87,18 +91,65 @@ class PhraseAppUpdater
87
91
  end
88
92
  end
89
93
 
94
+ # Empirically, PhraseApp fails to parse the uploaded files when uploaded in
95
+ # parallel. Give it a better chance by uploading them one at a time.
90
96
  def upload_files(locale_files, default_locale:)
91
- known_locales = fetch_locales.index_by(&:name)
97
+ is_default = ->(l) { l.locale_name == default_locale }
92
98
 
99
+ # Ensure the locales all exist
100
+ STDERR.puts('Creating locales')
101
+ known_locales = fetch_locales.index_by(&:name)
93
102
  threaded_request(locale_files) do |locale_file|
94
103
  unless known_locales.has_key?(locale_file.locale_name)
95
- create_locale(locale_file.locale_name,
96
- default: (locale_file.locale_name == default_locale))
104
+ create_locale(locale_file.locale_name, default: is_default.(locale_file))
105
+ end
106
+ end
107
+
108
+ # Upload the files in a stable order, ensuring the default locale is first.
109
+ locale_files.sort! do |a, b|
110
+ next -1 if is_default.(a)
111
+ next 1 if is_default.(b)
112
+
113
+ a.locale_name <=> b.locale_name
114
+ end
115
+
116
+ uploads = {}
117
+
118
+ uploads = locale_files.to_h do |locale_file|
119
+ STDERR.puts("Uploading #{locale_file}")
120
+ upload_id = upload_file(locale_file)
121
+ [upload_id, locale_file]
122
+ end
123
+
124
+ # Validate the uploads, retrying failures as necessary
125
+ successful_upload_ids = {}
126
+
127
+ STDERR.puts('Verifying uploads...')
128
+ until uploads.empty?
129
+ threaded_request(uploads.to_a) do |upload_id, locale_file|
130
+ upload = phraseapp_request(Phrase::UploadsApi, :upload_show, @project_id, upload_id)
131
+
132
+ case upload.state
133
+ when "enqueued", "processing"
134
+ STDERR.puts("#{locale_file}: still processing")
135
+ when "success"
136
+ STDERR.puts("#{locale_file}: success")
137
+ successful_upload_ids[locale_file.locale_name] = upload_id
138
+ uploads.delete(upload_id)
139
+ when "error"
140
+ STDERR.puts("#{locale_file}: upload failure, retrying")
141
+ new_upload_id = upload_file(locale_file)
142
+ uploads.delete(upload_id)
143
+ uploads[new_upload_id] = locale_file
144
+ else
145
+ raise RuntimeError.new("Unknown upload state: #{upload.state}")
146
+ end
97
147
  end
98
148
 
99
- STDERR.puts "Uploading #{locale_file}"
100
- upload_file(locale_file)
149
+ sleep(2) unless uploads.empty?
101
150
  end
151
+
152
+ successful_upload_ids
102
153
  end
103
154
 
104
155
  def remove_keys_not_in_uploads(upload_ids)
@@ -108,105 +159,101 @@ class PhraseAppUpdater
108
159
  end
109
160
  end
110
161
 
111
- def download_file(locale, skip_unverified)
112
- download_params = PhraseApp::RequestParams::LocaleDownloadParams.new
113
-
114
- download_params.file_format = @locale_file_class.phraseapp_type
115
- download_params.skip_unverified_translations = skip_unverified
162
+ def download_locale(locale, skip_unverified)
163
+ opts = {
164
+ file_format: @locale_file_class.phraseapp_type,
165
+ skip_unverified_translations: skip_unverified,
166
+ }
116
167
 
117
- phraseapp_request { @client.locale_download(@project_id, locale.id, download_params) }
168
+ # Avoid allocating a tempfile (and emitting unnecessary warnings) by using `return_type` of `String`
169
+ phraseapp_request(Phrase::LocalesApi, :locale_download, @project_id, locale.id, return_type: 'String', **opts)
118
170
  end
119
171
 
120
172
  def upload_file(locale_file)
121
- upload_params = create_upload_params(locale_file.locale_name)
122
-
123
173
  # The PhraseApp gem only accepts a filename to upload,
124
174
  # so we need to write the file out and pass it the path
125
175
  Tempfile.create([locale_file.locale_name, ".json"]) do |f|
126
176
  f.write(locale_file.content)
127
177
  f.close
128
178
 
129
- upload_params.file = f.path
130
- phraseapp_request { @client.upload_create(@project_id, upload_params) }.id
179
+ opts = {
180
+ file: f,
181
+ file_encoding: 'UTF-8',
182
+ file_format: @locale_file_class.phraseapp_type,
183
+ locale_id: locale_file.locale_name,
184
+ skip_unverification: false,
185
+ update_translations: true,
186
+ tags: [generate_upload_tag],
187
+ }
188
+
189
+ result = phraseapp_request(Phrase::UploadsApi, :upload_create, @project_id, **opts)
190
+
191
+ result.id
131
192
  end
132
193
  end
133
194
 
134
195
  def remove_keys_not_in_upload(upload_id)
135
- delete_params = PhraseApp::RequestParams::KeysDeleteParams.new
136
- delete_params.q = "unmentioned_in_upload:#{upload_id}"
137
-
138
- begin
139
- phraseapp_request { @client.keys_delete(@project_id, delete_params) }
140
- rescue RuntimeError => _e
141
- # PhraseApp will accept but mark invalid uploads, however the gem
142
- # returns the same response in both cases. If we call this API
143
- # with the ID of an upload of a bad file, it will fail.
144
- # This usually occurs when sending up an empty file, which is
145
- # a case we can ignore. However, it'd be better to have a way
146
- # to detect a bad upload and find the cause.
147
- end
196
+ delete_pattern = "unmentioned_in_upload:#{upload_id}"
197
+ phraseapp_request(Phrase::KeysApi, :keys_delete_collection, @project_id, q: delete_pattern)
148
198
  end
149
199
 
150
200
  private
151
201
 
152
202
  def store_parent_commit(commit_hash)
153
- params = PhraseApp::RequestParams::TagParams.new(
154
- name: GIT_TAG_PREFIX + commit_hash)
155
- phraseapp_request { @client.tag_create(@project_id, params) }
203
+ params = Phrase::TagCreateParameters.new(name: GIT_TAG_PREFIX + commit_hash)
204
+ phraseapp_request(Phrase::TagsApi,:tag_create, @project_id, params)
205
+ end
206
+
207
+ def wrap_phrase_errors
208
+ yield
209
+ rescue Phrase::ApiError => e
210
+ if e.code == 401
211
+ raise BadAPIKeyError.new(e)
212
+ elsif e.message.match?(/not found/)
213
+ raise BadProjectIDError.new(e, @project_id)
214
+ elsif e.message.match?(/has already been taken/)
215
+ raise ProjectNameTakenError.new(e)
216
+ else
217
+ raise
218
+ end
156
219
  end
157
220
 
158
- def paginate_request(method, *params, limit: nil, &filter)
221
+ def paginated_request(api_class, method, *params, limit: nil, **opts, &filter)
222
+
223
+ api_instance = api_class.new(@client)
159
224
  page = 1
160
225
  results = []
161
226
 
162
227
  loop do
163
- response = phraseapp_request do
164
- @client.public_send(method, *params, page, PAGE_SIZE)
228
+ response = wrap_phrase_errors do
229
+ api_instance.public_send(method, *params, opts.merge(page: page, page_size: PAGE_SIZE))
165
230
  end
166
231
 
167
- break if response.empty?
232
+ break if response.data.empty?
168
233
 
169
- matches = response.filter(&filter)
234
+ matches = response.data
235
+ matches = matches.filter(&filter) if filter
170
236
  matches = matches[0, limit - results.size] if limit
171
237
 
172
- unless matches.empty?
173
- results.concat(matches)
238
+ results.concat(matches) unless matches.empty?
174
239
 
175
- break if results.size == limit
176
- end
240
+ break if results.size == limit
241
+ break unless response.next_page?
177
242
 
178
- page += 1
243
+ page = response.next_page
179
244
  end
180
245
 
181
246
  results
182
247
  end
183
248
 
184
- def phraseapp_request(&block)
185
- res, err = block.call
249
+ def phraseapp_request(api_class, method, *params, **opts)
250
+ api_instance = api_class.new(@client)
186
251
 
187
- unless err.nil?
188
- error =
189
- if err.respond_to?(:error)
190
- err.error
191
- else
192
- err.errors.join('|')
193
- end
194
-
195
- raise RuntimeError.new(error)
252
+ response = wrap_phrase_errors do
253
+ api_instance.public_send(method, *params, opts)
196
254
  end
197
255
 
198
- res
199
-
200
- rescue RuntimeError => e
201
- if e.message.match?(/\(401\)/)
202
- raise BadAPIKeyError.new(e)
203
- elsif e.message.match?(/not found/)
204
- raise BadProjectIDError.new(e, @project_id)
205
- elsif e.message.match?(/has already been taken/)
206
- raise ProjectNameTakenError.new(e)
207
- else
208
- raise
209
- end
256
+ response.data
210
257
  end
211
258
 
212
259
  # PhraseApp allows two concurrent connections at a time.
@@ -216,17 +263,6 @@ class PhraseAppUpdater
216
263
  Parallel.map(worklist, in_threads: THREAD_COUNT, &block)
217
264
  end
218
265
 
219
- def create_upload_params(locale_name)
220
- upload_params = PhraseApp::RequestParams::UploadParams.new
221
- upload_params.file_encoding = 'UTF-8'
222
- upload_params.file_format = @locale_file_class.phraseapp_type
223
- upload_params.locale_id = locale_name
224
- upload_params.skip_unverification = false
225
- upload_params.update_translations = true
226
- upload_params.tags = [generate_upload_tag]
227
- upload_params
228
- end
229
-
230
266
  def generate_upload_tag
231
267
  "phraseapp_updater_upload_#{Time.now.strftime('%Y%m%d%H%M%S')}"
232
268
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class PhraseAppUpdater
4
- VERSION = '2.1.2'
4
+ VERSION = '3.0.0'
5
5
  end
@@ -102,13 +102,14 @@ class PhraseAppUpdater
102
102
  # We assert that the default locale contains all legitimate strings, and so
103
103
  # we clean up orphaned content on PhraseApp post-upload by removing keys not
104
104
  # in the default locale.
105
- default_locale_index = locale_files.find_index { |f| f.locale_name == @default_locale }
106
- raise RuntimeError.new("Missing default locale") unless default_locale_index
105
+ unless locale_files.find { |f| f.locale_name == @default_locale }
106
+ raise RuntimeError.new("Missing default locale")
107
+ end
107
108
 
108
109
  upload_ids = @phraseapp_api.upload_files(locale_files, default_locale: @default_locale)
109
- default_upload_id = upload_ids[default_locale_index]
110
+ default_upload_id = upload_ids.fetch(@default_locale)
110
111
 
111
- STDERR.puts "Removing keys not in default locale upload #{default_upload_id}"
112
+ STDERR.puts "Removing keys not in default locale '#{@default_locale}' upload '#{default_upload_id}'"
112
113
  @phraseapp_api.remove_keys_not_in_upload(default_upload_id)
113
114
  end
114
115
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phraseapp_updater
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Kevin Griffin
7
+ - iKnow Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-17 00:00:00.000000000 Z
11
+ date: 2023-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.19'
27
27
  - !ruby/object:Gem::Dependency
28
- name: phraseapp-ruby
28
+ name: phrase
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: 2.8.3
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
- version: '1.3'
40
+ version: 2.8.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: hashdiff
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.3'
47
+ version: 1.0.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.3'
54
+ version: 1.0.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: multi_json
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -167,23 +167,13 @@ dependencies:
167
167
  description: A tool for merging data on PhraseApp with local changes (usually two
168
168
  git revisions)
169
169
  email:
170
- - kev@bibo.com.ph
170
+ - systems@iknow.jp
171
171
  executables:
172
172
  - phraseapp_updater
173
173
  extensions: []
174
174
  extra_rdoc_files: []
175
175
  files:
176
- - ".envrc"
177
- - ".github/workflows/gem-push.yml"
178
- - ".github/workflows/test.yml"
179
- - ".gitignore"
180
- - ".rspec"
181
- - ".travis.yml"
182
- - CODE_OF_CONDUCT.markdown
183
- - Gemfile
184
176
  - LICENSE.txt
185
- - README.markdown
186
- - Rakefile
187
177
  - bin/console
188
178
  - bin/phraseapp_common.sh
189
179
  - bin/phraseapp_updater
@@ -198,13 +188,7 @@ files:
198
188
  - lib/phraseapp_updater/phraseapp_api.rb
199
189
  - lib/phraseapp_updater/version.rb
200
190
  - lib/phraseapp_updater/yml_config_loader.rb
201
- - nix/gem/Gemfile
202
- - nix/gem/Gemfile.lock
203
- - nix/gem/gemset.nix
204
- - nix/generate.rb
205
- - phraseapp_updater.gemspec
206
- - shell.nix
207
- homepage: https://app.engoo.com
191
+ homepage: https://github.com/iknow/phraseapp_updater
208
192
  licenses:
209
193
  - MIT
210
194
  metadata: {}
data/.envrc DELETED
@@ -1 +0,0 @@
1
- eval "$(lorri direnv)"
@@ -1,31 +0,0 @@
1
- name: Publish Ruby Gem
2
-
3
- on:
4
- push:
5
- branches: [ "master" ]
6
-
7
- jobs:
8
- build:
9
- name: Build + Publish
10
- runs-on: ubuntu-latest
11
- permissions:
12
- contents: read
13
- packages: write
14
-
15
- steps:
16
- - uses: actions/checkout@v3
17
- - name: Set up Ruby 2.7
18
- uses: ruby/setup-ruby@v1
19
- with:
20
- ruby-version: 2.7
21
-
22
- - name: Publish to RubyGems
23
- run: |
24
- mkdir -p $HOME/.gem
25
- touch $HOME/.gem/credentials
26
- chmod 0600 $HOME/.gem/credentials
27
- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
28
- gem build *.gemspec
29
- gem push *.gem
30
- env:
31
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -1,41 +0,0 @@
1
- name: Run Tests
2
-
3
- on:
4
- pull_request:
5
- branches: "**"
6
-
7
- permissions:
8
- contents: read
9
- checks: write
10
- pull-requests: write
11
-
12
- jobs:
13
- test:
14
- runs-on: ubuntu-latest
15
-
16
- strategy:
17
- matrix:
18
- ruby-version: ['2.7', '3.0', '3.1']
19
-
20
- steps:
21
- - uses: actions/checkout@v3
22
- - name: Set up Ruby
23
- uses: ruby/setup-ruby@v1
24
- with:
25
- ruby-version: ${{ matrix.ruby-version }}
26
- bundler-cache: true # runs 'bundle install' and caches installed gems automatically
27
- - name: Run tests
28
- run: bundle exec rspec --profile 10 --format RspecJunitFormatter --out test_results/rspec.xml --format progress
29
- - name: Upload result
30
- uses: actions/upload-artifact@v3
31
- if: always()
32
- with:
33
- name: rspec.xml
34
- path: test_results/rspec.xml
35
- - name: Test Report
36
- uses: dorny/test-reporter@v1
37
- if: always()
38
- with:
39
- name: Rspec Tests - ${{ matrix.ruby-version }}
40
- path: test_results/rspec.xml
41
- reporter: java-junit
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3.3
5
- before_install: gem install bundler -v 1.12.5
@@ -1,50 +0,0 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, and in the interest of
4
- fostering an open and welcoming community, we pledge to respect all people who
5
- contribute through reporting issues, posting feature requests, updating
6
- documentation, submitting pull requests or patches, and other activities.
7
-
8
- We are committed to making participation in this project a harassment-free
9
- experience for everyone, regardless of level of experience, gender, gender
10
- identity and expression, sexual orientation, disability, personal appearance,
11
- body size, race, ethnicity, age, religion, or nationality.
12
-
13
- Examples of unacceptable behavior by participants include:
14
-
15
- * The use of sexualized language or imagery
16
- * Personal attacks
17
- * Trolling or insulting/derogatory comments
18
- * Public or private harassment
19
- * Publishing other's private information, such as physical or electronic
20
- addresses, without explicit permission
21
- * Other unethical or unprofessional conduct
22
-
23
- Project maintainers have the right and responsibility to remove, edit, or
24
- reject comments, commits, code, wiki edits, issues, and other contributions
25
- that are not aligned to this Code of Conduct, or to ban temporarily or
26
- permanently any contributor for other behaviors that they deem inappropriate,
27
- threatening, offensive, or harmful.
28
-
29
- By adopting this Code of Conduct, project maintainers commit themselves to
30
- fairly and consistently applying these principles to every aspect of managing
31
- this project. Project maintainers who do not follow or enforce the Code of
32
- Conduct may be permanently removed from the project team.
33
-
34
- This code of conduct applies both within project spaces and in public spaces
35
- when an individual is representing the project or its community.
36
-
37
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
- reported by contacting a project maintainer at kev@bibo.com.ph. All
39
- complaints will be reviewed and investigated and will result in a response that
40
- is deemed necessary and appropriate to the circumstances. Maintainers are
41
- obligated to maintain confidentiality with regard to the reporter of an
42
- incident.
43
-
44
- This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
- version 1.3.0, available at
46
- [http://contributor-covenant.org/version/1/3/0/][version]
47
-
48
- [homepage]: http://contributor-covenant.org
49
- [version]: http://contributor-covenant.org/version/1/3/0/
50
-
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in phraseapp_updater.gemspec
4
- gemspec
5
- gem 'byebug'
6
- gem 'rspec_junit_formatter'
7
-
8
- gem 'irb', require: false
data/README.markdown DELETED
@@ -1,177 +0,0 @@
1
- # PhraseAppUpdater
2
-
3
- [![Build Status](https://travis-ci.org/iknow/phraseapp_updater.svg?branch=master)](https://travis-ci.org/iknow/phraseapp_updater)
4
-
5
- **Version** 2.0.0
6
-
7
- This is a tool for managing synchronization between locale data in
8
- [PhraseApp](https://phraseapp.com) and committed in your project. It can perform
9
- JSON-aware three-way merges with respect to a common ancestor, and maintains a
10
- record of the common ancestor on PhraseApp using tags.
11
-
12
- Our workflow considers localization data stored on PhraseApp to be a working
13
- copy for a given branch. We expect developers working on the code and
14
- translators working on PhraseApp to both be able to make changes and have them
15
- integrated.
16
-
17
- PhraseApp provides [APIs](https://phraseapp.com/docs/api/v2/) and a [Ruby
18
- gem](https://github.com/phrase/phraseapp-ruby) for accessing them, but the API
19
- only allows either a) completely overwriting PhraseApp's data with local data or
20
- b) reapplying PhraseApp's data on top of the local data. Neither of these cases
21
- is appropriate for integrating changes made on both sides.
22
-
23
- What we want instead is a three way merge where the committed data wins on
24
- conflict. Non-conflicting changes on PhraseApp are preserved, while changes to
25
- the same key on both sides take the committed data. The result of the merge is
26
- then applied to both sides, keeping them up to date with each other.
27
-
28
- This is especially important when removing keys. Imagine we have the
29
- following, no-longer useful key:
30
-
31
- ```json
32
- unused:
33
- one: An unused
34
- ```
35
-
36
- On PhraseApp, we've added another plural form:
37
-
38
-
39
- ```json
40
- unused:
41
- one: An unused
42
- zero: No unused's
43
- ```
44
-
45
- And in our feature branch, we remove it. The result we want is that the key
46
- completely disappears, instead of getting a result like either of the above.
47
-
48
- ## Installation
49
-
50
- This gem provides a command line interface for performing the
51
- merge and uploading the result to PhraseApp. To use it, install the gem:
52
-
53
- `gem install phraseapp_updater`
54
-
55
- You may also use this gem programatically from your own application.
56
-
57
- Add this line to your application's Gemfile:
58
-
59
- ```ruby
60
- gem 'phraseapp_updater'
61
- ```
62
-
63
- And then execute:
64
-
65
- $ bundle
66
-
67
- Or install it yourself as:
68
-
69
- $ gem install phraseapp_updater
70
-
71
- ## Usage
72
-
73
- CLI
74
- ---
75
-
76
- **Setup**
77
-
78
- `phraseapp_updater setup` creates and initializes a PhraseApp project
79
- corresponding to your branch. It must be provided with the current git revision
80
- of the branch and the path to the locale files.
81
-
82
- ```
83
- phraseapp_updater setup --phraseapp_project_name=<yourbranch> --parent_commit=<yourhash> --phraseapp_api_key=<yourkey> --file-format=json <path_to_locales>
84
- ```
85
-
86
- **Synchronize**
87
-
88
- `phraseapp_updater synchronize` synchronizes a git remote branch with its
89
- corresponding PhraseApp project, incorporating changes from each side into the
90
- other. If both sides were changed, a three-way merge is performed. The result is
91
- uploaded to PhraseApp and committed and pushed to the git remote as appropriate.
92
-
93
- The option `--no_commit` may be provided to restrict changes to the PhraseApp
94
- side. If specified, then in the case that the branch was modified, the merge
95
- result will be uploaded to PhraseApp and the common ancestor updated to the
96
- branch head.
97
-
98
- ```
99
- phraseapp_updater synchronize <checkout_path> --prefix=config/locales --phraseapp_project_id=<yourid> --phraseapp_api_key=<yourkey> --file-format=json
100
- ```
101
-
102
- **Download**
103
-
104
- `phraseapp_updater download` downloads and normalizes locale files from
105
- PhraseApp, saving them to the specified location. The revision of the recorded
106
- common ancestor is printed to standard out.
107
-
108
- ```
109
- phraseapp_updater download --phraseapp_project_id=<yourid> --phraseapp_api_key=<yourkey> --file-format=json <target_path>
110
- ```
111
-
112
- **Upload**
113
-
114
- `phraseapp_updater upload` uploads normalized locale files from your branch to
115
- PhraseApp and resets the recorded common ancestor to the specified revision.
116
-
117
- ```
118
- phraseapp_updater upload --phraseapp_project_id=<yourid> --phraseapp_api_key=<yourkey> --file-format=json <path_to_locales>
119
- ```
120
-
121
- **Update Parent Commit**
122
- `phraseapp_updater update_parent_commit` records a new common ancestor on
123
- PhraseApp without changing the locales.
124
-
125
- ```
126
- phraseapp_updater update_parent_commit --phraseapp_project_id=<yourid> --phraseapp_api_key=<yourkey> --parent_commit=<yournewhash>
127
- ```
128
-
129
- **Merge**
130
-
131
- `phraseapp_updater merge` performs a content-aware three-way merge between
132
- locale files in three directories: `ancestor_path`, `our_path`, and
133
- `their_path`. In the case of conflicts, the changes from `our_path` are
134
- accepted. The results are normalized and written to the path specified with
135
- `to`.
136
-
137
- ```
138
- phraseapp_updater merge ancestor_path our_path their_path --to target_path --file-format=json
139
- ```
140
-
141
-
142
- **Diff**
143
-
144
- Performs a content-aware diff between locale files in two directories. Returns
145
- with exit status 1 or 0 to signal differences or no differences respectively
146
-
147
- ```
148
- phraseapp_updater diff path1 path2 --file-format=json
149
- ```
150
-
151
- ## Future Improvements
152
-
153
- If you'd like to contribute, these would be very helpful!
154
-
155
- * We'd like to use "unverified" translations on PhraseApp as the equivalent of
156
- an unstaged working copy. For this to work, we need to be able to recover
157
- previous translations at the same key. While PhraseApp doesn't itself keep
158
- this history, we could do this by restoring the absent keys from the diff
159
- between verified and unverified download from the common ancestor.
160
- * Expose the changed files on the command line.
161
- * Checking if PhraseApp files changed during execution before upload, to reduce the race condition window.
162
- * More specs for the API and shell.
163
-
164
- ## Development
165
-
166
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
167
-
168
- To install this gem onto your local machine, run `bundle exec rake install`. When everything is working, make a pull request.
169
-
170
- ## Contributing
171
-
172
- Bug reports and pull requests are welcome on GitHub at https://github.com/iknow/phraseapp_updater. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
173
-
174
- ## License
175
-
176
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
177
-
data/Rakefile DELETED
@@ -1,7 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
7
-
data/nix/gem/Gemfile DELETED
@@ -1,24 +0,0 @@
1
- source "https://rubygems.org/"
2
-
3
- gem "byebug", "11.0.1"
4
- gem "coderay", "1.1.2"
5
- gem "deep_merge", "1.2.1"
6
- gem "diff-lcs", "1.3"
7
- gem "hashdiff", "0.4.0"
8
- gem "io-console", "0.5.4"
9
- gem "irb", "1.2.1"
10
- gem "method_source", "0.9.2"
11
- gem "multi_json", "1.14.1"
12
- gem "oj", "2.18.5"
13
- gem "parallel", "1.19.1"
14
- gem "phraseapp-ruby", "1.6.0"
15
- gem "pry", "0.12.2"
16
- gem "rake", "10.5.0"
17
- gem "reline", "0.1.2"
18
- gem "rspec", "3.8.0"
19
- gem "rspec-core", "3.8.0"
20
- gem "rspec-expectations", "3.8.3"
21
- gem "rspec-mocks", "3.8.0"
22
- gem "rspec-support", "3.8.0"
23
- gem "rspec_junit_formatter", "0.4.1"
24
- gem "thor", "0.20.3"
data/nix/gem/Gemfile.lock DELETED
@@ -1,68 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- byebug (11.0.1)
5
- coderay (1.1.2)
6
- deep_merge (1.2.1)
7
- diff-lcs (1.3)
8
- hashdiff (0.4.0)
9
- io-console (0.5.4)
10
- irb (1.2.1)
11
- reline (>= 0.0.1)
12
- method_source (0.9.2)
13
- multi_json (1.14.1)
14
- oj (2.18.5)
15
- parallel (1.19.1)
16
- phraseapp-ruby (1.6.0)
17
- pry (0.12.2)
18
- coderay (~> 1.1.0)
19
- method_source (~> 0.9.0)
20
- rake (10.5.0)
21
- reline (0.1.2)
22
- io-console (~> 0.5)
23
- rspec (3.8.0)
24
- rspec-core (~> 3.8.0)
25
- rspec-expectations (~> 3.8.0)
26
- rspec-mocks (~> 3.8.0)
27
- rspec-core (3.8.0)
28
- rspec-support (~> 3.8.0)
29
- rspec-expectations (3.8.3)
30
- diff-lcs (>= 1.2.0, < 2.0)
31
- rspec-support (~> 3.8.0)
32
- rspec-mocks (3.8.0)
33
- diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.8.0)
35
- rspec-support (3.8.0)
36
- rspec_junit_formatter (0.4.1)
37
- rspec-core (>= 2, < 4, != 2.12.0)
38
- thor (0.20.3)
39
-
40
- PLATFORMS
41
- ruby
42
-
43
- DEPENDENCIES
44
- byebug (= 11.0.1)
45
- coderay (= 1.1.2)
46
- deep_merge (= 1.2.1)
47
- diff-lcs (= 1.3)
48
- hashdiff (= 0.4.0)
49
- io-console (= 0.5.4)
50
- irb (= 1.2.1)
51
- method_source (= 0.9.2)
52
- multi_json (= 1.14.1)
53
- oj (= 2.18.5)
54
- parallel (= 1.19.1)
55
- phraseapp-ruby (= 1.6.0)
56
- pry (= 0.12.2)
57
- rake (= 10.5.0)
58
- reline (= 0.1.2)
59
- rspec (= 3.8.0)
60
- rspec-core (= 3.8.0)
61
- rspec-expectations (= 3.8.3)
62
- rspec-mocks (= 3.8.0)
63
- rspec-support (= 3.8.0)
64
- rspec_junit_formatter (= 0.4.1)
65
- thor (= 0.20.3)
66
-
67
- BUNDLED WITH
68
- 1.17.3
data/nix/gem/gemset.nix DELETED
@@ -1,230 +0,0 @@
1
- {
2
- byebug = {
3
- groups = ["default"];
4
- platforms = [];
5
- source = {
6
- remotes = ["https://rubygems.org"];
7
- sha256 = "1mmkls9n56l4gx2k0dnyianwz36z2zgpxli5bpsbr7jbw7hn2x6j";
8
- type = "gem";
9
- };
10
- version = "11.0.1";
11
- };
12
- coderay = {
13
- groups = ["default"];
14
- platforms = [];
15
- source = {
16
- remotes = ["https://rubygems.org"];
17
- sha256 = "15vav4bhcc2x3jmi3izb11l4d9f3xv8hp2fszb7iqmpsccv1pz4y";
18
- type = "gem";
19
- };
20
- version = "1.1.2";
21
- };
22
- deep_merge = {
23
- groups = ["default"];
24
- platforms = [];
25
- source = {
26
- remotes = ["https://rubygems.org"];
27
- sha256 = "1q3picw7zx1xdkybmrnhmk2hycxzaa0jv4gqrby1s90dy5n7fmsb";
28
- type = "gem";
29
- };
30
- version = "1.2.1";
31
- };
32
- diff-lcs = {
33
- groups = ["default"];
34
- platforms = [];
35
- source = {
36
- remotes = ["https://rubygems.org"];
37
- sha256 = "18w22bjz424gzafv6nzv98h0aqkwz3d9xhm7cbr1wfbyas8zayza";
38
- type = "gem";
39
- };
40
- version = "1.3";
41
- };
42
- hashdiff = {
43
- groups = ["default"];
44
- platforms = [];
45
- source = {
46
- remotes = ["https://rubygems.org"];
47
- sha256 = "1ncwxv7jbm3jj9phv6dd514463bkjwggxk10n2z100wf4cjcicrk";
48
- type = "gem";
49
- };
50
- version = "0.4.0";
51
- };
52
- io-console = {
53
- groups = ["default"];
54
- platforms = [];
55
- source = {
56
- remotes = ["https://rubygems.org"];
57
- sha256 = "109yzpv9kslwra2mxnjsg3r6mwxkbqmxihj266qdvccapghi05wg";
58
- type = "gem";
59
- };
60
- version = "0.5.4";
61
- };
62
- irb = {
63
- dependencies = ["reline"];
64
- groups = ["default"];
65
- platforms = [];
66
- source = {
67
- remotes = ["https://rubygems.org"];
68
- sha256 = "1r1y8i46qd5izdszzzn5jxvwvq00m89rk0hm8cs8f21p7nlwmh5w";
69
- type = "gem";
70
- };
71
- version = "1.2.1";
72
- };
73
- method_source = {
74
- groups = ["default"];
75
- platforms = [];
76
- source = {
77
- remotes = ["https://rubygems.org"];
78
- sha256 = "1pviwzvdqd90gn6y7illcdd9adapw8fczml933p5vl739dkvl3lq";
79
- type = "gem";
80
- };
81
- version = "0.9.2";
82
- };
83
- multi_json = {
84
- groups = ["default"];
85
- platforms = [];
86
- source = {
87
- remotes = ["https://rubygems.org"];
88
- sha256 = "0xy54mjf7xg41l8qrg1bqri75agdqmxap9z466fjismc1rn2jwfr";
89
- type = "gem";
90
- };
91
- version = "1.14.1";
92
- };
93
- oj = {
94
- groups = ["default"];
95
- platforms = [];
96
- source = {
97
- remotes = ["https://rubygems.org"];
98
- sha256 = "1jli4mi1xpmm8564pc09bfvv7znzqghidwa3zfw21r365ihmbv2p";
99
- type = "gem";
100
- };
101
- version = "2.18.5";
102
- };
103
- parallel = {
104
- groups = ["default"];
105
- platforms = [];
106
- source = {
107
- remotes = ["https://rubygems.org"];
108
- sha256 = "12jijkap4akzdv11lm08dglsc8jmc87xcgq6947i1s3qb69f4zn2";
109
- type = "gem";
110
- };
111
- version = "1.19.1";
112
- };
113
- phraseapp-ruby = {
114
- groups = ["default"];
115
- platforms = [];
116
- source = {
117
- remotes = ["https://rubygems.org"];
118
- sha256 = "14n2hhwjn32xk0qk6rprs3awnrddhnd4zckyd0a4j8lv8k648pnn";
119
- type = "gem";
120
- };
121
- version = "1.6.0";
122
- };
123
- pry = {
124
- dependencies = ["coderay" "method_source"];
125
- groups = ["default"];
126
- platforms = [];
127
- source = {
128
- remotes = ["https://rubygems.org"];
129
- sha256 = "00rm71x0r1jdycwbs83lf9l6p494m99asakbvqxh8rz7zwnlzg69";
130
- type = "gem";
131
- };
132
- version = "0.12.2";
133
- };
134
- rake = {
135
- groups = ["default"];
136
- platforms = [];
137
- source = {
138
- remotes = ["https://rubygems.org"];
139
- sha256 = "0jcabbgnjc788chx31sihc5pgbqnlc1c75wakmqlbjdm8jns2m9b";
140
- type = "gem";
141
- };
142
- version = "10.5.0";
143
- };
144
- reline = {
145
- dependencies = ["io-console"];
146
- groups = ["default"];
147
- platforms = [];
148
- source = {
149
- remotes = ["https://rubygems.org"];
150
- sha256 = "0908ijrngc3wkn5iny7d0kxkp74w6ixk2nwzzngplplfla1vkp8x";
151
- type = "gem";
152
- };
153
- version = "0.1.2";
154
- };
155
- rspec = {
156
- dependencies = ["rspec-core" "rspec-expectations" "rspec-mocks"];
157
- groups = ["default"];
158
- platforms = [];
159
- source = {
160
- remotes = ["https://rubygems.org"];
161
- sha256 = "15ppasvb9qrscwlyjz67ppw1lnxiqnkzx5vkx1bd8x5n3dhikxc3";
162
- type = "gem";
163
- };
164
- version = "3.8.0";
165
- };
166
- rspec-core = {
167
- dependencies = ["rspec-support"];
168
- groups = ["default"];
169
- platforms = [];
170
- source = {
171
- remotes = ["https://rubygems.org"];
172
- sha256 = "1p1s5bnbqp3sxk67y0fh0x884jjym527r0vgmhbm81w7aq6b7l4p";
173
- type = "gem";
174
- };
175
- version = "3.8.0";
176
- };
177
- rspec-expectations = {
178
- dependencies = ["diff-lcs" "rspec-support"];
179
- groups = ["default"];
180
- platforms = [];
181
- source = {
182
- remotes = ["https://rubygems.org"];
183
- sha256 = "1c4gs5ybf7km0qshdm92p38zvg32n1j2kr5fgs2icacz7xf2y6fy";
184
- type = "gem";
185
- };
186
- version = "3.8.3";
187
- };
188
- rspec-mocks = {
189
- dependencies = ["diff-lcs" "rspec-support"];
190
- groups = ["default"];
191
- platforms = [];
192
- source = {
193
- remotes = ["https://rubygems.org"];
194
- sha256 = "06y508cjqycb4yfhxmb3nxn0v9xqf17qbd46l1dh4xhncinr4fyp";
195
- type = "gem";
196
- };
197
- version = "3.8.0";
198
- };
199
- rspec-support = {
200
- groups = ["default"];
201
- platforms = [];
202
- source = {
203
- remotes = ["https://rubygems.org"];
204
- sha256 = "0p3m7drixrlhvj2zpc38b11x145bvm311x6f33jjcxmvcm0wq609";
205
- type = "gem";
206
- };
207
- version = "3.8.0";
208
- };
209
- rspec_junit_formatter = {
210
- dependencies = ["rspec-core"];
211
- groups = ["default"];
212
- platforms = [];
213
- source = {
214
- remotes = ["https://rubygems.org"];
215
- sha256 = "1aynmrgnv26pkprrajvp7advb8nbh0x4pkwk6jwq8qmwzarzk21p";
216
- type = "gem";
217
- };
218
- version = "0.4.1";
219
- };
220
- thor = {
221
- groups = ["default"];
222
- platforms = [];
223
- source = {
224
- remotes = ["https://rubygems.org"];
225
- sha256 = "1yhrnp9x8qcy5vc7g438amd5j9sw83ih7c30dr6g6slgw9zj3g29";
226
- type = "gem";
227
- };
228
- version = "0.20.3";
229
- };
230
- }
data/nix/generate.rb DELETED
@@ -1,41 +0,0 @@
1
- #! /usr/bin/env nix-shell
2
- #! nix-shell -i ruby -p ruby -p bundler -p bundix
3
- # frozen_string_literal: true
4
-
5
- # Bundix doesn't support `gemspec` directive in Gemfiles, as it doesn't copy the
6
- # gemspec (and its dependencies) into the store.
7
- # This workaround is from https://github.com/manveru/bundix/issues/10#issuecomment-405879379
8
-
9
- require 'shellwords'
10
-
11
- def sh(*args)
12
- warn args.shelljoin
13
- system(*args) || raise
14
- end
15
-
16
- sh 'bundle', 'lock'
17
-
18
- require 'fileutils'
19
- require 'bundler'
20
-
21
- lockfile = Bundler::LockfileParser.new(File.read('Gemfile.lock'))
22
- gems = lockfile.specs.select { |spec| spec.source.is_a?(Bundler::Source::Rubygems) }
23
- sources = [URI('https://rubygems.org/')] | gems.map(&:source).flat_map(&:remotes)
24
-
25
- FileUtils.mkdir_p 'nix/gem'
26
- Dir.chdir 'nix/gem' do
27
- ['Gemfile', 'Gemfile.lock', 'gemset.nix'].each do |f|
28
- File.delete(f) if File.exist?(f)
29
- end
30
-
31
- File.open('Gemfile', 'w') do |gemfile|
32
- sources.each { |source| gemfile.puts "source #{source.to_s.inspect}" }
33
- gemfile.puts
34
-
35
- gems.each do |gem|
36
- gemfile.puts "gem #{gem.name.inspect}, #{gem.version.to_s.inspect}"
37
- end
38
- end
39
-
40
- sh 'bundix', '-l'
41
- end
@@ -1,35 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'phraseapp_updater/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "phraseapp_updater"
8
- spec.version = PhraseAppUpdater::VERSION
9
- spec.authors = ["Kevin Griffin"]
10
- spec.email = ["kev@bibo.com.ph"]
11
-
12
- spec.summary = %q{A three-way differ for PhraseApp projects.}
13
- spec.description = %q{A tool for merging data on PhraseApp with local changes (usually two git revisions)}
14
- spec.homepage = "https://app.engoo.com"
15
- spec.license = "MIT"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "bin"
19
- spec.executables = ["phraseapp_updater"]
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_dependency "thor", "~> 0.19"
23
- spec.add_dependency "phraseapp-ruby", "~> 1.3"
24
- spec.add_dependency "hashdiff", "~> 0.3"
25
- spec.add_dependency "multi_json", "~> 1.12"
26
- spec.add_dependency "oj", "~> 2.18"
27
- spec.add_dependency "deep_merge", "~> 1.1"
28
- spec.add_dependency "parallel", "~> 1.12"
29
-
30
- spec.add_development_dependency "bundler", "~> 2.2"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency "rspec", "~> 3.0"
33
- spec.add_development_dependency "pry", "~> 0.10"
34
- end
35
-
data/shell.nix DELETED
@@ -1,10 +0,0 @@
1
- with (import <nixpkgs> {});
2
- let
3
- env = bundlerEnv {
4
- name = "bundler-env";
5
- gemdir = ./nix/gem;
6
- };
7
- in stdenv.mkDerivation {
8
- name = "shell";
9
- buildInputs = [ env ];
10
- }