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 +4 -4
- data/VERSION +1 -1
- data/lib/refinement/analyzer.rb +20 -20
- data/lib/refinement/changeset.rb +5 -2
- data/lib/refinement/used_path.rb +47 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f99f7e0933bae18ddd8c4f6fbd14f3e182f6233a1244b1418ccf678b5c1e471
|
4
|
+
data.tar.gz: 451abebd764ff651e9489095bca0ce0fc4043965e81e962ca49df68e90341367
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f8348156cedae83212560898d95229be93c592347e052a82bd5a1bd3b13d76a7298703976f4e93799cd8d38543316409462d9c6ef564e1680bdde746bf084aa
|
7
|
+
data.tar.gz: 1109c4b167045b0a2ac2ba45aa036ec6b3d4aacf06726be393c68fe072ee49479d61d41c89a6a29ad927b1e419a3e7932f82acba25ccf02fe4a08efc0a8aaae6
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/refinement/analyzer.rb
CHANGED
@@ -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 :
|
8
|
-
private :
|
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
|
11
|
-
# @param
|
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(
|
25
|
+
def initialize(changesets:, workspace_path:, projects: nil,
|
26
26
|
augmenting_paths_yaml_files:, augmenting_paths_by_target: nil)
|
27
27
|
|
28
|
-
@
|
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').
|
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(
|
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 =
|
160
|
+
workspace_modification = find_workspace_modification_in_changesets
|
161
161
|
project_changes = Hash[projects.map do |project|
|
162
|
-
[project,
|
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] ||
|
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
|
309
|
+
def find_target_modification_in_changesets(target:)
|
310
310
|
augmenting_paths = used_paths_from_augmenting_paths_by_target[target.name]
|
311
|
-
|
312
|
-
Refinement.map_find(augmenting_paths, &
|
313
|
-
Refinement.map_find(target_each_file_path(target: target), &
|
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
|
337
|
+
def find_project_modification_in_changesets(project:)
|
338
338
|
Refinement.map_find(project_each_file_path(project: project)) do |path|
|
339
|
-
path.
|
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
|
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
|
-
.
|
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 =
|
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|
|
data/lib/refinement/changeset.rb
CHANGED
@@ -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 = {
|
data/lib/refinement/used_path.rb
CHANGED
@@ -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
|
-
|
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
|
+
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-
|
11
|
+
date: 2020-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xcodeproj
|