refinement 0.4.1 → 0.5.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: 1d250f8a41cab420b717380a1b0c713541ecda9d0a8439c596bd351c25631fbf
4
- data.tar.gz: cc6635b7ebb6f797f7d5142f99a7a85b355d90a0a09b5af15f39a5a6450c389c
3
+ metadata.gz: 3f99f7e0933bae18ddd8c4f6fbd14f3e182f6233a1244b1418ccf678b5c1e471
4
+ data.tar.gz: 451abebd764ff651e9489095bca0ce0fc4043965e81e962ca49df68e90341367
5
5
  SHA512:
6
- metadata.gz: bebda46b92a0bc1eaa25d4852c674a697472caa89f67d9fd5e990d0fd16cd7bf594b0c19559d9a8b4a9de7f4fe7a91f08d6f825ab2116afbe3b6fe5525d42cd1
7
- data.tar.gz: c86b9b7e206c8b201374817bc4c27b8e7b5372cec0e1a082f27e5c94d34245e50fb237cb5e22c6d3abadb33194ed90b7281d26a69b3484f470f477a47c20879e
6
+ metadata.gz: 6f8348156cedae83212560898d95229be93c592347e052a82bd5a1bd3b13d76a7298703976f4e93799cd8d38543316409462d9c6ef564e1680bdde746bf084aa
7
+ data.tar.gz: 1109c4b167045b0a2ac2ba45aa036ec6b3d4aacf06726be393c68fe072ee49479d61d41c89a6a29ad927b1e419a3e7932f82acba25ccf02fe4a08efc0a8aaae6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.5.0
@@ -4,11 +4,11 @@ module Refinement
4
4
  # Analyzes changes in a repository
5
5
  # and determines how those changes impact the targets in Xcode projects in the workspace.
6
6
  class Analyzer
7
- attr_reader :changeset, :workspace_path, :augmenting_paths_yaml_files
8
- private :changeset, :workspace_path, :augmenting_paths_yaml_files
7
+ attr_reader :changesets, :workspace_path, :augmenting_paths_yaml_files
8
+ private :changesets, :workspace_path, :augmenting_paths_yaml_files
9
9
 
10
- # Initializes an analyzer with a changeset, projects, and augmenting paths.
11
- # @param changeset [Changeset]
10
+ # Initializes an analyzer with changesets, projects, and augmenting paths.
11
+ # @param changesets [Array<Changeset>]
12
12
  # @param workspace_path [Pathname] path to a root workspace or project,
13
13
  # must be `nil` if `projects` are specified explicitly
14
14
  # @param projects [Array<Xcodeproj::Project>] projects to find targets in,
@@ -22,10 +22,10 @@ module Refinement
22
22
  #
23
23
  # @raise [ArgumentError] when conflicting arguments are given
24
24
  #
25
- def initialize(changeset:, workspace_path:, projects: nil,
25
+ def initialize(changesets:, workspace_path:, projects: nil,
26
26
  augmenting_paths_yaml_files:, augmenting_paths_by_target: nil)
27
27
 
28
- @changeset = changeset
28
+ @changesets = changesets
29
29
 
30
30
  raise ArgumentError, 'Can only specify one of workspace_path and projects' if workspace_path && projects
31
31
 
@@ -78,7 +78,7 @@ module Refinement
78
78
  end
79
79
 
80
80
  if !filter_when_scheme_has_changed &&
81
- UsedPath.new(path: Pathname(scheme_path), inclusion_reason: 'scheme').find_in_changeset(changeset)
81
+ UsedPath.new(path: Pathname(scheme_path), inclusion_reason: 'scheme').find_in_changesets(changesets)
82
82
  return scheme
83
83
  end
84
84
 
@@ -145,7 +145,7 @@ module Refinement
145
145
  @augmenting_paths_by_target ||= begin
146
146
  require 'yaml'
147
147
  augmenting_paths_yaml_files.reduce({}) do |augmenting_paths_by_target, yaml_file|
148
- yaml_file = Pathname(yaml_file).expand_path(changeset.repository)
148
+ yaml_file = Pathname(yaml_file).expand_path(changesets.first.repository)
149
149
  yaml = YAML.safe_load(yaml_file.read)
150
150
  augmenting_paths_by_target.merge(yaml) do |_target_name, prior_paths, new_paths|
151
151
  prior_paths + new_paths
@@ -157,9 +157,9 @@ module Refinement
157
157
  # @return [Array<AnnotatedTarget>] targets in the given list of Xcode projects,
158
158
  # annotated according to the given changeset
159
159
  def annotated_targets
160
- workspace_modification = find_workspace_modification_in_changeset
160
+ workspace_modification = find_workspace_modification_in_changesets
161
161
  project_changes = Hash[projects.map do |project|
162
- [project, find_project_modification_in_changeset(project: project) || workspace_modification]
162
+ [project, find_project_modification_in_changesets(project: project) || workspace_modification]
163
163
  end]
164
164
 
165
165
  require 'tsort'
@@ -198,7 +198,7 @@ module Refinement
198
198
  )
