refinement 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cde77a0d0d41bfeebca40808c3053d38d9eff4ec7d09d82a9f29d8f9f3bed31b
4
- data.tar.gz: 6d38e9cb3025c970513d80b18074e37eec4ad8edfec278c8c8eab9a4258310e8
3
+ metadata.gz: 23ec4c7c515278641dbd8dd7f8927a42126801d00d0963979a5deca88937382d
4
+ data.tar.gz: 10b9168d22d7853fbcbdc0d5a47127643a86f41a55bf6260b9f21c3a88457778
5
5
  SHA512:
6
- metadata.gz: a878d3fc86e0c733da2fcbddc9da9a869ef56e035172e17b8ea63ada49cde2cceb4ead3c5d6b1024343ebd809368f096a77d50cd6464233c87e6d724cac33127
7
- data.tar.gz: '09bd2a181cc8646d2f5a352a5b70bcf41681432a31588ee30502e40416f2641158fcaf59a3a8ad99b52abac383f1494f1804aaacaa97e9e286886fc4edc8afbb'
6
+ metadata.gz: d88a448b3f573e5f7441dd81b2fc818b928f61f4aeb7fcbbf4b31a9cbb33fd64cc0f91b9d9199a572017b1bde699595c694831368ac528d961d54f3e65f951d3
7
+ data.tar.gz: 7d9eddf6218a4f70d433a55e8fa1aef2b055dbe5d8f599c94e1496a407de45704e260808562dd2c8358991ca40054cb0eeeae52740c011d5d5384428e9124038
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Refinement Changes
2
2
 
3
+ ## 0.3.0 (2019-08-09)
4
+
5
+ ##### Bug Fixes
6
+
7
+ * Multiple YAML used keys paths for the same file will no longer cause the YAML
8
+ to be parsed multiple times.
9
+
10
+
3
11
  ## 0.2.2 (2019-04-08)
4
12
 
5
13
  No changes.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.0
data/exe/refine CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'refinement'
4
5
  require 'refinement/cli'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cocoapods'
2
4
 
3
5
  Pod::Installer
@@ -7,9 +9,7 @@ Pod::Installer
7
9
 
8
10
  return unless plugins.key?('refinement')
9
11
 
10
- unless Gem::Version.create(Pod::VERSION) >= Gem::Version.create('1.6.0')
11
- raise Pod::Informative, 'Refinement requires a CocoaPods version >= 1.6.0'
12
- end
12
+ raise Pod::Informative, 'Refinement requires a CocoaPods version >= 1.6.0' unless Gem::Version.create(Pod::VERSION) >= Gem::Version.create('1.6.0')
13
13
 
14
14
  require 'refinement/cocoapods_post_install_writer'
15
15
  Pod::UI.message 'Writing refinement file' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Refinement
2
4
  # Analyzes changes in a repository
3
5
  # and determines how those changes impact the targets in Xcode projects in the workspace.
@@ -26,12 +28,12 @@ module Refinement
26
28
  @changeset = changeset
27
29
 
28
30
  raise ArgumentError, 'Can only specify one of workspace_path and projects' if workspace_path && projects
31
+
29
32
  @workspace_path = workspace_path
30
33
  @projects = projects
31
34
 
32
- if augmenting_paths_yaml_files && augmenting_paths_by_target
33
- raise ArgumentError, 'Can only specify one of augmenting_paths_yaml_files and augmenting_paths_by_target'
34
- end
35
+ raise ArgumentError, 'Can only specify one of augmenting_paths_yaml_files and augmenting_paths_by_target' if augmenting_paths_yaml_files && augmenting_paths_by_target
36
+
35
37
  @augmenting_paths_yaml_files = augmenting_paths_yaml_files
36
38
  @augmenting_paths_by_target = augmenting_paths_by_target
37
39
  end
@@ -110,6 +112,7 @@ module Refinement
110
112
  .map do |annotated_target|
111
113
  change_reason = annotated_target.change_reason(level: change_level)
112
114
  next if !include_unchanged_targets && !change_reason
115
+
113
116
  change_reason ||= 'did not change'
114
117
  "\t#{annotated_target.xcode_target}: #{change_reason}"
115
118
  end.compact
@@ -152,6 +155,7 @@ module Refinement
152
155
  targets_by_name = Hash[targets.map { |t| [t.name, t] }]
153
156
  targets_by_product_name = Hash[targets.map do |t|
154
157
  next unless t.respond_to?(:product_reference)
158
+
155
159
  [File.basename(t.product_reference.path), t]
156
160
  end.compact]
157
161
 
@@ -166,7 +170,7 @@ module Refinement
166
170
  # yay auto-linking
167
171
  if (phase = target.frameworks_build_phases)
168
172
  phase.files_references.each do |fr|
169
- if (dt = fr && fr.path && targets_by_product_name[File.basename(fr.path)])
173
+ if (dt = fr&.path && targets_by_product_name[File.basename(fr.path)])
170
174
  target_dependencies << dt
