refinement 0.2.2 → 0.3.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: 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.