packs 0.1.0 → 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 +4 -4
- data/README.md +4 -1
- data/bin/rubocop +4 -17
- data/bin/tapioca +4 -17
- data/lib/packs/cli.rb +14 -17
- data/lib/packs/code_ownership_post_processor.rb +1 -1
- data/lib/packs/configuration.rb +2 -3
- data/lib/packs/per_file_processor_interface.rb +2 -1
- data/lib/packs/private/file_move_operation.rb +47 -9
- data/lib/packs/private/interactive_cli/pack_selector.rb +18 -14
- data/lib/packs/private/interactive_cli/team_selector.rb +20 -16
- data/lib/packs/private/interactive_cli/use_cases/get_info.rb +2 -2
- data/lib/packs/private/interactive_cli/use_cases/interface.rb +4 -2
- data/lib/packs/private/interactive_cli/use_cases/move_pack.rb +1 -1
- data/lib/packs/private/interactive_cli/use_cases/query.rb +1 -1
- data/lib/packs/private/interactive_cli.rb +10 -5
- data/lib/packs/private.rb +29 -23
- data/lib/packs/update_references_post_processor.rb +1 -1
- data/lib/packs/user_event_logger.rb +1 -24
- metadata +26 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 221210e029bee06a127a705570b20d9856571bb3ad187f4be782521c65be5901
|
|
4
|
+
data.tar.gz: b401bf88686e51f1316e5e81330edca9dd1a3b8cf78a90f5c46f4dad1058a6bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba96edf990cff199f9bdc26d79477724e294770d66de07520e48d7c7311c30d371cb8b00ae4529c35029ec65d4386e77f9009d62f5df07c29957c5e597c45dc1
|
|
7
|
+
data.tar.gz: 65696d3da54c5b85de8107ae76ed60c79c38167eacd4a98597026405379edfa7de8a117e7a347ed2e7c7ffbb1aa6e69c23145b878d97391e48de227d0d1152c0
|
data/README.md
CHANGED
|
@@ -53,6 +53,9 @@ bin/packwerk init
|
|
|
53
53
|
## Describe available commands or one specific command
|
|
54
54
|
`bin/packs help [COMMAND]`
|
|
55
55
|
|
|
56
|
+
## Print a tree of all available commands
|
|
57
|
+
`bin/packs tree`
|
|
58
|
+
|
|
56
59
|
## Create pack with name packs/your_pack
|
|
57
60
|
`bin/packs create packs/your_pack`
|
|
58
61
|
|
|
@@ -90,7 +93,7 @@ Make sure there are no spaces between the comma-separated list of paths of direc
|
|
|
90
93
|
`bin/packs move packs/destination_pack path/to/file.rb path/to/directory`
|
|
91
94
|
|
|
92
95
|
This is used for moving files into a pack (the pack must already exist).
|
|
93
|
-
Note this works for moving files to packs from the monolith or from other packs
|
|
96
|
+
Note this works for moving files to packs from the monolith or from other packs.
|
|
94
97
|
|
|
95
98
|
Make sure there are no spaces between the comma-separated list of paths of directories.
|
|
96
99
|
|
data/bin/rubocop
CHANGED
|
@@ -8,22 +8,9 @@
|
|
|
8
8
|
# this file is here to facilitate running it.
|
|
9
9
|
#
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
|
13
|
-
Pathname.new(__FILE__).realpath)
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
require "rubygems"
|
|
14
|
+
require "bundler/setup"
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
|
19
|
-
load(bundle_binstub)
|
|
20
|
-
else
|
|
21
|
-
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
22
|
-
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
require 'rubygems'
|
|
27
|
-
require 'bundler/setup'
|
|
28
|
-
|
|
29
|
-
load Gem.bin_path('rubocop', 'rubocop')
|
|
16
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/tapioca
CHANGED
|
@@ -8,22 +8,9 @@
|
|
|
8
8
|
# this file is here to facilitate running it.
|
|
9
9
|
#
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
|
13
|
-
Pathname.new(__FILE__).realpath)
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
require "rubygems"
|
|
14
|
+
require "bundler/setup"
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
|
19
|
-
load(bundle_binstub)
|
|
20
|
-
else
|
|
21
|
-
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
22
|
-
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
require 'rubygems'
|
|
27
|
-
require 'bundler/setup'
|
|
28
|
-
|
|
29
|
-
load Gem.bin_path('tapioca', 'tapioca')
|
|
16
|
+
load Gem.bin_path("tapioca", "tapioca")
|
data/lib/packs/cli.rb
CHANGED
|
@@ -39,10 +39,10 @@ module Packs
|
|
|
39
39
|
exit_successfully
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
POSSIBLE_TYPES = T.let(%w(dependency privacy layer).freeze, T::Array[String])
|
|
43
43
|
desc 'list_top_violations type [ packs/your_pack ]', 'List the top violations of a specific type for packs/your_pack.'
|
|
44
44
|
long_desc <<~LONG_DESC
|
|
45
|
-
Possible types are: #{
|
|
45
|
+
Possible types are: #{POSSIBLE_TYPES.join(', ')}.
|
|
46
46
|
|
|
47
47
|
Want to see who is depending on you? Not sure how your pack's code is being used in an unstated way? You can use this command to list the top dependency violations.
|
|
48
48
|
|
|
@@ -60,7 +60,7 @@ module Packs
|
|
|
60
60
|
).void
|
|
61
61
|
end
|
|
62
62
|
def list_top_violations(type, pack_name = nil)
|
|
63
|
-
raise StandardError, "Invalid type #{type}. Possible types are: #{
|
|
63
|
+
raise StandardError, "Invalid type #{type}. Possible types are: #{POSSIBLE_TYPES.join(', ')}" unless POSSIBLE_TYPES.include?(type)
|
|
64
64
|
|
|
65
65
|
Packs.list_top_violations(
|
|
66
66
|
type: type,
|
|
@@ -85,7 +85,7 @@ module Packs
|
|
|
85
85
|
desc 'move packs/destination_pack path/to/file.rb path/to/directory', 'Move files or directories from one pack to another'
|
|
86
86
|
long_desc <<~LONG_DESC
|
|
87
87
|
This is used for moving files into a pack (the pack must already exist).
|
|
88
|
-
Note this works for moving files to packs from the monolith or from other packs
|
|
88
|
+
Note this works for moving files to packs from the monolith or from other packs.
|
|
89
89
|
|
|
90
90
|
Make sure there are no spaces between the comma-separated list of paths of directories.
|
|
91
91
|
LONG_DESC
|
|
@@ -135,8 +135,8 @@ module Packs
|
|
|
135
135
|
sig { params(pack_names: String).void }
|
|
136
136
|
def get_info(*pack_names)
|
|
137
137
|
selected_types = options[:types].to_s.downcase.split(',')
|
|
138
|
-
invalid_types = selected_types -
|
|
139
|
-
raise StandardError, "Invalid type(s): #{invalid_types.join(', ')}. Possible types are: #{
|
|
138
|
+
invalid_types = selected_types - POSSIBLE_TYPES
|
|
139
|
+
raise StandardError, "Invalid type(s): #{invalid_types.join(', ')}. Possible types are: #{POSSIBLE_TYPES.join(', ')}" unless invalid_types.empty?
|
|
140
140
|
|
|
141
141
|
Private.get_info(
|
|
142
142
|
packs: parse_pack_names(pack_names),
|
|
@@ -176,17 +176,14 @@ module Packs
|
|
|
176
176
|
|
|
177
177
|
private
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def exit_successfully
|
|
188
|
-
Private.exit_with(true)
|
|
189
|
-
end
|
|
179
|
+
sig { params(pack_names: T::Array[String]).returns(T::Array[Packs::Pack]) }
|
|
180
|
+
def parse_pack_names(pack_names)
|
|
181
|
+
pack_names.empty? ? Packs.all : pack_names.filter_map { |p| Packs.find(p.delete_suffix('/')) }
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
sig { void }
|
|
185
|
+
def exit_successfully
|
|
186
|
+
Private.exit_with(true)
|
|
190
187
|
end
|
|
191
188
|
end
|
|
192
189
|
end
|
data/lib/packs/configuration.rb
CHANGED
|
@@ -30,7 +30,7 @@ module Packs
|
|
|
30
30
|
def initialize
|
|
31
31
|
@enforce_dependencies = T.let(default_enforce_dependencies, T::Boolean)
|
|
32
32
|
@user_event_logger = T.let(DefaultUserEventLogger.new, UserEventLogger)
|
|
33
|
-
@on_package_todo_lint_failure = T.let(->(output) {}, OnPackageTodoLintFailure)
|
|
33
|
+
@on_package_todo_lint_failure = T.let(-> (output) {}, OnPackageTodoLintFailure)
|
|
34
34
|
@use_pks = T.let(false, T::Boolean)
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -68,8 +68,7 @@ module Packs
|
|
|
68
68
|
sig { returns(Configuration) }
|
|
69
69
|
def config
|
|
70
70
|
Private.load_client_configuration
|
|
71
|
-
@config
|
|
72
|
-
@config ||= Configuration.new
|
|
71
|
+
@config ||= T.let(Configuration.new, T.nilable(Configuration))
|
|
73
72
|
end
|
|
74
73
|
|
|
75
74
|
sig { params(blk: T.proc.params(arg0: Configuration).void).void }
|
|
@@ -8,7 +8,8 @@ module Packs
|
|
|
8
8
|
abstract!
|
|
9
9
|
|
|
10
10
|
sig { abstract.params(file_move_operation: Private::FileMoveOperation).void }
|
|
11
|
-
def before_move_file!(file_move_operation)
|
|
11
|
+
def before_move_file!(file_move_operation)
|
|
12
|
+
end
|
|
12
13
|
|
|
13
14
|
sig { overridable.params(file_move_operations: T::Array[Private::FileMoveOperation]).void }
|
|
14
15
|
def after_move_files!(file_move_operations)
|
|
@@ -51,8 +51,8 @@ module Packs
|
|
|
51
51
|
).cleanpath
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
sig { returns(FileMoveOperation) }
|
|
55
|
-
def
|
|
54
|
+
sig { returns(T::Array[FileMoveOperation]) }
|
|
55
|
+
def spec_file_move_operations
|
|
56
56
|
path_parts = filepath_without_pack_name.split('/')
|
|
57
57
|
folder = T.must(path_parts[0])
|
|
58
58
|
file_extension = T.must(filepath_without_pack_name.split('.').last)
|
|
@@ -67,11 +67,20 @@ module Packs
|
|
|
67
67
|
new_destination_pathname = spec_pathname_for_non_app(destination_pathname, file_extension, folder)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
ops = [
|
|
71
|
+
FileMoveOperation.new(
|
|
72
|
+
origin_pathname: new_origin_pathname,
|
|
73
|
+
destination_pathname: new_destination_pathname,
|
|
74
|
+
destination_pack: destination_pack
|
|
75
|
+
),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
# For controllers, also include the request spec (spec/requests/<name>_spec.rb) if it exists.
|
|
79
|
+
# Request specs are named without "controller" suffix (e.g. my_controller -> my_spec)
|
|
80
|
+
request_spec_op = request_spec_file_move_operation
|
|
81
|
+
ops << request_spec_op if request_spec_op
|
|
82
|
+
|
|
83
|
+
ops
|
|
75
84
|
end
|
|
76
85
|
|
|
77
86
|
sig { params(filepath: Pathname, pack: T.nilable(Packs::Pack)).returns(String) }
|
|
@@ -94,7 +103,7 @@ module Packs
|
|
|
94
103
|
def spec_pathname_for_app(pathname, file_extension)
|
|
95
104
|
pathname
|
|
96
105
|
.sub('/app/', '/spec/')
|
|
97
|
-
.sub(%r
|
|
106
|
+
.sub(%r(\Aapp/), 'spec/')
|
|
98
107
|
.sub(".#{file_extension}", '_spec.rb')
|
|
99
108
|
end
|
|
100
109
|
|
|
@@ -102,10 +111,39 @@ module Packs
|
|
|
102
111
|
def spec_pathname_for_non_app(pathname, file_extension, folder)
|
|
103
112
|
pathname
|
|
104
113
|
.sub("/#{folder}/", "/spec/#{folder}/")
|
|
105
|
-
.sub(%r{
|
|
114
|
+
.sub(%r(\A#{folder}/), "spec/#{folder}/")
|
|
106
115
|
.sub(".#{file_extension}", '_spec.rb')
|
|
107
116
|
end
|
|
108
117
|
|
|
118
|
+
# Maps app/controllers/<namespaces/>*_controller.rb to spec/requests/<namespaces/>*_spec.rb.
|
|
119
|
+
# Returns nil if the path is not a controller path.
|
|
120
|
+
sig { params(pathname: Pathname).returns(T.nilable(Pathname)) }
|
|
121
|
+
def pathname_to_request_spec(pathname)
|
|
122
|
+
return nil unless pathname.to_s.end_with?('_controller.rb')
|
|
123
|
+
|
|
124
|
+
pathname
|
|
125
|
+
.sub('app/controllers/', 'spec/requests/')
|
|
126
|
+
.sub('/app/', '/spec/') # if destionation doesn't have controller subdirectory
|
|
127
|
+
.sub(%r(\Aapp/), 'spec/')
|
|
128
|
+
.sub(/_controller\.rb\z/, '_spec.rb')
|
|
129
|
+
.cleanpath
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
sig { returns(T.nilable(FileMoveOperation)) }
|
|
133
|
+
def request_spec_file_move_operation
|
|
134
|
+
request_spec_origin = pathname_to_request_spec(origin_pathname)
|
|
135
|
+
return if request_spec_origin.nil? || !request_spec_origin.exist?
|
|
136
|
+
|
|
137
|
+
request_spec_destination = pathname_to_request_spec(destination_pathname)
|
|
138
|
+
return if request_spec_destination.nil?
|
|
139
|
+
|
|
140
|
+
FileMoveOperation.new(
|
|
141
|
+
origin_pathname: request_spec_origin,
|
|
142
|
+
destination_pathname: request_spec_destination,
|
|
143
|
+
destination_pack: destination_pack
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
|
|
109
147
|
sig { params(path: Pathname).returns(FileMoveOperation) }
|
|
110
148
|
def relative_to(path)
|
|
111
149
|
FileMoveOperation.new(
|
|
@@ -10,13 +10,15 @@ module Packs
|
|
|
10
10
|
def self.single_pack_select(prompt, question_text: 'Please use space to select a pack')
|
|
11
11
|
packs = Packs.all.to_h { |t| [t.name, t] }
|
|
12
12
|
|
|
13
|
-
pack_selection = T.let(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
pack_selection = T.let(
|
|
14
|
+
prompt.select(
|
|
15
|
+
question_text,
|
|
16
|
+
packs,
|
|
17
|
+
filter: true,
|
|
18
|
+
per_page: 10,
|
|
19
|
+
show_help: :always
|
|
20
|
+
), T.nilable(Packs::Pack)
|
|
21
|
+
)
|
|
20
22
|
|
|
21
23
|
while pack_selection.nil?
|
|
22
24
|
prompt.error(
|
|
@@ -31,13 +33,15 @@ module Packs
|
|
|
31
33
|
|
|
32
34
|
sig { params(prompt: TTY::Prompt, question_text: String).returns(T::Array[Packs::Pack]) }
|
|
33
35
|
def self.single_or_all_pack_multi_select(prompt, question_text: 'Please use space to select one or more packs')
|
|
34
|
-
pack_selection = T.let(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
pack_selection = T.let(
|
|
37
|
+
prompt.multi_select(
|
|
38
|
+
question_text,
|
|
39
|
+
Packs.all.to_h { |t| [t.name, t] },
|
|
40
|
+
filter: true,
|
|
41
|
+
per_page: 10,
|
|
42
|
+
show_help: :always
|
|
43
|
+
), T::Array[Packs::Pack]
|
|
44
|
+
)
|
|
41
45
|
|
|
42
46
|
while pack_selection.empty?
|
|
43
47
|
prompt.error(
|
|
@@ -9,15 +9,17 @@ module Packs
|
|
|
9
9
|
sig { params(prompt: TTY::Prompt, question_text: String).returns(T.nilable(CodeTeams::Team)) }
|
|
10
10
|
def self.single_select(prompt, question_text: 'Please use space to select a team owner')
|
|
11
11
|
teams = CodeTeams.all.sort_by(&:name).to_h { |t| [t.name, t] }
|
|
12
|
-
return nil if teams.
|
|
13
|
-
|
|
14
|
-
team_selection = T.let(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
return nil if teams.none?
|
|
13
|
+
|
|
14
|
+
team_selection = T.let(
|
|
15
|
+
prompt.select(
|
|
16
|
+
question_text,
|
|
17
|
+
teams,
|
|
18
|
+
filter: true,
|
|
19
|
+
per_page: 10,
|
|
20
|
+
show_help: :always
|
|
21
|
+
), T.nilable(CodeTeams::Team)
|
|
22
|
+
)
|
|
21
23
|
|
|
22
24
|
while team_selection.nil?
|
|
23
25
|
prompt.error(
|
|
@@ -34,13 +36,15 @@ module Packs
|
|
|
34
36
|
def self.multi_select(prompt, question_text: 'Please use space to select team owners')
|
|
35
37
|
teams = CodeTeams.all.to_h { |t| [t.name, t] }
|
|
36
38
|
|
|
37
|
-
team_selection = T.let(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
team_selection = T.let(
|
|
40
|
+
prompt.multi_select(
|
|
41
|
+
question_text,
|
|
42
|
+
teams,
|
|
43
|
+
filter: true,
|
|
44
|
+
per_page: 10,
|
|
45
|
+
show_help: :always
|
|
46
|
+
), T::Array[CodeTeams::Team]
|
|
47
|
+
)
|
|
44
48
|
|
|
45
49
|
while team_selection.empty?
|
|
46
50
|
prompt.error(
|
|
@@ -26,11 +26,11 @@ module Packs
|
|
|
26
26
|
selected_packs = PackSelector.single_or_all_pack_multi_select(prompt, question_text: 'What pack(s) would you like info on?')
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
format = prompt.select('What output format do you want?', %w
|
|
29
|
+
format = prompt.select('What output format do you want?', %w(Detail CSV))
|
|
30
30
|
|
|
31
31
|
types = prompt.multi_select(
|
|
32
32
|
'What violation types do you want stats for?',
|
|
33
|
-
%w
|
|
33
|
+
%w(Privacy Dependency Layer)
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
include_date = !prompt.no?('Should the current date be included in the report?')
|
|
@@ -23,10 +23,12 @@ module Packs
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
sig { abstract.params(prompt: TTY::Prompt).void }
|
|
26
|
-
def perform!(prompt)
|
|
26
|
+
def perform!(prompt)
|
|
27
|
+
end
|
|
27
28
|
|
|
28
29
|
sig { abstract.returns(String) }
|
|
29
|
-
def user_facing_name
|
|
30
|
+
def user_facing_name
|
|
31
|
+
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
end
|
|
@@ -30,7 +30,7 @@ module Packs
|
|
|
30
30
|
|
|
31
31
|
limit = prompt.ask('Specify the limit of constants to analyze', default: 10, convert: :integer)
|
|
32
32
|
|
|
33
|
-
selection = prompt.select('Are you interested in dependency, privacy, or layer violations?', %w
|
|
33
|
+
selection = prompt.select('Are you interested in dependency, privacy, or layer violations?', %w(Dependency Privacy Layer), default: 'Privacy')
|
|
34
34
|
|
|
35
35
|
Packs.list_top_violations(
|
|
36
36
|
type: selection.downcase,
|
|
@@ -28,16 +28,21 @@ module Packs
|
|
|
28
28
|
|
|
29
29
|
sig { params(prompt: T.nilable(TTY::Prompt)).void }
|
|
30
30
|
def self.start!(prompt: nil)
|
|
31
|
-
prompt ||= TTY::Prompt.new(
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
prompt ||= TTY::Prompt.new(
|
|
32
|
+
interrupt: -> {
|
|
33
|
+
puts "\n\nGoodbye! I hope you have a good day."
|
|
34
|
+
exit 1
|
|
35
|
+
}
|
|
36
|
+
)
|
|
34
37
|
help_text = '(Press ↑/↓ arrow to move, Enter to select and letters to filter)'
|
|
35
|
-
choice = prompt.select(
|
|
38
|
+
choice = prompt.select(
|
|
39
|
+
'Hello! What would you like to do?',
|
|
36
40
|
cycle: true,
|
|
37
41
|
filter: true,
|
|
38
42
|
help: help_text,
|
|
39
43
|
show_help: :always,
|
|
40
|
-
per_page: 15
|
|
44
|
+
per_page: 15
|
|
45
|
+
) do |menu|
|
|
41
46
|
menu.enum '.'
|
|
42
47
|
|
|
43
48
|
UseCases::Interface.all.each do |use_case|
|
data/lib/packs/private.rb
CHANGED
|
@@ -22,7 +22,7 @@ module Packs
|
|
|
22
22
|
# This results in the pack not being found, but when we write the package YML it writes to the same place,
|
|
23
23
|
# causing a behaviorally confusing diff.
|
|
24
24
|
# We ignore trailing slashes as an ergonomic feature to the user.
|
|
25
|
-
pack_name.
|
|
25
|
+
pack_name.delete_suffix('/')
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
sig do
|
|
@@ -37,10 +37,12 @@ module Packs
|
|
|
37
37
|
return if !file.exist?
|
|
38
38
|
|
|
39
39
|
count = 0
|
|
40
|
-
file.write(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
file.write(
|
|
41
|
+
file.read.gsub(find.to_s) do
|
|
42
|
+
count += 1
|
|
43
|
+
replace_with.to_s
|
|
44
|
+
end
|
|
45
|
+
)
|
|
44
46
|
Logging.print "Replaced #{count} occurrence(s) of #{find} in #{file}" if count > 0
|
|
45
47
|
end
|
|
46
48
|
|
|
@@ -69,7 +71,7 @@ module Packs
|
|
|
69
71
|
team: team
|
|
70
72
|
)
|
|
71
73
|
add_public_directory(package) if package.enforce_privacy
|
|
72
|
-
|
|
74
|
+
add_readme(package)
|
|
73
75
|
|
|
74
76
|
Logging.section('Next steps') do
|
|
75
77
|
next_steps = Packs.config.user_event_logger.after_create_pack(pack_name)
|
|
@@ -131,7 +133,7 @@ module Packs
|
|
|
131
133
|
)
|
|
132
134
|
[
|
|
133
135
|
file_move_operation,
|
|
134
|
-
file_move_operation.
|
|
136
|
+
*file_move_operation.spec_file_move_operations,
|
|
135
137
|
]
|
|
136
138
|
end
|
|
137
139
|
file_move_operations.each do |file_move_operation|
|
|
@@ -140,7 +142,7 @@ module Packs
|
|
|
140
142
|
end
|
|
141
143
|
end
|
|
142
144
|
|
|
143
|
-
|
|
145
|
+
add_readme(package)
|
|
144
146
|
|
|
145
147
|
per_file_processors.each do |processor|
|
|
146
148
|
processor.after_move_files!(file_move_operations)
|
|
@@ -297,8 +299,8 @@ module Packs
|
|
|
297
299
|
end
|
|
298
300
|
|
|
299
301
|
if other_package.name == parent_name &&
|
|
300
|
-
|
|
301
|
-
|
|
302
|
+
!new_dependencies.include?(new_package_name) &&
|
|
303
|
+
!new_config['ignored_dependencies']&.include?(new_package_name)
|
|
302
304
|
new_dependencies += [new_package_name]
|
|
303
305
|
end
|
|
304
306
|
|
|
@@ -358,7 +360,7 @@ module Packs
|
|
|
358
360
|
|
|
359
361
|
[
|
|
360
362
|
file_move_operation,
|
|
361
|
-
file_move_operation.
|
|
363
|
+
*file_move_operation.spec_file_move_operations,
|
|
362
364
|
]
|
|
363
365
|
end
|
|
364
366
|
|
|
@@ -446,18 +448,22 @@ module Packs
|
|
|
446
448
|
|
|
447
449
|
if public_directory.glob('**/**.rb').none?
|
|
448
450
|
FileUtils.mkdir_p(public_directory)
|
|
449
|
-
|
|
450
|
-
public_directory.join(
|
|
451
|
+
package_name = package.directory.basename.to_s
|
|
452
|
+
FileUtils.mkdir_p(public_directory.join(package_name))
|
|
451
453
|
end
|
|
452
454
|
end
|
|
453
455
|
|
|
454
456
|
sig { params(package: ParsePackwerk::Package).void }
|
|
455
|
-
def self.
|
|
457
|
+
def self.add_readme(package)
|
|
456
458
|
pack_directory = package.directory
|
|
457
459
|
|
|
458
460
|
if !pack_directory.join('README.md').exist?
|
|
459
|
-
|
|
460
|
-
pack_directory.join('
|
|
461
|
+
readme_md = Packs.config.user_event_logger.on_create_readme(package.name)
|
|
462
|
+
pack_directory.join('README.md').write(readme_md)
|
|
463
|
+
|
|
464
|
+
if pack_directory.join('README_TODO.md').exist?
|
|
465
|
+
pack_directory.join('README_TODO.md').delete
|
|
466
|
+
end
|
|
461
467
|
end
|
|
462
468
|
end
|
|
463
469
|
|
|
@@ -484,7 +490,7 @@ module Packs
|
|
|
484
490
|
# but we'll need to add an API to CodeOwnership to do this
|
|
485
491
|
if Pathname.new('config/code_ownership.yml').exist?
|
|
486
492
|
config = {
|
|
487
|
-
'owner' => team.nil? ? 'MyTeam' : team.name
|
|
493
|
+
'owner' => team.nil? ? 'MyTeam' : team.name,
|
|
488
494
|
}
|
|
489
495
|
else
|
|
490
496
|
config = {}
|
|
@@ -526,7 +532,7 @@ module Packs
|
|
|
526
532
|
def self.bust_cache!
|
|
527
533
|
Packs.config.bust_cache!
|
|
528
534
|
# This comes explicitly after `Packs.config.bust_cache!` because
|
|
529
|
-
# otherwise `Packs.config` will attempt to reload the client
|
|
535
|
+
# otherwise `Packs.config` will attempt to reload the client configuration.
|
|
530
536
|
@loaded_client_configuration = false
|
|
531
537
|
end
|
|
532
538
|
|
|
@@ -555,7 +561,7 @@ module Packs
|
|
|
555
561
|
write_package_todo_to_tmp_folder(before, dir_containing_contents_before)
|
|
556
562
|
write_package_todo_to_tmp_folder(after, dir_containing_contents_after)
|
|
557
563
|
|
|
558
|
-
diff =
|
|
564
|
+
diff = %x(diff -r #{dir_containing_contents_before}/ #{dir_containing_contents_after}/)
|
|
559
565
|
# For ease of reading, sub out the tmp directory from the diff
|
|
560
566
|
diff.gsub(dir_containing_contents_before, '').gsub(dir_containing_contents_after, '')
|
|
561
567
|
ensure
|
|
@@ -600,13 +606,13 @@ module Packs
|
|
|
600
606
|
include_date: T::Boolean
|
|
601
607
|
).void
|
|
602
608
|
end
|
|
603
|
-
def self.get_info(packs: Packs.all, format: :detail, types: %i
|
|
609
|
+
def self.get_info(packs: Packs.all, format: :detail, types: %i(privacy dependency layer), include_date: false)
|
|
604
610
|
require 'csv' if format == :csv
|
|
605
611
|
|
|
606
612
|
today = Date.today.iso8601
|
|
607
613
|
violations = {
|
|
608
614
|
inbound: {},
|
|
609
|
-
outbound: {}
|
|
615
|
+
outbound: {},
|
|
610
616
|
}
|
|
611
617
|
|
|
612
618
|
package_by_name = {}
|
|
@@ -623,7 +629,7 @@ module Packs
|
|
|
623
629
|
|
|
624
630
|
all = {
|
|
625
631
|
inbound: T.let([], T::Array[ParsePackwerk::Violation]),
|
|
626
|
-
outbound: T.let([], T::Array[ParsePackwerk::Violation])
|
|
632
|
+
outbound: T.let([], T::Array[ParsePackwerk::Violation]),
|
|
627
633
|
}
|
|
628
634
|
packs.each do |pack|
|
|
629
635
|
all[:inbound] += violations[:inbound][pack.name] || []
|
|
@@ -657,7 +663,7 @@ module Packs
|
|
|
657
663
|
pack_name: pack.name,
|
|
658
664
|
owner: owner.nil? ? 'No one' : owner.name,
|
|
659
665
|
size: pack.relative_path.glob('**/*.rb').count,
|
|
660
|
-
public_api: pack.relative_path.join(package_by_name[pack.name].public_path)
|
|
666
|
+
public_api: pack.relative_path.join(package_by_name[pack.name].public_path),
|
|
661
667
|
}
|
|
662
668
|
|
|
663
669
|
row.delete(:date) unless include_date
|
|
@@ -19,7 +19,7 @@ module Packs
|
|
|
19
19
|
destination_pack = T.must(file_move_operations.first).destination_pack.name
|
|
20
20
|
|
|
21
21
|
if self.class.ripgrep_enabled?
|
|
22
|
-
matching_files =
|
|
22
|
+
matching_files = %x(rg -l --hidden '#{origin_pack}' .)
|
|
23
23
|
matching_files.split("\n").each do |file_name|
|
|
24
24
|
substitute_references!(file_name, origin_pack, destination_pack)
|
|
25
25
|
end
|
|
@@ -124,30 +124,7 @@ module Packs
|
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
sig { params(pack_name: String).returns(String) }
|
|
127
|
-
def
|
|
128
|
-
<<~MSG
|
|
129
|
-
This directory holds your public API!
|
|
130
|
-
|
|
131
|
-
Any classes, constants, or modules that you want other packs to use and you intend to support should go in here.
|
|
132
|
-
Anything that is considered private should go in other folders.
|
|
133
|
-
|
|
134
|
-
If another pack uses classes, constants, or modules that are not in your public folder, it will be considered a "privacy violation" by packwerk.
|
|
135
|
-
You can prevent other packs from using private API by using packwerk.
|
|
136
|
-
|
|
137
|
-
Want to find how your private API is being used today?
|
|
138
|
-
Try running: `bin/packs list_top_violations privacy #{pack_name}`
|
|
139
|
-
|
|
140
|
-
Want to move something into this folder?
|
|
141
|
-
Try running: `bin/packs make_public #{pack_name}/path/to/file.rb`
|
|
142
|
-
|
|
143
|
-
One more thing -- feel free to delete this file and replace it with a README.md describing your package in the main package directory.
|
|
144
|
-
|
|
145
|
-
See #{documentation_link} for more info!
|
|
146
|
-
MSG
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
sig { params(pack_name: String).returns(String) }
|
|
150
|
-
def on_create_readme_todo(pack_name)
|
|
127
|
+
def on_create_readme(pack_name)
|
|
151
128
|
readme_template_pathname = Packs.config.readme_template_pathname
|
|
152
129
|
readme_template = readme_template_pathname.read if readme_template_pathname.exist?
|
|
153
130
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: packs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gusto Engineers
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bigdecimal
|
|
@@ -140,16 +139,16 @@ dependencies:
|
|
|
140
139
|
name: bundler
|
|
141
140
|
requirement: !ruby/object:Gem::Requirement
|
|
142
141
|
requirements:
|
|
143
|
-
- - "
|
|
142
|
+
- - ">="
|
|
144
143
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '
|
|
144
|
+
version: '0'
|
|
146
145
|
type: :development
|
|
147
146
|
prerelease: false
|
|
148
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
148
|
requirements:
|
|
150
|
-
- - "
|
|
149
|
+
- - ">="
|
|
151
150
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: '
|
|
151
|
+
version: '0'
|
|
153
152
|
- !ruby/object:Gem::Dependency
|
|
154
153
|
name: pry
|
|
155
154
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -220,6 +219,20 @@ dependencies:
|
|
|
220
219
|
- - ">="
|
|
221
220
|
- !ruby/object:Gem::Version
|
|
222
221
|
version: '0'
|
|
222
|
+
- !ruby/object:Gem::Dependency
|
|
223
|
+
name: rubocop-gusto
|
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
|
225
|
+
requirements:
|
|
226
|
+
- - ">="
|
|
227
|
+
- !ruby/object:Gem::Version
|
|
228
|
+
version: '0'
|
|
229
|
+
type: :development
|
|
230
|
+
prerelease: false
|
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
232
|
+
requirements:
|
|
233
|
+
- - ">="
|
|
234
|
+
- !ruby/object:Gem::Version
|
|
235
|
+
version: '0'
|
|
223
236
|
- !ruby/object:Gem::Dependency
|
|
224
237
|
name: sorbet
|
|
225
238
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -252,16 +265,16 @@ dependencies:
|
|
|
252
265
|
name: spoom
|
|
253
266
|
requirement: !ruby/object:Gem::Requirement
|
|
254
267
|
requirements:
|
|
255
|
-
- -
|
|
268
|
+
- - ">="
|
|
256
269
|
- !ruby/object:Gem::Version
|
|
257
|
-
version:
|
|
270
|
+
version: '0'
|
|
258
271
|
type: :development
|
|
259
272
|
prerelease: false
|
|
260
273
|
version_requirements: !ruby/object:Gem::Requirement
|
|
261
274
|
requirements:
|
|
262
|
-
- -
|
|
275
|
+
- - ">="
|
|
263
276
|
- !ruby/object:Gem::Version
|
|
264
|
-
version:
|
|
277
|
+
version: '0'
|
|
265
278
|
- !ruby/object:Gem::Dependency
|
|
266
279
|
name: tapioca
|
|
267
280
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -329,7 +342,6 @@ metadata:
|
|
|
329
342
|
source_code_uri: https://github.com/rubyatscale/packs
|
|
330
343
|
changelog_uri: https://github.com/rubyatscale/packs/releases
|
|
331
344
|
allowed_push_host: https://rubygems.org
|
|
332
|
-
post_install_message:
|
|
333
345
|
rdoc_options: []
|
|
334
346
|
require_paths:
|
|
335
347
|
- lib
|
|
@@ -337,15 +349,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
337
349
|
requirements:
|
|
338
350
|
- - ">="
|
|
339
351
|
- !ruby/object:Gem::Version
|
|
340
|
-
version: 2
|
|
352
|
+
version: '3.2'
|
|
341
353
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
342
354
|
requirements:
|
|
343
355
|
- - ">="
|
|
344
356
|
- !ruby/object:Gem::Version
|
|
345
357
|
version: '0'
|
|
346
358
|
requirements: []
|
|
347
|
-
rubygems_version: 3.
|
|
348
|
-
signing_key:
|
|
359
|
+
rubygems_version: 3.6.9
|
|
349
360
|
specification_version: 4
|
|
350
361
|
summary: Provides CLI tools for working with ruby packs.
|
|
351
362
|
test_files: []
|