171
175
  end
172
176
  end
@@ -232,6 +236,7 @@ module Refinement
232
236
 
233
237
  expand_build_settings = lambda do |s|
234
238
  return [s] unless s =~ /\$(?:\{([_a-zA-Z0-0]+?)\}|\(([_a-zA-Z0-0]+?)\))/
239
+
235
240
  match, key = Regexp.last_match.values_at(0, 1, 2).compact
236
241
  substitutions = target.resolved_build_setting(key, true).values.compact.uniq
237
242
  substitutions.flat_map do |sub|
@@ -242,6 +247,7 @@ module Refinement
242
247
  target.build_configuration_list.build_configurations.each do |build_configuration|
243
248
  ref = build_configuration.base_configuration_reference
244
249
  next unless ref
250
+
245
251
  yield UsedPath.new(path: ref.real_path,
246
252
  inclusion_reason: "base configuration reference for #{build_configuration}")
247
253
  end
@@ -249,6 +255,7 @@ module Refinement
249
255
  target.build_phases.each do |build_phase|
250
256
  build_phase.files_references.each do |fr|
251
257
  next unless fr
258
+
252
259
  yield UsedPath.new(path: fr.real_path,
253
260
  inclusion_reason: "#{build_phase.display_name.downcase.chomp('s')} file")
254
261
  end
@@ -257,9 +264,11 @@ module Refinement
257
264
  target.shell_script_build_phases.each do |shell_script_build_phase|
258
265
  %w[input_file_list_paths output_file_list_paths input_paths output_paths].each do |method|
259
266
  next unless (paths = shell_script_build_phase.public_send(method))
267
+
260
268
  file_type = method.tr('_', ' ').chomp('s')
261
269
  paths.each do |config_path|
262
270
  next unless config_path
271
+
263
272
  expand_build_settings[config_path].each do |path|
264
273
  path = Pathname(path).expand_path(target.project.project_dir)
