packs 0.0.5 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +101 -12
- data/bin/packs +10 -0
- data/bin/rubocop +29 -0
- data/bin/tapioca +29 -0
- data/lib/packs/cli.rb +164 -0
- data/lib/packs/code_ownership_post_processor.rb +58 -0
- data/lib/packs/configuration.rb +61 -0
- data/lib/packs/default_user_event_logger.rb +7 -0
- data/lib/packs/logging.rb +37 -0
- data/lib/packs/per_file_processor_interface.rb +18 -0
- data/lib/packs/private/file_move_operation.rb +80 -0
- data/lib/packs/private/interactive_cli/file_selector.rb +26 -0
- data/lib/packs/private/interactive_cli/pack_selector.rb +55 -0
- data/lib/packs/private/interactive_cli/team_selector.rb +58 -0
- data/lib/packs/private/interactive_cli/use_cases/add_dependency.rb +30 -0
- data/lib/packs/private/interactive_cli/use_cases/check.rb +25 -0
- data/lib/packs/private/interactive_cli/use_cases/create.rb +27 -0
- data/lib/packs/private/interactive_cli/use_cases/get_info.rb +37 -0
- data/lib/packs/private/interactive_cli/use_cases/interface.rb +34 -0
- data/lib/packs/private/interactive_cli/use_cases/lint_package_todo_yml_files.rb +25 -0
- data/lib/packs/private/interactive_cli/use_cases/lint_package_yml_files.rb +26 -0
- data/lib/packs/private/interactive_cli/use_cases/make_public.rb +30 -0
- data/lib/packs/private/interactive_cli/use_cases/move.rb +32 -0
- data/lib/packs/private/interactive_cli/use_cases/move_to_parent.rb +31 -0
- data/lib/packs/private/interactive_cli/use_cases/query.rb +51 -0
- data/lib/packs/private/interactive_cli/use_cases/rename.rb +25 -0
- data/lib/packs/private/interactive_cli/use_cases/update.rb +25 -0
- data/lib/packs/private/interactive_cli/use_cases/validate.rb +25 -0
- data/lib/packs/private/interactive_cli/use_cases/visualize.rb +44 -0
- data/lib/packs/private/interactive_cli.rb +52 -0
- data/lib/packs/private/pack_relationship_analyzer.rb +135 -0
- data/lib/packs/private/packwerk_wrapper/offenses_aggregator_formatter.rb +44 -0
- data/lib/packs/private/packwerk_wrapper.rb +70 -0
- data/lib/packs/private.rb +606 -4
- data/lib/packs/rubocop_post_processor.rb +30 -0
- data/lib/packs/user_event_logger.rb +199 -0
- data/lib/packs.rb +233 -53
- metadata +225 -14
- data/lib/packs/pack.rb +0 -43
- data/lib/packs/private/configuration.rb +0 -36
- data/lib/packs/rspec/fixture_helper.rb +0 -33
- data/lib/packs/rspec/support.rb +0 -21
@@ -0,0 +1,55 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
class PackSelector
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(Packs::Pack) }
|
10
|
+
def self.single_pack_select(prompt, question_text: 'Please use space to select a pack')
|
11
|
+
packs = Packs.all.to_h { |t| [t.name, t] }
|
12
|
+
|
13
|
+
pack_selection = T.let(prompt.select(
|
14
|
+
question_text,
|
15
|
+
packs,
|
16
|
+
filter: true,
|
17
|
+
per_page: 10,
|
18
|
+
show_help: :always
|
19
|
+
), T.nilable(Packs::Pack))
|
20
|
+
|
21
|
+
while pack_selection.nil?
|
22
|
+
prompt.error(
|
23
|
+
'No packs were selected, please select a pack using the space key before pressing enter.'
|
24
|
+
)
|
25
|
+
|
26
|
+
pack_selection = single_pack_select(prompt, question_text: question_text)
|
27
|
+
end
|
28
|
+
|
29
|
+
pack_selection
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(T::Array[Packs::Pack]) }
|
33
|
+
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(prompt.multi_select(
|
35
|
+
question_text,
|
36
|
+
Packs.all.to_h { |t| [t.name, t] },
|
37
|
+
filter: true,
|
38
|
+
per_page: 10,
|
39
|
+
show_help: :always
|
40
|
+
), T::Array[Packs::Pack])
|
41
|
+
|
42
|
+
while pack_selection.empty?
|
43
|
+
prompt.error(
|
44
|
+
'No packs were selected, please select one or more packs using the space key before pressing enter.'
|
45
|
+
)
|
46
|
+
|
47
|
+
pack_selection = single_or_all_pack_multi_select(prompt, question_text: question_text)
|
48
|
+
end
|
49
|
+
|
50
|
+
pack_selection
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
class TeamSelector
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(T.nilable(CodeTeams::Team)) }
|
10
|
+
def self.single_select(prompt, question_text: 'Please use space to select a team owner')
|
11
|
+
teams = CodeTeams.all.sort_by(&:name).to_h { |t| [t.name, t] }
|
12
|
+
return nil if teams.count == 0
|
13
|
+
|
14
|
+
team_selection = T.let(prompt.select(
|
15
|
+
question_text,
|
16
|
+
teams,
|
17
|
+
filter: true,
|
18
|
+
per_page: 10,
|
19
|
+
show_help: :always
|
20
|
+
), T.nilable(CodeTeams::Team))
|
21
|
+
|
22
|
+
while team_selection.nil?
|
23
|
+
prompt.error(
|
24
|
+
'No owners were selected, please select an owner using the space key before pressing enter.'
|
25
|
+
)
|
26
|
+
|
27
|
+
team_selection = single_select(prompt, question_text: question_text)
|
28
|
+
end
|
29
|
+
|
30
|
+
team_selection
|
31
|
+
end
|
32
|
+
|
33
|
+
sig { params(prompt: TTY::Prompt, question_text: String).returns(T::Array[CodeTeams::Team]) }
|
34
|
+
def self.multi_select(prompt, question_text: 'Please use space to select team owners')
|
35
|
+
teams = CodeTeams.all.to_h { |t| [t.name, t] }
|
36
|
+
|
37
|
+
team_selection = T.let(prompt.multi_select(
|
38
|
+
question_text,
|
39
|
+
teams,
|
40
|
+
filter: true,
|
41
|
+
per_page: 10,
|
42
|
+
show_help: :always
|
43
|
+
), T::Array[CodeTeams::Team])
|
44
|
+
|
45
|
+
while team_selection.empty?
|
46
|
+
prompt.error(
|
47
|
+
'No owners were selected, please select one or more owners using the space key before pressing enter.'
|
48
|
+
)
|
49
|
+
|
50
|
+
team_selection = multi_select(prompt, question_text: question_text)
|
51
|
+
end
|
52
|
+
|
53
|
+
team_selection
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
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
|
+
Packs.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,25 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Check
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.returns(String) }
|
13
|
+
def user_facing_name
|
14
|
+
'Run bin/packwerk check'
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
18
|
+
def perform!(prompt)
|
19
|
+
system('bin/packwerk check')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
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
|
+
Packs.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,37 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
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
|
+
if team_or_pack == 'By team'
|
21
|
+
teams = TeamSelector.multi_select(prompt)
|
22
|
+
selected_packs = Packs.all.select do |p|
|
23
|
+
teams.map(&:name).include?(CodeOwnership.for_package(p)&.name)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
selected_packs = PackSelector.single_or_all_pack_multi_select(prompt, question_text: 'What pack(s) would you like info on?')
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "You've selected #{selected_packs.count} packs. Wow! Here's all the info."
|
30
|
+
|
31
|
+
Private.get_info(packs: selected_packs)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
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,25 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class LintPackageYmlTodoFiles
|
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
|
+
Private.lint_package_todo_yml_files!
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.returns(String) }
|
18
|
+
def user_facing_name
|
19
|
+
'Lint .package_todo.yml files'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class LintPackageYmlFiles
|
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
|
+
packs = PackSelector.single_or_all_pack_multi_select(prompt, question_text: 'Please select the packs you want to lint package.yml files for')
|
15
|
+
Packs.lint_package_yml_files!(packs)
|
16
|
+
end
|
17
|
+
|
18
|
+
sig { override.returns(String) }
|
19
|
+
def user_facing_name
|
20
|
+
'Lint packs/*/package.yml for one or more packs'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
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
|
+
paths_relative_to_root = FileSelector.select(prompt)
|
20
|
+
|
21
|
+
Packs.make_public!(
|
22
|
+
paths_relative_to_root: paths_relative_to_root,
|
23
|
+
per_file_processors: [Packs::RubocopPostProcessor.new, Packs::CodeOwnershipPostProcessor.new]
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
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
|
+
paths_relative_to_root = FileSelector.select(prompt)
|
16
|
+
|
17
|
+
Packs.move_to_pack!(
|
18
|
+
pack_name: pack.name,
|
19
|
+
paths_relative_to_root: paths_relative_to_root,
|
20
|
+
per_file_processors: [Packs::RubocopPostProcessor.new, Packs::CodeOwnershipPostProcessor.new]
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
sig { override.returns(String) }
|
25
|
+
def user_facing_name
|
26
|
+
'Move files'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class MoveToParent
|
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 child 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
|
+
Packs.move_to_parent!(
|
17
|
+
parent_name: parent_pack.name,
|
18
|
+
pack_name: child_pack.name,
|
19
|
+
per_file_processors: [Packs::RubocopPostProcessor.new, Packs::CodeOwnershipPostProcessor.new]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
sig { override.returns(String) }
|
24
|
+
def user_facing_name
|
25
|
+
'Move a child pack to be nested under a parent pack'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
#
|
8
|
+
# We have not yet pulled QueryPackwerk into open source, so we cannot include it in this CLI yet
|
9
|
+
#
|
10
|
+
class Query
|
11
|
+
extend T::Sig
|
12
|
+
extend T::Helpers
|
13
|
+
include Interface
|
14
|
+
|
15
|
+
sig { override.returns(String) }
|
16
|
+
def user_facing_name
|
17
|
+
'Query violations about a pack'
|
18
|
+
end
|
19
|
+
|
20
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
21
|
+
def perform!(prompt)
|
22
|
+
selection = prompt.select('For one pack or all packs?', ['One pack', 'All packs'])
|
23
|
+
if selection == 'All packs'
|
24
|
+
# Probably should just make `list_top_dependency_violations` take in an array of things
|
25
|
+
# Better yet we might just want to replace these functions with `QueryPackwerk`
|
26
|
+
selected_pack = nil
|
27
|
+
else
|
28
|
+
selected_pack = PackSelector.single_pack_select(prompt).name
|
29
|
+
end
|
30
|
+
|
31
|
+
limit = prompt.ask('Specify the limit of constants to analyze', default: 10, convert: :integer)
|
32
|
+
|
33
|
+
selection = prompt.select('Are you interested in dependency or privacy violations?', %w[Dependency Privacy], default: 'Privacy')
|
34
|
+
|
35
|
+
if selection == 'Dependency'
|
36
|
+
Packs.list_top_dependency_violations(
|
37
|
+
pack_name: selected_pack,
|
38
|
+
limit: limit
|
39
|
+
)
|
40
|
+
else
|
41
|
+
Packs.list_top_privacy_violations(
|
42
|
+
pack_name: selected_pack,
|
43
|
+
limit: limit
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Rename
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.returns(String) }
|
13
|
+
def user_facing_name
|
14
|
+
'Rename a pack'
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
18
|
+
def perform!(prompt)
|
19
|
+
prompt.warn(Private.rename_pack)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Update
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.returns(String) }
|
13
|
+
def user_facing_name
|
14
|
+
'Run bin/packwerk update'
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
18
|
+
def perform!(prompt)
|
19
|
+
system('bin/packwerk update')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Packs
|
4
|
+
module Private
|
5
|
+
module InteractiveCli
|
6
|
+
module UseCases
|
7
|
+
class Validate
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
include Interface
|
11
|
+
|
12
|
+
sig { override.returns(String) }
|
13
|
+
def user_facing_name
|
14
|
+
'Run bin/packwerk validate (detects cycles)'
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
18
|
+
def perform!(prompt)
|
19
|
+
system('bin/packwerk validate')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
require 'visualize_packs'
|
4
|
+
|
5
|
+
module Packs
|
6
|
+
module Private
|
7
|
+
module InteractiveCli
|
8
|
+
module UseCases
|
9
|
+
class Visualize
|
10
|
+
extend T::Sig
|
11
|
+
extend T::Helpers
|
12
|
+
include Interface
|
13
|
+
|
14
|
+
sig { override.params(prompt: TTY::Prompt).void }
|
15
|
+
def perform!(prompt)
|
16
|
+
teams_or_packs = prompt.select('Do you want the graph nodes to be teams or packs?', %w[Teams Packs])
|
17
|
+
|
18
|
+
if teams_or_packs == 'Teams'
|
19
|
+
teams = TeamSelector.multi_select(prompt)
|
20
|
+
VisualizePacks.team_graph!(teams)
|
21
|
+
else
|
22
|
+
by_name_or_by_owner = prompt.select('Do you select packs by name or by owner?', ['By name', 'By owner'])
|
23
|
+
if by_name_or_by_owner == 'By owner'
|
24
|
+
teams = TeamSelector.multi_select(prompt)
|
25
|
+
selected_packs = Packs.all.select do |p|
|
26
|
+
teams.map(&:name).include?(CodeOwnership.for_package(p)&.name)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
selected_packs = PackSelector.single_or_all_pack_multi_select(prompt)
|
30
|
+
end
|
31
|
+
|
32
|
+
Private.visualize(packs: selected_packs)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
sig { override.returns(String) }
|
37
|
+
def user_facing_name
|
38
|
+
'Visualize pack relationships'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
# https://github.com/piotrmurach/tty-prompt
|
4
|
+
require 'tty-prompt'
|
5
|
+
|
6
|
+
require 'packs/private/interactive_cli/team_selector'
|
7
|
+
require 'packs/private/interactive_cli/pack_selector'
|
8
|
+
require 'packs/private/interactive_cli/file_selector'
|
9
|
+
require 'packs/private/interactive_cli/use_cases/interface'
|
10
|
+
require 'packs/private/interactive_cli/use_cases/create'
|
11
|
+
require 'packs/private/interactive_cli/use_cases/move'
|
12
|
+
require 'packs/private/interactive_cli/use_cases/add_dependency'
|
13
|
+
require 'packs/private/interactive_cli/use_cases/get_info'
|
14
|
+
require 'packs/private/interactive_cli/use_cases/query'
|
15
|
+
require 'packs/private/interactive_cli/use_cases/make_public'
|
16
|
+
require 'packs/private/interactive_cli/use_cases/move_to_parent'
|
17
|
+
require 'packs/private/interactive_cli/use_cases/rename'
|
18
|
+
require 'packs/private/interactive_cli/use_cases/check'
|
19
|
+
require 'packs/private/interactive_cli/use_cases/update'
|
20
|
+
require 'packs/private/interactive_cli/use_cases/validate'
|
21
|
+
require 'packs/private/interactive_cli/use_cases/lint_package_yml_files'
|
22
|
+
require 'packs/private/interactive_cli/use_cases/visualize'
|
23
|
+
|
24
|
+
module Packs
|
25
|
+
module Private
|
26
|
+
module InteractiveCli
|
27
|
+
extend T::Sig
|
28
|
+
|
29
|
+
sig { params(prompt: T.nilable(TTY::Prompt)).void }
|
30
|
+
def self.start!(prompt: nil)
|
31
|
+
prompt ||= TTY::Prompt.new(interrupt: lambda {
|
32
|
+
puts "\n\nGoodbye! I hope you have a good day."
|
33
|
+
exit 1 })
|
34
|
+
help_text = '(Press ↑/↓ arrow to move, Enter to select and letters to filter)'
|
35
|
+
choice = prompt.select('Hello! What would you like to do?',
|
36
|
+
cycle: true,
|
37
|
+
filter: true,
|
38
|
+
help: help_text,
|
39
|
+
show_help: :always,
|
40
|
+
per_page: 15) do |menu|
|
41
|
+
menu.enum '.'
|
42
|
+
|
43
|
+
UseCases::Interface.all.each do |use_case|
|
44
|
+
menu.choice use_case.user_facing_name, use_case
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
choice.perform!(prompt)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|