monoz 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: 8690b4b3d6adc785adfa22b77c24f72fb2524aa57f337b9d58723b29d9c95e37
4
- data.tar.gz: ffce67da4773d0a25c7c0844fcbe35e5ee21b6e8aff7ada1541e5cf7fdaf6feb
3
+ metadata.gz: a4b5b401a4bf7239ed13540d493ca21b270307357e9e0c6aa4eaadacb7b0a887
4
+ data.tar.gz: 0537ac18ffe150db50875fb8c1dd7537019792d50616cef4693f4fbf9192913d
5
5
  SHA512:
6
- metadata.gz: bf09e686e3baddbe8bb618d7372044f0d862a0cbe2b2f787490d98b8d5dce1f40d0c78891c4a910c1d162c3998586d9d96e24671c49a8ea6f23b54d6a4f4fe2d
7
- data.tar.gz: 21015ca0dbdf5b9ac345043415156003c1ed02e46244b0ca6f20858a8d9b9d99d35060d6f23a4f44ca9076c2ece7f6868466b0a73bbe660336de79284340f95d
6
+ metadata.gz: d2c82d448831e9cfec6901a3dcc09b9b2531a63621849a2def1c4b50aa2f150547148ef01a454eb7f57012922da93560fd3884f497ba79a9965f227be4e78abe
7
+ data.tar.gz: a569b1c68211574c5e03beeb87a6d95b9cc7047d41c692c095f0e63168e5aec03fcc6bb3fe1f01c7ce0d6d980393148b7da327f9926df6e35655a32b73f18e59
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monoz
4
+ class ActionCommand
5
+ attr_reader :filter, :command
6
+ def initialize(filter, command)
7
+ @filter = filter
8
+ @command = command
9
+ end
10
+ end
11
+
12
+ class Action
13
+ attr_reader :name, :commands
14
+
15
+ def initialize(name, raw_commands)
16
+ @name = name
17
+ @commands = []
18
+ parse_commands(raw_commands)
19
+ end
20
+
21
+ private
22
+ def parse_commands(raw_commands)
23
+ raw_commands.each do |command|
24
+ @commands << Monoz::ActionCommand.new(command.dig("in"), command.dig("run"))
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/delegation"
4
+
5
+ module Monoz
6
+ class ActionCollection
7
+ include Enumerable
8
+ delegate_missing_to :@items
9
+
10
+ def initialize
11
+ @items = []
12
+ populate_items
13
+ end
14
+
15
+ def exist?(name)
16
+ !!find(name)
17
+ end
18
+
19
+ def find(name)
20
+ @items.select { |i| i.name == name.to_s }&.first
21
+ end
22
+
23
+ def all
24
+ @items
25
+ end
26
+
27
+ private
28
+ def populate_items
29
+ actions = Monoz.config.dig("actions")
30
+ return if actions.empty?
31
+
32
+ raise "Invalid format, actions must be a hash." unless actions.is_a?(Hash)
33
+
34
+ actions.each do |action_name, config_raw_data|
35
+ @items << Monoz::Action.new(action_name, config_raw_data)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -6,7 +6,7 @@ require "fileutils"
6
6
 
7
7
  module Monoz
8
8
  class Application < Thor
9
- class_option :tty, type: :boolean, aliases: ["--verbose", "-t"], default: false
9
+ class_option :verbose, type: :boolean, aliases: ["--tty", "-t"], default: false
10
10
  class_option :filter
11
11
 
12
12
  def initialize(*args)
@@ -49,5 +49,11 @@ module Monoz
49
49
  def version
50
50
  say "Monoz version: #{Monoz::VERSION}"
51
51
  end
52
+
53
+ # This method will be called when a command is not found
54
+ desc "[ACTION]", "Custom action"
55
+ def method_missing(action_name, *args)
56
+ Monoz::Services::ActionService.new(self).call(action_name)
57
+ end
52
58
  end
53
59
  end
@@ -11,7 +11,7 @@ module Monoz
11
11
 
12
12
  def initialize(file_path)
13
13
  @items = []
14
- project_folders = Monoz.config.dig("folders") || ["apps", "gems"]
14
+ project_folders = Monoz.folders
15
15
 
16
16
  search_paths = project_folders.map { |folder| File.join(file_path, folder) }
