use_packwerk 0.55.0 → 0.57.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/packs +5 -0
- data/lib/use_packwerk/cli.rb +10 -10
- data/lib/use_packwerk/code_ownership_post_processor.rb +3 -3
- data/lib/use_packwerk/configuration.rb +18 -14
- data/lib/use_packwerk/default_user_event_logger.rb +7 -0
- data/lib/use_packwerk/logging.rb +1 -2
- data/lib/use_packwerk/per_file_processor_interface.rb +1 -2
- data/lib/use_packwerk/private/file_move_operation.rb +9 -11
- data/lib/use_packwerk/private/interactive_cli/pack_selector.rb +34 -0
- data/lib/use_packwerk/private/interactive_cli/team_selector.rb +35 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/add_dependency.rb +30 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/create.rb +27 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/get_info.rb +74 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/interface.rb +34 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/make_public.rb +34 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/move.rb +36 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/nest.rb +31 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/query.rb +51 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/rename.rb +34 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/update_deprecations.rb +25 -0
- data/lib/use_packwerk/private/interactive_cli/use_cases/validate.rb +25 -0
- data/lib/use_packwerk/private/interactive_cli.rb +48 -0
- data/lib/use_packwerk/private/pack_relationship_analyzer.rb +24 -108
- data/lib/use_packwerk/private.rb +126 -161
- data/lib/use_packwerk/rubocop_post_processor.rb +17 -17
- data/lib/use_packwerk/user_event_logger.rb +265 -0
- data/lib/use_packwerk.rb +38 -76
- metadata +74 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f49d1c83c2428ea899e55eb53afa3ae0744e3257e08461066b098662de34c3d
|
4
|
+
data.tar.gz: 43350c95f8a33c1900c80f152eee0c644bc14376e69f2f13f1f9799162ea79f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c556f16dc02d9fbdc8a895ba1092abd003d258bfa43e8a89f68c90bd440da99edc446a5ea89bc85aa25b8e4547deb4b2256f7b7ccaca975b7cfcf1e202331c22
|
7
|
+
data.tar.gz: 816849ee8b3b65cb2307a4982b12114645f2890d998aee23ce685f78cf4ac41ba304cff44a63cf6f42604d08a59883b4e9fcd05f7f0300c72e1aa4223d14fe27
|
data/bin/packs
ADDED
data/lib/use_packwerk/cli.rb
CHANGED
@@ -6,13 +6,13 @@ module UsePackwerk
|
|
6
6
|
class CLI < Thor
|
7
7
|
extend T::Sig
|
8
8
|
|
9
|
-
desc
|
9
|
+
desc 'create packs/your_pack', 'Create pack with name packs/your_pack'
|
10
10
|
sig { params(pack_name: String).void }
|
11
11
|
def create(pack_name)
|
12
12
|
UsePackwerk.create_pack!(pack_name: pack_name)
|
13
13
|
end
|
14
14
|
|
15
|
-
desc
|
15
|
+
desc 'add_dependency packs/from_pack packs/to_pack', 'Add packs/to_pack to packs/from_pack/package.yml list of dependencies'
|
16
16
|
long_desc <<~LONG_DESC
|
17
17
|
Use this to add a dependency between packs.
|
18
18
|
|
@@ -29,7 +29,7 @@ module UsePackwerk
|
|
29
29
|
)
|
30
30
|
end
|
31
31
|
|
32
|
-
desc
|
32
|
+
desc 'list_top_dependency_violations packs/your_pack', 'List the top dependency violations of packs/your_pack'
|
33
33
|
option :limit, type: :numeric, default: 10, aliases: :l, banner: 'Specify the limit of constants to analyze'
|
34
34
|
sig { params(pack_name: String).void }
|
35
35
|
def list_top_dependency_violations(pack_name)
|
@@ -39,7 +39,7 @@ module UsePackwerk
|
|
39
39
|
)
|
40
40
|
end
|
41
41
|
|
42
|
-
desc
|
42
|
+
desc 'list_top_privacy_violations packs/your_pack', 'List the top privacy violations of packs/your_pack'
|
43
43
|
option :limit, type: :numeric, default: 10, aliases: :l, banner: 'Specify the limit of constants to analyze'
|
44
44
|
sig { params(pack_name: String).void }
|
45
45
|
def list_top_privacy_violations(pack_name)
|
@@ -49,32 +49,32 @@ module UsePackwerk
|
|
49
49
|
)
|
50
50
|
end
|
51
51
|
|
52
|
-
desc
|
52
|
+
desc 'make_public path/to/file.rb path/to/directory', 'Pass in a space-separated list of file or directory paths to make public'
|
53
53
|
sig { params(paths: String).void }
|
54
54
|
def make_public(*paths)
|
55
55
|
UsePackwerk.make_public!(
|
56
56
|
paths_relative_to_root: paths,
|
57
|
-
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
57
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
58
58
|
)
|
59
59
|
end
|
60
60
|
|
61
|
-
desc
|
61
|
+
desc 'move packs/destination_pack path/to/file.rb path/to/directory', 'Pass in a destination pack and a space-separated list of file or directory paths to move to the destination pack'
|
62
62
|
sig { params(pack_name: String, paths: String).void }
|
63
63
|
def move(pack_name, *paths)
|
64
64
|
UsePackwerk.move_to_pack!(
|
65
65
|
pack_name: pack_name,
|
66
66
|
paths_relative_to_root: paths,
|
67
|
-
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
67
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
68
68
|
)
|
69
69
|
end
|
70
70
|
|
71
|
-
desc
|
71
|
+
desc 'move_to_parent packs/parent_pack packs/child_pack', 'Pass in a parent pack and another pack to be made as a child to the parent pack!'
|
72
72
|
sig { params(parent_name: String, pack_name: String).void }
|
73
73
|
def move_to_parent(parent_name, pack_name)
|
74
74
|
UsePackwerk.move_to_parent!(
|
75
75
|
parent_name: parent_name,
|
76
76
|
pack_name: pack_name,
|
77
|
-
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
77
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
78
78
|
)
|
79
79
|
end
|
80
80
|
end
|
@@ -22,7 +22,7 @@ module UsePackwerk
|
|
22
22
|
UsePackwerk.replace_in_file(
|
23
23
|
file: code_owners_allow_list_file.to_s,
|
24
24
|
find: relative_path_to_origin,
|
25
|
-
replace_with: relative_path_to_destination
|
25
|
+
replace_with: relative_path_to_destination
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
@@ -45,11 +45,11 @@ module UsePackwerk
|
|
45
45
|
if @teams.any?
|
46
46
|
Logging.section('Code Ownership') do
|
47
47
|
Logging.print('This section contains info about the current ownership distribution of the moved files.')
|
48
|
-
@teams.group_by { |team| team }.sort_by { |
|
48
|
+
@teams.group_by { |team| team }.sort_by { |_team, instances| -instances.count }.each do |team, instances|
|
49
49
|
Logging.print " #{team} - #{instances.count} files"
|
50
50
|
end
|
51
51
|
if @did_move_files
|
52
|
-
Logging.print
|
52
|
+
Logging.print 'Since the destination package has package-based ownership, file-annotations were removed from moved files.'
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# typed: strict
|
2
2
|
|
3
|
+
require 'use_packwerk/user_event_logger'
|
4
|
+
require 'use_packwerk/default_user_event_logger'
|
5
|
+
|
3
6
|
module UsePackwerk
|
4
7
|
class Configuration
|
5
8
|
extend T::Sig
|
@@ -7,28 +10,28 @@ module UsePackwerk
|
|
7
10
|
sig { params(enforce_dependencies: T::Boolean).void }
|
8
11
|
attr_writer :enforce_dependencies
|
9
12
|
|
10
|
-
sig {
|
11
|
-
|
13
|
+
sig { returns(UserEventLogger) }
|
14
|
+
attr_accessor :user_event_logger
|
12
15
|
|
13
16
|
sig { void }
|
14
17
|
def initialize
|
15
|
-
@enforce_dependencies = T.let(
|
16
|
-
@
|
18
|
+
@enforce_dependencies = T.let(default_enforce_dependencies, T::Boolean)
|
19
|
+
@user_event_logger = T.let(DefaultUserEventLogger.new, UserEventLogger)
|
17
20
|
end
|
18
21
|
|
19
22
|
sig { returns(T::Boolean) }
|
20
23
|
def enforce_dependencies
|
21
|
-
|
22
|
-
@enforce_dependencies
|
23
|
-
else
|
24
|
-
true
|
25
|
-
end
|
24
|
+
@enforce_dependencies
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
sig { void }
|
28
|
+
def bust_cache!
|
29
|
+
@enforce_dependencies = default_enforce_dependencies
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { returns(T::Boolean) }
|
33
|
+
def default_enforce_dependencies
|
34
|
+
true
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -37,12 +40,13 @@ module UsePackwerk
|
|
37
40
|
|
38
41
|
sig { returns(Configuration) }
|
39
42
|
def config
|
43
|
+
Private.load_client_configuration
|
40
44
|
@config = T.let(@config, T.nilable(Configuration))
|
41
45
|
@config ||= Configuration.new
|
42
46
|
end
|
43
47
|
|
44
48
|
sig { params(blk: T.proc.params(arg0: Configuration).void).void }
|
45
|
-
def configure(&blk)
|
49
|
+
def configure(&blk)
|
46
50
|
yield(config)
|
47
51
|
end
|
48
52
|
end
|
data/lib/use_packwerk/logging.rb
CHANGED
@@ -9,7 +9,7 @@ module UsePackwerk
|
|
9
9
|
sig { params(title: String, block: T.proc.void).void }
|
10
10
|
def self.section(title, &block)
|
11
11
|
print_divider
|
12
|
-
out ColorizedString.new(
|
12
|
+
out ColorizedString.new(title).green.bold
|
13
13
|
out "\n"
|
14
14
|
yield
|
15
15
|
end
|
@@ -35,4 +35,3 @@ module UsePackwerk
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
@@ -8,8 +8,7 @@ module UsePackwerk
|
|
8
8
|
abstract!
|
9
9
|
|
10
10
|
sig { abstract.params(file_move_operation: Private::FileMoveOperation).void }
|
11
|
-
def before_move_file!(file_move_operation)
|
12
|
-
end
|
11
|
+
def before_move_file!(file_move_operation); end
|
13
12
|
|
14
13
|
sig { void }
|
15
14
|
def print_final_message!
|
@@ -18,7 +18,6 @@ module UsePackwerk
|
|
18
18
|
def self.destination_pathname_for_package_move(origin_pathname, new_package_root)
|
19
19
|
origin_pack = T.must(ParsePackwerk.package_from_path(origin_pathname))
|
20
20
|
|
21
|
-
new_implementation = nil
|
22
21
|
if origin_pack.name == ParsePackwerk::ROOT_PACKAGE_NAME
|
23
22
|
new_package_root.join(origin_pathname).cleanpath
|
24
23
|
else
|
@@ -28,7 +27,6 @@ module UsePackwerk
|
|
28
27
|
|
29
28
|
sig { params(origin_pathname: Pathname).returns(Pathname) }
|
30
29
|
def self.destination_pathname_for_new_public_api(origin_pathname)
|
31
|
-
|
32
30
|
origin_pack = T.must(ParsePackwerk.package_from_path(origin_pathname))
|
33
31
|
if origin_pack.name == ParsePackwerk::ROOT_PACKAGE_NAME
|
34
32
|
filepath_without_pack_name = origin_pathname.to_s
|
@@ -37,15 +35,15 @@ module UsePackwerk
|
|
37
35
|
end
|
38
36
|
|
39
37
|
# We join the pack name with the rest of the path...
|
40
|
-
path_parts = filepath_without_pack_name.split(
|
38
|
+
path_parts = filepath_without_pack_name.split('/')
|
41
39
|
Pathname.new(origin_pack.name).join(
|
42
40
|
# ... keeping the "app" or "spec"
|
43
41
|
T.must(path_parts[0]),
|
44
42
|
# ... substituting "controllers," "services," etc. with "public"
|
45
43
|
'public',
|
46
44
|
# ... then the rest is the same
|
47
|
-
T.must(path_parts[2..]).join(
|
48
|
-
|
45
|
+
T.must(path_parts[2..]).join('/')
|
46
|
+
# and we take the cleanpath so `./app/...` becomes `app/...`
|
49
47
|
).cleanpath
|
50
48
|
end
|
51
49
|
|
@@ -54,16 +52,16 @@ module UsePackwerk
|
|
54
52
|
# This could probably be implemented by some "strategy pattern" where different extension types are handled by different helpers
|
55
53
|
# Such a thing could also include, for example, when moving a controller, moving its ERB view too.
|
56
54
|
if origin_pathname.extname == '.rake'
|
57
|
-
new_origin_pathname = origin_pathname.sub('/lib/', '/spec/lib/').sub(
|
58
|
-
new_destination_pathname = destination_pathname.sub('/lib/', '/spec/lib/').sub(
|
55
|
+
new_origin_pathname = origin_pathname.sub('/lib/', '/spec/lib/').sub(%r{^lib/}, 'spec/lib/').sub('.rake', '_spec.rb')
|
56
|
+
new_destination_pathname = destination_pathname.sub('/lib/', '/spec/lib/').sub(%r{^lib/}, 'spec/lib/').sub('.rake', '_spec.rb')
|
59
57
|
else
|
60
|
-
new_origin_pathname = origin_pathname.sub('/app/', '/spec/').sub(
|
61
|
-
new_destination_pathname = destination_pathname.sub('/app/', '/spec/').sub(
|
58
|
+
new_origin_pathname = origin_pathname.sub('/app/', '/spec/').sub(%r{^app/}, 'spec/').sub('.rb', '_spec.rb')
|
59
|
+
new_destination_pathname = destination_pathname.sub('/app/', '/spec/').sub(%r{^app/}, 'spec/').sub('.rb', '_spec.rb')
|
62
60
|
end
|
63
61
|
FileMoveOperation.new(
|
64
62
|
origin_pathname: new_origin_pathname,
|
65
63
|
destination_pathname: new_destination_pathname,
|
66
|
-
destination_pack: destination_pack
|
64
|
+
destination_pack: destination_pack
|
67
65
|
)
|
68
66
|
end
|
69
67
|
|
@@ -74,7 +72,7 @@ module UsePackwerk
|
|
74
72
|
FileMoveOperation.new(
|
75
73
|
origin_pathname: origin_pathname.relative_path_from(path),
|
76
74
|
destination_pathname: destination_pathname.relative_path_from(path),
|
77
|
-
destination_pack: destination_pack
|
75
|
+
destination_pack: destination_pack
|
78
76
|
)
|
79
77
|
end
|
80
78
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
class PackSelector
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(ParsePackwerk::Package) }
|
10
|
+
def self.single_pack_select(prompt, question_text: 'Please select a pack')
|
11
|
+
packs = ParsePackwerk.all.to_h { |t| [t.name, t] }
|
12
|
+
prompt.select(
|
13
|
+
question_text,
|
14
|
+
packs,
|
15
|
+
filter: true,
|
16
|
+
per_page: 10,
|
17
|
+
show_help: :always
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(T::Array[ParsePackwerk::Package]) }
|
22
|
+
def self.single_or_all_pack_multi_select(prompt, question_text: 'Please select one or more packs')
|
23
|
+
prompt.multi_select(
|
24
|
+
question_text,
|
25
|
+
ParsePackwerk.all.to_h { |t| [t.name, t] },
|
26
|
+
filter: true,
|
27
|
+
per_page: 10,
|
28
|
+
show_help: :always
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
class TeamSelector
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(CodeTeams::Team) }
|
10
|
+
def self.single_select(prompt, question_text: 'Please select a team owner')
|
11
|
+
teams = CodeTeams.all.to_h { |t| [t.name, t] }
|
12
|
+
prompt.select(
|
13
|
+
question_text,
|
14
|
+
teams,
|
15
|
+
filter: true,
|
16
|
+
per_page: 10,
|
17
|
+
show_help: :always
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(T::Array[CodeTeams::Team]) }
|
22
|
+
def self.multi_select(prompt, question_text: 'Please select team owners')
|
23
|
+
teams = CodeTeams.all.to_h { |t| [t.name, t] }
|
24
|
+
prompt.multi_select(
|
25
|
+
question_text,
|
26
|
+
teams,
|
27
|
+
filter: true,
|
28
|
+
per_page: 10,
|
29
|
+
show_help: :always
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class AddDependency
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
13
|
+
def perform!(prompt)
|
14
|
+
dependent_pack = PackSelector.single_pack_select(prompt, question_text: 'Please select the pack you are adding a dependency to.')
|
15
|
+
dependency_pack = PackSelector.single_pack_select(prompt, question_text: "Please select the pack that #{dependent_pack.name} should depend on.")
|
16
|
+
UsePackwerk.add_dependency!(
|
17
|
+
pack_name: dependent_pack.name,
|
18
|
+
dependency_name: dependency_pack.name
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
sig { override.returns(String) }
|
23
|
+
def user_facing_name
|
24
|
+
'Add a dependency'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Create
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
13
|
+
def perform!(prompt)
|
14
|
+
pack_name = prompt.ask('What should the name of your pack be?', value: 'packs/')
|
15
|
+
team = TeamSelector.single_select(prompt)
|
16
|
+
UsePackwerk.create_pack!(pack_name: pack_name, team: team)
|
17
|
+
end
|
18
|
+
|
19
|
+
sig { override.returns(String) }
|
20
|
+
def user_facing_name
|
21
|
+
'Create a new pack'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class GetInfo
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.returns(String) }
|
13
|
+
def user_facing_name
|
14
|
+
'Get info on one or more packs'
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
18
|
+
def perform!(prompt)
|
19
|
+
team_or_pack = prompt.select('Do you want info by team or by pack?', ['By team', 'By pack'])
|
20
|
+
|
21
|
+
if team_or_pack == 'By team'
|
22
|
+
teams = TeamSelector.multi_select(prompt)
|
23
|
+
selected_packs = ParsePackwerk.all.select do |p|
|
24
|
+
teams.map(&:name).include?(CodeOwnership.for_package(p)&.name)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
selected_packs = PackSelector.single_or_all_pack_multi_select(prompt, question_text: 'What pack(s) would you like info on?')
|
28
|
+
end
|
29
|
+
|
30
|
+
inbound_violations = {}
|
31
|
+
outbound_violations = {}
|
32
|
+
ParsePackwerk.all.each do |p|
|
33
|
+
violations_for_pack = ParsePackwerk::DeprecatedReferences.for(p).violations
|
34
|
+
violations_for_pack.each do |violation|
|
35
|
+
outbound_violations[p.name] ||= []
|
36
|
+
outbound_violations[p.name] << violation
|
37
|
+
inbound_violations[violation.to_package_name] ||= []
|
38
|
+
inbound_violations[violation.to_package_name] << violation
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "You've selected #{selected_packs.count} packs. Wow! Here's all the info."
|
43
|
+
all_inbound = T.let([], T::Array[ParsePackwerk::Violation])
|
44
|
+
all_outbound = T.let([], T::Array[ParsePackwerk::Violation])
|
45
|
+
selected_packs.each do |pack|
|
46
|
+
all_inbound += inbound_violations[pack.name] || []
|
47
|
+
all_outbound += outbound_violations[pack.name] || []
|
48
|
+
end
|
49
|
+
|
50
|
+
puts "There are #{all_inbound.select(&:privacy?).sum { |v| v.files.count }} total inbound privacy violations"
|
51
|
+
puts "There are #{all_inbound.select(&:dependency?).sum { |v| v.files.count }} total inbound dependency violations"
|
52
|
+
puts "There are #{all_outbound.select(&:privacy?).sum { |v| v.files.count }} total outbound privacy violations"
|
53
|
+
puts "There are #{all_outbound.select(&:dependency?).sum { |v| v.files.count }} total outbound dependency violations"
|
54
|
+
|
55
|
+
selected_packs.sort_by { |p| -p.directory.glob('**/*.rb').count }.each do |pack|
|
56
|
+
puts "\n=========== Info about: #{pack.name}"
|
57
|
+
owner = CodeOwnership.for_package(pack)
|
58
|
+
puts "Owned by: #{owner.nil? ? 'No one' : owner.name}"
|
59
|
+
puts "Size: #{pack.directory.glob('**/*.rb').count} ruby files"
|
60
|
+
puts "Public API: #{pack.directory.join('app/public')}"
|
61
|
+
|
62
|
+
inbound_for_pack = inbound_violations[pack.name] || []
|
63
|
+
outbound_for_pack = outbound_violations[pack.name] || []
|
64
|
+
puts "There are #{inbound_for_pack.select(&:privacy?).sum { |v| v.files.count }} inbound privacy violations"
|
65
|
+
puts "There are #{inbound_for_pack.flatten.select(&:dependency?).sum { |v| v.files.count }} inbound dependency violations"
|
66
|
+
puts "There are #{outbound_for_pack.select(&:privacy?).sum { |v| v.files.count }} outbound privacy violations"
|
67
|
+
puts "There are #{outbound_for_pack.flatten.select(&:dependency?).sum { |v| v.files.count }} outbound dependency violations"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
module Interface
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
|
11
|
+
interface!
|
12
|
+
|
13
|
+
sig { params(base: Class).void }
|
14
|
+
def self.included(base)
|
15
|
+
@use_cases ||= T.let(@use_cases, T.nilable(T::Array[Class]))
|
16
|
+
@use_cases ||= []
|
17
|
+
@use_cases << base
|
18
|
+
end
|
19
|
+
|
20
|
+
sig { returns(T::Array[Interface]) }
|
21
|
+
def self.all
|
22
|
+
T.unsafe(@use_cases).map(&:new)
|
23
|
+
end
|
24
|
+
|
25
|
+
sig { abstract.params(prompt: TTY::Prompt).void }
|
26
|
+
def perform!(prompt); end
|
27
|
+
|
28
|
+
sig { abstract.returns(String) }
|
29
|
+
def user_facing_name; end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class MakePublic
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.returns(String) }
|
13
|
+
def user_facing_name
|
14
|
+
'Make files or directories public'
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
18
|
+
def perform!(prompt)
|
19
|
+
raw_paths_relative_to_root = prompt.multiline('Please copy in a space or new line separated list of files or directories to make public')
|
20
|
+
paths_relative_to_root = T.let([], T::Array[String])
|
21
|
+
raw_paths_relative_to_root.each do |path|
|
22
|
+
paths_relative_to_root += path.chomp.split
|
23
|
+
end
|
24
|
+
|
25
|
+
UsePackwerk.make_public!(
|
26
|
+
paths_relative_to_root: paths_relative_to_root,
|
27
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Move
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
13
|
+
def perform!(prompt)
|
14
|
+
pack = PackSelector.single_pack_select(prompt, question_text: 'Please select a destination pack')
|
15
|
+
raw_paths_relative_to_root = prompt.multiline('Please copy in a space or new line separated list of files or directories')
|
16
|
+
paths_relative_to_root = T.let([], T::Array[String])
|
17
|
+
raw_paths_relative_to_root.each do |path|
|
18
|
+
paths_relative_to_root += path.chomp.split
|
19
|
+
end
|
20
|
+
|
21
|
+
UsePackwerk.move_to_pack!(
|
22
|
+
pack_name: pack.name,
|
23
|
+
paths_relative_to_root: paths_relative_to_root,
|
24
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
sig { override.returns(String) }
|
29
|
+
def user_facing_name
|
30
|
+
'Move files'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module UsePackwerk
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Nest
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
13
|
+
def perform!(prompt)
|
14
|
+
child_pack = PackSelector.single_pack_select(prompt, question_text: 'Please select the pack that will be nested')
|
15
|
+
parent_pack = PackSelector.single_pack_select(prompt, question_text: 'Please select the pack that will be the parent')
|
16
|
+
UsePackwerk.move_to_parent!(
|
17
|
+
parent_name: parent_pack.name,
|
18
|
+
pack_name: child_pack.name,
|
19
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
sig { override.returns(String) }
|
24
|
+
def user_facing_name
|
25
|
+
'Nest one pack under another'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|