1
1
require 'pp'
2
+ require 'tty-prompt'
2
3
3
4
module Chronicle
4
5
module ETL
5
6
module CLI
6
7
# CLI commands for working with ETL jobs
7
8
class Jobs < SubcommandBase
8
9
default_task "start"
9
- namespace :jobs
10
+ namespace :jobs
10
11
11
12
class_option :name , aliases : '-j' , desc : 'Job configuration name'
12
13
@@ -26,15 +27,9 @@ class Jobs < SubcommandBase
26
27
class_option :output , aliases : '-o' , desc : 'Output filename' , type : 'string'
27
28
class_option :fields , desc : 'Output only these fields' , type : 'array' , banner : 'field1 field2 ...'
28
29
29
- class_option :log_level , desc : 'Log level (debug, info, warn, error, fatal)' , default : 'info'
30
- class_option :verbose , aliases : '-v' , desc : 'Set log level to verbose' , type : :boolean
31
- class_option :silent , desc : 'Silence all output' , type : :boolean
32
-
33
30
# Thor doesn't like `run` as a command name
34
31
map run : :start
35
32
desc "run" , "Start a job"
36
- option :log_level , desc : 'Log level (debug, info, warn, error, fatal)' , default : 'info'
37
- option :verbose , aliases : '-v' , desc : 'Set log level to verbose' , type : :boolean
38
33
option :dry_run , desc : 'Only run the extraction and transform steps, not the loading' , type : :boolean
39
34
long_desc <<-LONG_DESC
40
35
This will run an ETL job. Each job needs three parts:
@@ -49,11 +44,15 @@ class Jobs < SubcommandBase
49
44
LONG_DESC
50
45
# Run an ETL job
51
46
def start
52
- setup_log_level
53
- job_definition = build_job_definition ( options )
54
- job = Chronicle ::ETL ::Job . new ( job_definition )
55
- runner = Chronicle ::ETL ::Runner . new ( job )
56
- runner . run!
47
+ run_job ( options )
48
+ rescue Chronicle ::ETL ::JobDefinitionError => e
49
+ missing_plugins = e . job_definition . errors
50
+ . select { |error | error . is_a? ( Chronicle ::ETL ::PluginLoadError ) }
51
+ . map ( &:name )
52
+ . uniq
53
+
54
+ install_missing_plugins ( missing_plugins )
55
+ run_job ( options )
57
56
end
58
57
59
58
desc "create" , "Create a job"
@@ -87,21 +86,39 @@ def list
87
86
88
87
headers = [ 'name' , 'extractor' , 'transformer' , 'loader' ] . map { |h | h . upcase . bold }
89
88
89
+ puts "Available jobs:"
90
90
table = TTY ::Table . new ( headers , job_details )
91
91
puts table . render ( indent : 0 , padding : [ 0 , 2 ] )
92
92
end
93
93
94
94
private
95
95
96
- def setup_log_level
97
- if options [ :silent ]
98
- Chronicle ::ETL ::Logger . log_level = Chronicle ::ETL ::Logger ::SILENT
99
- elsif options [ :verbose ]
100
- Chronicle ::ETL ::Logger . log_level = Chronicle ::ETL ::Logger ::DEBUG
101
- elsif options [ :log_level ]
102
- level = Chronicle ::ETL ::Logger . const_get ( options [ :log_level ] . upcase )
103
- Chronicle ::ETL ::Logger . log_level = level
96
+ def run_job ( options )
97
+ job_definition = build_job_definition ( options )
98
+ job = Chronicle ::ETL ::Job . new ( job_definition )
99
+ runner = Chronicle ::ETL ::Runner . new ( job )
100
+ runner . run!
101
+ end
102
+
103
+ # TODO: probably could merge this with something in cli/plugin
104
+ def install_missing_plugins ( missing_plugins )
105
+ prompt = TTY ::Prompt . new
106
+ message = "Plugin#{ 's' if missing_plugins . count > 1 } specified by job not installed.\n "
107
+ message += "Do you want to install "
108
+ message += missing_plugins . map { |name | "chronicle-#{ name } " . bold } . join ( ", " )
109
+ message += " and start the job?"
110
+ install = prompt . yes? ( message )
111
+ return unless install
112
+
113
+ spinner = TTY ::Spinner . new ( "[:spinner] Installing plugins..." , format : :dots_2 )
114
+ spinner . auto_spin
115
+ missing_plugins . each do |plugin |
116
+ Chronicle ::ETL ::Registry ::PluginRegistry . install ( plugin )
104
117
end
118
+ spinner . success ( "(#{ 'successful' . green } )" )
119
+ rescue Chronicle ::ETL ::PluginNotAvailableError => e
120
+ spinner . error ( "Error" . red )
121
+ Chronicle ::ETL ::Logger . fatal ( "Plugin '#{ e . name } ' could not be installed" . red )
105
122
end
106
123
107
124
# Create job definition by reading config file and then overwriting with flag options
0 commit comments