17
17
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "fileutils"
5
+
6
+ module Monoz
7
+ module Services
8
+ class ActionService < Monoz::Services::BaseService
9
+ def call(action)
10
+ @action = Monoz.actions.find(action)
11
+ say_invalid_action(action) if @action.nil?
12
+ Monoz.verbose = true
13
+ run_action
14
+ end
15
+
16
+ private
17
+ def run_action
18
+ say "Running Monoz action: "
19
+ say @action.name, [:bold, :blue]
20
+
21
+ @action.commands.each do |action_command|
22
+ projects = Monoz.projects.filter(action_command.filter).order(:dependants)
23
+ command = action_command.command.split(" ")
24
+ Monoz::Services::RunService.new(self).call(projects, *command)
25
+ end
26
+ end
27
+
28
+ def say_invalid_action(cmd_or_action)
29
+ say "Error: The command or action ", :red
30
+ say "#{cmd_or_action} ", [:red, :bold]
31
+ say "does not exist.", [:red]
32
+ exit(1)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -2,68 +2,26 @@
2
2
 
3
3
  require "yaml"
4
4
  require "fileutils"
5
- require "open3"
5
+ require "pty"
6
6
 
7
7
  module Monoz
8
- class Spinner
9
- include Thor::Shell
8
+ module Responses
9
+ class RunServiceResponse
10
+ attr_reader :output, :exit_code
10
11
 
11
- def initialize(message, prefix: nil)
12
- @spinner = nil
13
- @message = message
14
- @prefix = prefix
15
- end
16
-
17
- def start
18
- @spinner = main
19
- self
20
- end
21
-
22
- def success!
23
- @spinner.kill
24
- say_formatted(" \u2713 ", [:bold, :green])
25
- say() # line break
26
- end
27
-
28
- def error!
29
- @spinner.kill
30
- say_formatted(" \u2717 ", [:bold, :red])
31
- say() # line break
32
- end
33
-
34
- private
35
- def reset
36
- say("\r", nil, false)
12
+ def initialize(output, exit_code)
13
+ @output = output
14
+ @exit_code = exit_code
37
15
  end
38
16
 
39
- def say_formatted(suffix, suffix_formatting = nil)
40
- if @prefix != nil
41
- say "\r[#{@prefix}] ", [:blue, :bold], nil
42
- say @message, nil, false
43
- say suffix, suffix_formatting, false
44
- else
45
- say "\r#{@message}", nil, false
46
- say suffix, suffix_formatting, false
47
- end
17
+ def success?
18
+ exit_code == 0
48
19
  end
49
20
 
50
- def main
51
- spinner_count = 0
52
-
53
- Thread.new do
54
- loop do
55
- dots = case spinner_count % 3
56
- when 0 then "."
57
- when 1 then ".."
58
- when 2 then "..."
59
- end
60
-
61
- say_formatted(dots)
62
- spinner_count += 1
63
- sleep(0.5)
64
- end
65
- end
21
+ def failed?
22
+ !!success?
66
23
  end
24
+ end
67
25
  end
68
26
 
69
27
  module Services
@@ -71,27 +29,17 @@ module Monoz
71
29
  attr_reader :errors, :warnings
72
30
 
73
31
  def initialize(thor_instance)
32
+ super(thor_instance)
74
33
  @projects = nil
75
34
  @errors = []
76
35
  @warnings = []
77
- super(thor_instance)
78
- end
79
-
80
- def success?
81
- !errors? && !warnings?
82
- end
83
-
84
- def errors?
85
- @errors.any?
86
- end
87
-
88
- def warnings?
89
- @warnings.any?
36
+ @command = []
90
37
  end
91
38
 
92
39
  def call(projects, *command)
93
- raise ArgumentError.new("Missing command") if command.empty?
40
+ raise ArgumentError, "Missing command" if command.empty?
94
41
 
42
+ @command = command
95
43
  if projects.is_a?(Monoz::ProjectCollection)
96
44
  @projects = projects.all
97
45
  elsif projects.is_a?(Monoz::Project)
@@ -100,37 +48,16 @@ module Monoz
100
48
  raise "Invalid projects"
101
49
  end
102
50
 