265
274
  yield UsedPath.new(path: path,
@@ -273,6 +282,7 @@ module Refinement
273
282
  target.resolved_build_setting(build_setting, true).each_value do |paths|
274
283
  Array(paths).each do |path|
275
284
  next unless path
285
+
276
286
  path = Pathname(path).expand_path(target.project.project_dir)
277
287
  yield UsedPath.new(path: path, inclusion_reason: "#{build_setting} value")
278
288
  end
@@ -301,6 +311,7 @@ module Refinement
301
311
  project.root_object.build_configuration_list.build_configurations.each do |build_configuration|
302
312
  ref = build_configuration.base_configuration_reference
303
313
  next unless ref
314
+
304
315
  yield UsedPath.new(path: ref.real_path,
305
316
  inclusion_reason: "base configuration reference for #{build_configuration}")
306
317
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Refinement
2
4
  # A target, annotated with any changes
3
5
  class AnnotatedTarget
@@ -45,15 +47,18 @@ module Refinement
45
47
  when :full_transitive
46
48
  direct_change_reason || Refinement.map_find(dependencies) do |dependency|
47
49
  next unless (dependency_change_reason = dependency.change_reason(level: level))
50
+
48
51
  "dependency #{dependency} changed because #{dependency_change_reason}"
49
52
  end
50
53
  when proc { |symbol, int| (symbol == :at_most_n_away) && int.is_a?(Integer) }
51
54
  distance_from_target = level.last
52
- raise ArgumentError, "level must be positive, not #{distance_from_target}" if distance_from_target < 0
55
+ raise ArgumentError, "level must be positive, not #{distance_from_target}" if distance_from_target.negative?
56
+
53
57
  change_reason = direct_change_reason
54
- if distance_from_target > 0
58
+ if distance_from_target.positive?
55
59
  change_reason ||= Refinement.map_find(dependencies) do |dependency|
56
60
  next unless (dependency_change_reason = dependency.change_reason(level: [:at_most_n_away, level.last.pred]))
61
+
57
62
  "dependency #{dependency} changed because #{dependency_change_reason}"
58
63
  end
59
64
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Refinement
2
4
  class Changeset
3
5
  # Represents a modification to a single file or directory on disk
@@ -51,12 +53,14 @@ module Refinement
51
53
  # @visibility private
52
54
  def ==(other)
53
55
  return unless other.is_a?(FileModification)
56
+
54
57
  (path == other.path) && (type == other.type) && prior_path == other.prior_path
55
58
  end
56
59
 
57
60
  # @visibility private
58
61
  def eql?(other)
59
62
  return unless other.is_a?(FileModification)
63
+
60
64
  path.eql?(other.path) && type.eql?(other.type) && prior_path.eql?(other.prior_path)
61
65
  end
62
66
 
@@ -68,9 +72,12 @@ module Refinement
68
72
  def yaml_diff(keypath)
69
73
  require 'yaml'
70
74
 
71
- dig_yaml = lambda do |yaml|
75
+ @cached_yaml ||= {}
76
+
77
+ dig_yaml = lambda do |yaml, path|
72
78
  return yaml if DOES_NOT_EXIST == yaml
73
- object = YAML.safe_load(yaml, [Symbol])
79
+
80
+ object = @cached_yaml[path] ||= YAML.safe_load(yaml, [Symbol])
74
81
  if keypath.empty?
75
82
  object
76
83
  elsif object.respond_to?(:dig)
@@ -82,8 +89,8 @@ module Refinement
82
89
  end
83
90
  end
84
91
 
85
- prior = dig_yaml[prior_contents]
86
- current = dig_yaml[contents]
92
+ prior = dig_yaml[prior_contents, :prior]
93
+ current = dig_yaml[contents, :current]
87
94
 
88
95
  require 'xcodeproj/differ'
89
96
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cocoapods/executable'
2
4
  require 'set'
3
5
 
@@ -43,6 +45,7 @@ module Refinement
43
45
  dirs = Set.new
44
46
  add = lambda { |path|
45
47
  break unless dirs.add?(path)
48
+
46
49
  add[path.dirname]
47
50
  }
48
51
  modifications.each do |mod|
@@ -124,8 +127,10 @@ module Refinement
124
127
  # @param keypath [Array]
125
128
  def find_modification_for_yaml_keypath(absolute_path:, keypath:)
126
129
  return unless (file_modification = find_modification_for_path(absolute_path: absolute_path))
130
+
127
131
  diff = file_modification.yaml_diff(keypath)
128
132
  return unless diff
133
+
129
134
  [file_modification, diff]
130
135
  end
131
136
 
@@ -144,14 +149,14 @@ module Refinement
144
149
  end
145
150
 
146
151
  CHANGE_TYPES = {
147
- :'was added' => 'A',
148
- :'was copied' => 'C',
149
- :'was deleted' => 'D',
150
- :'was modified' => 'M',
151
- :'was renamed' => 'R',
152
- :'changed type' => 'T',
153
- :'is unmerged' => 'U',
154
- :'changed in an unknown way' => 'X'
152
+ 'was added': 'A',
153
+ 'was copied': 'C',
154
+ 'was deleted': 'D',
155
+ 'was modified': 'M',
156
+ 'was renamed': 'R',
157
+ 'changed type': 'T',
158
+ 'is unmerged': 'U',
159
+ 'changed in an unknown way': 'X'
155
160
  }.freeze
156
161
  private_constant :CHANGE_TYPES
157
162
 
@@ -206,9 +211,8 @@ module Refinement
206
211
  def self.git!(command, *args, chdir:)
207
212
  require 'open3'
208
213
  out, err, status = Open3.capture3('git', command, *args, chdir: chdir.to_s)
209
- unless status.success?
210
- raise GitError, "Running git #{command} failed (#{status.to_s.gsub(/pid \d+\s*/, '')}):\n\n#{err}"
211
- end
214
+ raise GitError, "Running git #{command} failed (#{status.to_s.gsub(/pid \d+\s*/, '')}):\n\n#{err}" unless status.success?
215
+
212
216
  out
213
217
  end
214
218
  private_class_method :git!
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'claide'
2
4
 
3
5
  module Refinement
@@ -48,6 +50,7 @@ module Refinement
48
50
  puts analyzer.format_changes if @print_changes
49
51
 
50
52
  return unless @scheme
53
+
51
54
  analyzer.filtered_scheme(scheme_path: @scheme, log_changes: @print_scheme_changes, filter_scheme_for_build_action: @filter_scheme_for_build_action)
52
55
  .save_as(@scheme.gsub(%r{\.(xcodeproj|xcworkspace)/.+}, '.\1'), File.basename(@scheme, '.xcscheme'), true)
53
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Refinement
2
4
  # Called after CocoaPods installation to write an augmenting file that
3
5
  # takes into account changes to Pod configuration,
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Refinement
2
4
  # Represents a path that some target depends upon.
3
5
  class UsedPath
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Refinement
2
4
  # @visibility private
3
5
  VERSION = File.read(File.expand_path('../../VERSION', __dir__)).strip.freeze
data/lib/refinement.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xcodeproj'
2
4
 
3
5
  # Generates a list of Xcode targets to build & test as a result of a git diff.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: refinement
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giddins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-09 00:00:00.000000000 Z
11
+ date: 2019-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xcodeproj
@@ -78,14 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '2.1'
81
+ version: '2.3'
82
82
  required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  requirements:
84
84
  - - ">="
85
85
  - !ruby/object:Gem::Version
86
86
  version: '0'
87
87
  requirements: []
88
- rubygems_version: 3.0.2
88
+ rubygems_version: 3.0.4
89
89
  signing_key:
90
90
  specification_version: 4
91
91
  summary: Generates a list of Xcode targets to build & test as a result of a git diff.