199
199
 
200
200
  targets.each_with_object({}) do |target, h|
201
- change_reason = project_changes[target.project] || find_target_modification_in_changeset(target: target)
201
+ change_reason = project_changes[target.project] || find_target_modification_in_changesets(target: target)
202
202
 
203
203
  h[target] = AnnotatedTarget.new(
204
204
  target: target,
@@ -306,11 +306,11 @@ module Refinement
306
306
  # @return [FileModification,Nil] a modification to a file that is used by the given target, or `nil`
307
307
  # if none if found
308
308
  # @param target [Xcodeproj::Project::AbstractTarget]
309
- def find_target_modification_in_changeset(target:)
309
+ def find_target_modification_in_changesets(target:)
310
310
  augmenting_paths = used_paths_from_augmenting_paths_by_target[target.name]
311
- find_in_changeset = ->(path) { path.find_in_changeset(changeset) }
312
- Refinement.map_find(augmenting_paths, &find_in_changeset) ||
313
- Refinement.map_find(target_each_file_path(target: target), &find_in_changeset)
311
+ find_in_changesets = ->(path) { path.find_in_changesets(changesets) }
312
+ Refinement.map_find(augmenting_paths, &find_in_changesets) ||
313
+ Refinement.map_find(target_each_file_path(target: target), &find_in_changesets)
314
314
  end
315
315
 
316
316
  # @yieldparam used_path [UsedPath] an absolute path that belongs to the given project
@@ -334,9 +334,9 @@ module Refinement
334
334
  # if none if found
335
335
  # @note This method does not take into account whatever file paths targets in the project may reference
336
336
  # @param project [Xcodeproj::Project]
337
- def find_project_modification_in_changeset(project:)
337
+ def find_project_modification_in_changesets(project:)
338
338
  Refinement.map_find(project_each_file_path(project: project)) do |path|
339
- path.find_in_changeset(changeset)
339
+ path.find_in_changesets(changesets)
340
340
  end
341
341
  end
342
342
 
@@ -344,17 +344,17 @@ module Refinement
344
344
  # if none if found
345
345
  # @note This method does not take into account whatever file paths projects or
346
346
  # targets in the workspace path may reference
347
- def find_workspace_modification_in_changeset
347
+ def find_workspace_modification_in_changesets
348
348
  return unless workspace_path
349
349
 
350
350
  UsedPath.new(path: workspace_path, inclusion_reason: 'workspace directory')
351
- .find_in_changeset(changeset)
351
+ .find_in_changesets(changesets)
352
352
  end
353
353
 
354
354
  # @return [Hash<String,UsedPath>]
355
355
  def used_paths_from_augmenting_paths_by_target
356
356
  @used_paths_from_augmenting_paths_by_target ||= begin
357
- repo = changeset.repository
357
+ repo = changesets.first.repository
358
358
  used_paths_from_augmenting_paths_by_target =
359
359
  augmenting_paths_by_target.each_with_object({}) do |(name, augmenting_paths), h|
360
360
  h[name] = augmenting_paths.map do |augmenting_path|
@@ -18,12 +18,15 @@ module Refinement
18
18
  attr_reader :modified_paths
19
19
  # @return [Hash<Pathname,FileModification>] modifications keyed by relative path
20
20
  attr_reader :modified_absolute_paths
21
+ # @return [String] a desciption of the changeset
22
+ attr_reader :description
21
23
 
22
24
  private :modifications, :modified_paths, :modified_absolute_paths
23
25
 
24
- def initialize(repository:, modifications:)
26
+ def initialize(repository:, modifications:, description: nil)
25
27
  @repository = repository
26
28
  @modifications = self.class.add_directories(modifications).uniq.freeze
29
+ @description = description
27
30
 
28
31
  @modified_paths = {}
29
32
  @modifications
@@ -145,7 +148,7 @@ module Refinement
145
148
  diff = git!('diff', '--raw', '-z', merge_base, chdir: repository)
146
149
  modifications = parse_raw_diff(diff, repository: repository, base_revision: merge_base).freeze
147
150
 
148
- new(repository: repository, modifications: modifications)
151
+ new(repository: repository, modifications: modifications, description: "since #{base_revision}")
149
152
  end
150
153
 
151
154
  CHANGE_TYPES = {
@@ -19,7 +19,17 @@ module Refinement
19
19
  # @return [Nil, String] If the path has been modified, a string explaining the modification
20
20
  # @param changeset [Changeset] the changeset to search for a modification to this path
21
21
  def find_in_changeset(changeset)
22
- add_reason changeset.find_modification_for_path(absolute_path: path)
22
+ add_reason changeset.find_modification_for_path(absolute_path: path), changeset: changeset
23
+ end
24
+
25
+ # @return [Nil, String] If the path has been modified, a string explaining the modification
26
+ # @param changesets [Array<Changeset>] the changesets to search for a modification to this path
27
+ def find_in_changesets(changesets)
28
+ raise ArgumentError, 'Must provide at least one changeset' if changesets.empty?
29
+
30
+ changesets.reduce(true) do |explanation, changeset|
31
+ explanation && find_in_changeset(changeset)
32
+ end
23
33
  end
24
34
 
25
35
  # @return [String]
@@ -33,10 +43,22 @@ module Refinement
33
43
  # @return [Nil, String] A string suitable for user display that explains
34
44
  # why the given modification means a target is modified
35
45
  # @param modification [Nil, FileModification]
36
- def add_reason(modification)
46
+ # @param changeset [Changeset]
47
+ def add_reason(modification, changeset:)
37
48
  return unless modification
38
49
 
39
- "#{modification.path} (#{inclusion_reason}) #{modification.type}"
50
+ add_changeset_description "#{modification.path} (#{inclusion_reason}) #{modification.type}", changeset: changeset
51
+ end
52
+
53
+ # @return [String] A string suitable for user display that explains
54
+ # why the given modification means a target is modified, including the description
55
+ # of the changeset that contains the modification
56
+ # @param description [String]
57
+ # @param changeset [Nil, Changeset]
58
+ def add_changeset_description(description, changeset:)
59
+ return description unless changeset&.description
60
+
61
+ description + " (#{changeset.description})"
40
62
  end
41
63
 
42
64
  # Represents a path to a YAML file that some target depends upon,
@@ -54,7 +76,7 @@ module Refinement
54
76
  # (see UsedPath#find_in_changeset)
55
77
  def find_in_changeset(changeset)
56
78
  modification, _yaml_diff = changeset.find_modification_for_yaml_keypath(absolute_path: path, keypath: yaml_keypath)
57
- add_reason modification
79
+ add_reason modification, changeset: changeset
58
80
  end
59
81
 
60
82
  # (see UsedPath#to_s)
@@ -65,7 +87,7 @@ module Refinement
65
87
  private
66
88
 
67
89
  # (see UsedPath#add_reason)
68
- def add_reason(modification)
90
+ def add_reason(modification, changeset:)
69
91
  return unless modification
70
92
 
71
93
  keypath_string =
@@ -74,7 +96,7 @@ module Refinement
74
96
  else
75
97
  ' @ ' + yaml_keypath.map { |path| path.to_s =~ /\A[a-zA-Z0-9_]+\z/ ? path : path.inspect }.join('.')
76
98
  end
77
- "#{modification.path}#{keypath_string} (#{inclusion_reason}) #{modification.type}"
99
+ add_changeset_description "#{modification.path}#{keypath_string} (#{inclusion_reason}) #{modification.type}", changeset: changeset
78
100
  end
79
101
  end
80
102
  end
@@ -96,7 +118,16 @@ module Refinement
96
118
 
97
119
  # (see UsedPath#find_in_changeset)
98
120
  def find_in_changeset(changeset)
99
- add_reason changeset.find_modification_for_glob(absolute_glob: glob)
121
+ add_reason changeset.find_modification_for_glob(absolute_glob: glob), changeset: changeset
122
+ end
123
+
124
+ # (see UsedPath#find_in_changesets)
125
+ def find_in_changesets(changesets)
126
+ raise ArgumentError, 'Must provide at least one changeset' if changesets.empty?
127
+
128
+ changesets.reduce(true) do |explanation, changeset|
129
+ explanation && find_in_changeset(changeset)
130
+ end
100
131
  end
101
132
 
102
133
  # (see UsedPath#to_s)
@@ -107,10 +138,17 @@ module Refinement
107
138
  private
108
139
 
109
140
  # (see UsedPath#add_reason)
110
- def add_reason(modification)
141
+ def add_reason(modification, changeset:)
111
142
  return unless modification
112
143
 
113
- "#{modification.path} (#{inclusion_reason}) #{modification.type}"
144
+ add_changeset_description "#{modification.path} (#{inclusion_reason}) #{modification.type}", changeset: changeset
145
+ end
146
+
147
+ # (see UsedPath#add_changeset_description)
148
+ def add_changeset_description(description, changeset:)
149
+ return description unless changeset&.description
150
+
151
+ description + " (#{changeset.description})"
114
152
  end
115
153
  end
116
154
  end
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.4.1
4
+ version: 0.5.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: 2020-08-04 00:00:00.000000000 Z
11
+ date: 2020-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xcodeproj