103
- @projects.each do |project|
104
- # say "#{project.name}: ", [:bold, :blue]
105
- # Monoz.tty? ? say(command.join(" ")) : say("#{command.join(" ")} ")
106
-
107
- if Monoz.tty?
108
- say "[#{project.name}] ", [:blue, :bold], nil
109
- say command.join(" ")
110
- else
111
- spinner = Monoz::Spinner.new(command.join(" "), prefix: project.name).start
112
- end
113
-
114
- response = run_commands_in_project(project, *command)
115
-
116
- if response.success?
117
- spinner.success! unless Monoz.tty?
118
- else
119
- spinner.error! unless Monoz.tty?
120
- say response.output
121
- say "" # line break
122
- @errors << {
123
- project: project.name,
124
- command: command.join(" "),
125
- exit_code: response.exit_code,
126
- output: response.output
127
- }
128
- end
129
- end
51
+ say "Running ", nil, false
52
+ say command.join(" "), [:bold], false
53
+ say " in #{@projects.map { |p| p.name }.join(", ")}:"
130
54
 
55
+ say ""
56
+ run_commands
131
57
  say ""
132
58
 
133
59
  if errors?
60
+ say ""
134
61
  say "Error: The command ", :red
135
62
  say "#{command.join(" ")} ", [:red, :bold]
136
63
  say "failed to run in one or more project directories", [:red]
@@ -138,32 +65,74 @@ module Monoz
138
65
  end
139
66
  end
140
67
 
68
+ def success?
69
+ !errors? && !warnings?
70
+ end
71
+
72
+ def errors?
73
+ @errors.any?
74
+ end
75
+
76
+ def warnings?
77
+ @warnings.any?
78
+ end
79
+
141
80
  private
142
- def run_commands_in_project(project, *command)
143
- raise ArgumentError.new("Invalid command") if command.empty?
81
+ def run_commands
82
+ @projects.each do |project|
83
+ if spinner?
84
+ spinner = Monoz::Spinner.new(@command.join(" "), prefix: project.name).start
85
+ else
86
+ say "[#{project.name}] ", [:blue, :bold], nil
87
+ say @command.join(" ")
88
+ end
89
+
90
+ response = run_in_project(project, *@command)
91
+
92
+ if response.success?
93
+ spinner&.success! if spinner?
94
+ else
95
+ spinner&.error! if spinner?
96
+ say response.output
97
+ say "" # line break
98
+ @errors << {
99
+ project: project.name,
100
+ command: @command.join(" "),
101
+ exit_code: response.exit_code,
102
+ output: response.output
103
+ }
104
+ end
105
+ end
106
+ end
107
+
108
+ def spinner?
109
+ !Monoz.verbose?
110
+ end
111
+
112
+ def run_in_project(project, *command)
113
+ raise ArgumentError, "Invalid command" if command.empty?
144
114
 
145
115
  output = ""
146
116
  exit_status = nil
147
117
 
148
118
  FileUtils.chdir(project.root_path) do
149
- if Monoz.tty?
150
- Open3.popen2e(*command.map { |arg| Shellwords.escape(arg) }) do |stdin, stdout_err, wait_thr|
151
- while line = stdout_err.gets
119
+ PTY.spawn(*command.map { |arg| Shellwords.escape(arg) }) do |stdout, stdin, pid|
120
+ begin
121
+ stdout.each do |line|
152
122
  output += line
153
- print line
123
+ print line if Monoz.verbose?
154
124
  end
155
-
156
- exit_status = wait_thr.value.exitstatus
125
+ rescue Errno::EIO
157
126
  end
158
127
 
159
- say ""
160
- else
161
- output, status = Open3.capture2e(*command.map { |arg| Shellwords.escape(arg) })
162
- exit_status = status.exitstatus
128
+ Process.wait(pid)
129
+ exit_status = $?.exitstatus
163
130
  end
164
131
  end
165
132
 
166
- return Monoz::Responses::CaptureRunResponse.new(output, exit_status)
133
+ Monoz::Responses::RunServiceResponse.new(output, exit_status)
134
+ rescue Errno::ENOENT => e
135
+ Monoz::Responses::RunServiceResponse.new(e.message, 1)
167
136
  end
168
137
  end
