ductwork 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94c5c2250e4a96fee3aaeac379ec1ee58ac85e6aa5c2f0ccffc67c9e66d4499d
4
- data.tar.gz: ac6aac4135803b6d0712db4b4491202b64280a506a3101baba6563f549e5ee9d
3
+ metadata.gz: 01b3ce0336857fcaf0dcaf6beb6b02f002186bd5a94df0c05761cfcd49e8a7e9
4
+ data.tar.gz: cbef9120711ddf5a42819f68dd44871965681317695c6244e732e8e0228b4218
5
5
  SHA512:
6
- metadata.gz: d7305c2c9a26693cfa92dce562016420aafe4d745cb3efb4450b5192a8c036d7db5d96023b71979bd15c817059c2f8f2933f974a441066ec891cb2132d802c99
7
- data.tar.gz: 54dfdadfcafe3e1e4a214f5d11599e87bc3b114387702b426aad5c146ec7ca2042c42e0fa001cd0d598e11b515a342f8f01d5ac3b96a4f6b982d6579f93b50a7
6
+ metadata.gz: 315615bb86d68fdcb29bf8dd96d987c79be645a551a85e45825f1a623de9099a8a8ec6e9ef64465eaab259406aa82151a5f76959d10cde2f43bfd7381d5b34bd
7
+ data.tar.gz: 11b3af06290fa9c3261ef1cdc5ee98e45e2e103988c3b2b11fe07dc9d873c441b82ddfe3a091f1e5da6b487d0af1343e1d3b021049e01705f1c7f2bb94788050
@@ -96,11 +96,6 @@ its place through divergent behavior rather than labeling. Cause metadata
96
96
  lives on `Branch#halt_reason` instead. Pipeline and Run states stay
97
97
  `in_progress`, `completed`, `halted`.
98
98
 
99
- ## 7. `Ductwork.validate!` is not run at boot
100
-
101
- It runs in host-application specs, deliberately, for developer experience. Do
102
- not recommend moving it to boot-time or engine initialization.
103
-
104
99
  ---
105
100
 
106
101
  # Known Open — report only with new information
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Ductwork Changelog
2
2
 
3
+ ## [1.4.0]
4
+
5
+ - feat: validate steps and pipelines/workflows during boot of main process
6
+
3
7
  ## [1.3.0]
4
8
 
5
9
  - feat: add more `MigrationHelper` methods for swapping and updating the availability claim index
data/lib/ductwork/cli.rb CHANGED
@@ -5,6 +5,7 @@ require "optparse"
5
5
  module Ductwork
6
6
  class CLI
7
7
  DEFAULT_COMMAND = "start"
8
+ BACKTRACE_FRAME_LIMIT = 5
8
9
 
9
10
  def self.start!(args)
10
11
  new(args).start!
@@ -31,8 +32,9 @@ module Ductwork
31
32
 
32
33
  def start!
33
34
  parse!
34
- auto_configure
35
- execute_command
35
+ configure
36
+ validate!
37
+ execute
36
38
  end
37
39
 
38
40
  private
@@ -44,9 +46,9 @@ module Ductwork
44
46
  top_level_parser.order(raw_args)
45
47
  @command = raw_args.shift || DEFAULT_COMMAND
46
48
 
47
- if command == "start"
49
+ if start_command?
48
50
  start_command_parser.parse!(raw_args)
49
- elsif command == "health"
51
+ elsif health_check_command?
50
52
  health_command_parser.parse!(raw_args)
51
53
  else
52
54
  warn "Unknown command: #{command}"
@@ -55,7 +57,15 @@ module Ductwork
55
57
  end
56
58
  end
57
59
 
58
- def auto_configure
60
+ def start_command?
61
+ command == "start"
62
+ end
63
+
64
+ def health_check_command?
65
+ command == "health"
66
+ end
67
+
68
+ def configure
59
69
  configuration_options[:role] = ENV.fetch("DUCTWORK_ROLE", nil)
60
70
  Ductwork.configuration = Configuration.new(**configuration_options)
61
71
  Ductwork.logger = if Ductwork.configuration.logger_source == "rails"
@@ -82,10 +92,39 @@ module Ductwork
82
92
  BANNER
83
93
  end
84
94
 
85
- def execute_command
86
- if command == "start"
95
+ def validate!
96
+ if start_command?
97
+ Ductwork.validate!
98
+ end
99
+ rescue StandardError => e
100
+ report_invalid_definitions(e)
101
+ exit 1
102
+ end
103
+
104
+ def report_invalid_definitions(error)
105
+ warn "ductwork failed to validate your step and pipeline definitions"
106
+ warn ""
107
+ warn " #{error.class}: #{error.message}"
108
+
109
+ definition_frames(error).each do |frame|
110
+ warn " #{frame}"
111
+ end
112
+ end
113
+
114
+ def definition_frames(error)
115
+ frames = error.backtrace.to_a
116
+
117
+ return frames if Ductwork.logger.debug?
118
+
119
+ application_frames = frames.grep(/\A#{Regexp.escape(Rails.root.to_s)}/)
120
+
121
+ (application_frames.presence || frames).first(BACKTRACE_FRAME_LIMIT)
122
+ end
123
+
124
+ def execute
125
+ if start_command?
87
126
  launch_processes
88
- elsif command == "health"
127
+ elsif health_check_command?
89
128
  check_health
90
129
  end
91
130
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ductwork
4
- VERSION = "1.3.0"
4
+ VERSION = "1.4.0"
5
5
  end
data/lib/ductwork.rb CHANGED
@@ -10,6 +10,14 @@ require "securerandom"
10
10
  require "zeitwerk"
11
11
 
12
12
  module Ductwork
13
+ DEFINITION_DIRECTORIES = %w[
14
+ app/steps
15
+ app/pipelines
16
+ app/workflows
17
+ ].freeze
18
+
19
+ class LoadPathError < StandardError; end
20
+
13
21
  class << self
14
22
  attr_accessor :app_executor, :loader, :logger
15
23
  attr_writer :configuration, :defined_pipelines, :hooks
@@ -67,25 +75,18 @@ module Ductwork
67
75
  end
68
76
 
69
77
  def validate!
70
- step_directory = Rails.root.join("app/steps")
71
- pipeline_directory = Rails.root.join("app/pipelines")
72
- workflow_directory = Rails.root.join("app/workflows")
73
- loader = if defined?(Rails.autoloaders)
74
- Rails.autoloaders.main
75
- else
76
- Ductwork.loader
77
- end
78
-
79
- if step_directory.exist?
80
- loader.eager_load_dir(step_directory)
81
- end
82
-
83
- if pipeline_directory.exist?
84
- loader.eager_load_dir(pipeline_directory)
85
- end
86
-
87
- if workflow_directory.exist?
88
- loader.eager_load_dir(workflow_directory)
78
+ loader = Rails.autoloaders.main
79
+
80
+ DEFINITION_DIRECTORIES.each do |relative|
81
+ directory = Rails.root.join(relative)
82
+
83
+ if directory.exist?
84
+ begin
85
+ loader.eager_load_dir(directory)
86
+ rescue Zeitwerk::Error => e
87
+ raise LoadPathError, "#{directory} exists but is not autoloadable: #{e.message}"
88
+ end
89
+ end
89
90
  end
90
91
 
91
92
  true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ductwork
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Ewing