refinement 0.4.1 → 0.5.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: 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