169
138
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monoz
4
+ class Spinner
5
+ include Thor::Shell
6
+
7
+ def initialize(message, prefix: nil)
8
+ @spinner = nil
9
+ @message = message
10
+ @prefix = prefix
11
+ end
12
+
13
+ def start
14
+ @spinner = main
15
+ self
16
+ end
17
+
18
+ def success!
19
+ @spinner.kill
20
+ say_formatted(" \u2713 ", [:bold, :green])
21
+ say() # line break
22
+ end
23
+
24
+ def error!
25
+ @spinner.kill
26
+ say_formatted(" \u2717 ", [:bold, :red])
27
+ say() # line break
28
+ end
29
+
30
+ private
31
+ def reset
32
+ say("\r", nil, false)
33
+ end
34
+
35
+ def say_formatted(suffix, suffix_formatting = nil)
36
+ if @prefix != nil
37
+ say "\r[#{@prefix}] ", [:blue, :bold], nil
38
+ say @message, nil, false
39
+ say suffix, suffix_formatting, false
40
+ else
41
+ say "\r#{@message}", nil, false
42
+ say suffix, suffix_formatting, false
43
+ end
44
+ end
45
+
46
+ def main
47
+ spinner_count = 0
48
+
49
+ Thread.new do
50
+ loop do
51
+ dots = case spinner_count % 3
52
+ when 0 then "."
53
+ when 1 then ".."
54
+ when 2 then "..."
55
+ end
56
+
57
+ say_formatted(dots)
58
+ spinner_count += 1
59
+ sleep(0.5)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
data/lib/monoz/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Monoz
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/monoz.rb CHANGED
@@ -11,35 +11,20 @@ module Monoz
11
11
  class ConfigurationNotFound < StandardError; end
12
12
  end
13
13
 
14
- module Responses
15
- class CaptureRunResponse
16
- attr_reader :output, :exit_code
17
-
18
- def initialize(output, exit_code)
19
- @output = output
20
- @exit_code = exit_code
21
- end
22
-
23
- def success?
24
- exit_code == 0
25
- end
26
-
27
- def error?
28
- exit_code == 1
29
- end
30
- end
31
- end
32
-
33
14
  module Services
15
+ autoload "ActionService", "monoz/services/action_service"
34
16
  autoload "BaseService", "monoz/services/base_service"
35
17
  autoload "InitService", "monoz/services/init_service"
36
18
  autoload "RunService", "monoz/services/run_service"
37
19
  end
38
20
 
21
+ autoload "Action", "monoz/action"
22
+ autoload "ActionCollection", "monoz/action_collection"
39
23
  autoload "Application", "monoz/application"
40
24
  autoload "Configuration", "monoz/configuration"
41
25
  autoload "Project", "monoz/project"
42
26
  autoload "ProjectCollection", "monoz/project_collection"
27
+ autoload "Spinner", "monoz/spinner"
43
28
 
44
29
  class << self
45
30
  def app
@@ -54,12 +39,24 @@ module Monoz
54
39
  @config ||= Monoz::Configuration.new(pwd)
55
40
  end
56
41
 
42
+ def actions
43
+ @actions ||= Monoz::ActionCollection.new
44
+ end
45
+
57
46
  def options
58
47
  @app&.options
59
48
  end
60
49
 
61
- def tty?
62
- Monoz.options.dig("tty") == true
50
+ def folders
51
+ config.dig("folders") || ["apps", "gems"]
52
+ end
53
+
54
+ def verbose?
55
+ @verbose ||= Monoz.options.dig("verbose") == true
56
+ end
57
+
58
+ def verbose=(value)
59
+ @verbose = value
63
60
  end
64
61
 
65
62
  def projects
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monoz
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
  - kjellberg
@@ -64,13 +64,17 @@ files:
64
64
  - README.md
65
65
  - bin/monoz
66
66
  - lib/monoz.rb
67
+ - lib/monoz/action.rb
68
+ - lib/monoz/action_collection.rb
67
69
  - lib/monoz/application.rb
68
70
  - lib/monoz/configuration.rb
69
71
  - lib/monoz/project.rb
70
72
  - lib/monoz/project_collection.rb
73
+ - lib/monoz/services/action_service.rb
71
74
  - lib/monoz/services/base_service.rb
72
75
  - lib/monoz/services/init_service.rb
73
76
  - lib/monoz/services/run_service.rb
77
+ - lib/monoz/spinner.rb
74
78
  - lib/monoz/version.rb
75
79
  homepage: https://github.com/kjellberg/monoz
76
80
  licenses:
@@ -94,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
98
  - !ruby/object:Gem::Version
95
99
  version: '0'
96
100
  requirements: []
97
- rubygems_version: 3.4.5
101
+ rubygems_version: 3.4.10
98
102
  signing_key:
99
103
  specification_version: 4
100
104
  summary: Command line tool for managing ruby monorepos.