pipely 0.3.0 → 0.4.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
  SHA1:
3
- metadata.gz: 41fc3328b9562c634d8431f24de10627f682e827
4
- data.tar.gz: 7bdc7a4693e34194baa787be589e1ca4e28d561d
3
+ metadata.gz: 9b9b109c0262cd83b9db819b8464e1ed39a6bef6
4
+ data.tar.gz: 633b3e1c8bb00323199629919714dec0cce1523f
5
5
  SHA512:
6
- metadata.gz: c6bb2fb0e3872e128241b0760ef95ddc97a5c7baf534439eae8dcfaa76d7d115196bb1254e98723125dbadf5c5aba485c7d65ce183bb1e593149d2a2a23c7bca
7
- data.tar.gz: 13495dbb6503f46cac2cd52682f9b3245e38970641e69081d59e13922f37987d3ac169253cf9fc68601564883bbee68523cfb0d4677386ef15720f88e7c8feb0
6
+ metadata.gz: 9576d0aeb1273ebf96021d60cd1f6fb98f9f800cdae3bcd14a1ea6ca5919864ba3896ff99668c340ef0f25b15fe1280997ca7f997ccabe78ddbb4709762c216a
7
+ data.tar.gz: ef09a07d9ecdb00ea13633455b88f262336756e3e8d51889dd989be384b0ce01192ccbc7c9d474b21d436a2a055c67c1d134bf9ed83786af47add4571b5a2a12
data/bin/pipely CHANGED
@@ -1,40 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'pipely'
4
- require 'optparse'
5
4
 
6
- pipeline_id = input_path = output_path = nil
7
- verbose = automatic_open = false
5
+ options = Pipely::Options.parse
8
6
 
9
- OptionParser.new do |opts|
10
- opts.banner = "Usage: pipely [options]"
7
+ if options.pipeline_id
8
+ Pipely::Actions::GraphLivePipeline.new(options).execute
11
9
 
12
- opts.on("-p", "--pipeline-id PIPELINE_ID",
13
- "ID of a live pipeline to visualize with live execution statuses") do |id|
14
- pipeline_id = id
15
- end
10
+ elsif options.input_path
11
+ Pipely::Actions::GraphFilePipeline.new(options).execute
16
12
 
17
- opts.on("-i", "--input PATH",
18
- "Path to a JSON pipeline definition file to visualize") do |input|
19
- input_path = input
20
- end
13
+ else
14
+ Pipely::Actions::ListLivePipelines.new(options).execute
21
15
 
22
- opts.on("-o", "--output PATH",
23
- "Path to write PNG file(s) of graph visualization(s)") do |output|
24
- output_path = output
25
- end
26
- end.parse!
27
-
28
- if pipeline_id
29
- live_pipeline = Pipely::LivePipeline.new(pipeline_id)
30
- live_pipeline.print_runs_report
31
- live_pipeline.render_graphs
32
-
33
- elsif input_path
34
- definition_json = File.open(input_path).read
35
- output_base = File.basename(input_path,".*") + '.png'
36
- output_file = output_path ? File.join(output_path, output_base) : output_base
37
-
38
- puts "Generating #{output_file}"
39
- Pipely.draw(definition_json, output_file)
40
16
  end
data/lib/pipely.rb CHANGED
@@ -1,6 +1,9 @@
1
+ require 'pipely/options'
2
+ require 'pipely/actions'
1
3
  require 'pipely/definition'
2
4
  require 'pipely/graph_builder'
3
5
  require 'pipely/live_pipeline'
6
+ require 'pipely/s3_writer'
4
7
 
5
8
  # The top-level module for this gem. It provides the recommended public
6
9
  # interface for using Pipely to visualize and manipulate your Data Pipeline
@@ -18,7 +21,14 @@ module Pipely
18
21
  graph_builder = GraphBuilder.new
19
22
 
20
23
  graph = graph_builder.build(definition.components_for_graph)
21
- graph.output( :png => filename )
24
+
25
+ if filename.start_with?('s3://')
26
+ content = graph.output( :png => String )
27
+ S3Writer.new(filename).write(content)
28
+ else
29
+ graph.output( :png => filename )
30
+ filename
31
+ end
22
32
  end
23
33
 
24
34
  end
@@ -0,0 +1,8 @@
1
+ require 'pipely/actions/graph_live_pipeline'
2
+ require 'pipely/actions/graph_file_pipeline'
3
+ require 'pipely/actions/list_live_pipelines'
4
+
5
+ module Pipely
6
+ module Actions
7
+ end
8
+ end
@@ -0,0 +1,39 @@
1
+ module Pipely
2
+ module Actions
3
+
4
+ # Graph a pipeline definition from a file.
5
+ #
6
+ class GraphFilePipeline
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def execute
13
+ puts "Generating #{output_file}"
14
+ Pipely.draw(definition_json, output_file)
15
+ end
16
+
17
+ private
18
+
19
+ def definition_json
20
+ File.open(@options.input_path).read
21
+ end
22
+
23
+ def output_base
24
+ @output_base ||= File.basename(@options.input_path,".*") + '.png'
25
+ end
26
+
27
+ def output_file
28
+ @output_file ||= if @options.output_path
29
+ File.join(@options.output_path, output_base)
30
+ else
31
+ output_base
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
39
+
@@ -0,0 +1,34 @@
1
+ module Pipely
2
+ module Actions
3
+
4
+ # Graph a deployed pipeline with live execution statuses.
5
+ #
6
+ class GraphLivePipeline
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def execute
13
+ live_pipeline = Pipely::LivePipeline.new(@options.pipeline_id)
14
+ live_pipeline.print_runs_report
15
+
16
+ outfile = if @options.latest_run
17
+ live_pipeline.render_latest_graph(@options.output_path)
18
+ else
19
+ live_pipeline.render_graphs(@options.output_path)
20
+ end
21
+
22
+ if @options.json_output
23
+ $stdout.puts({ :graph => outfile }.to_json)
24
+ elsif $stdout.tty?
25
+ $stdout.puts "Generated #{outfile}"
26
+ else
27
+ $stdout.puts outfile
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ module Pipely
2
+ module Actions
3
+
4
+ # List currently deployed pipelines
5
+ #
6
+ class ListLivePipelines
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def execute
13
+ if @options.json_output
14
+ $stdout.puts pipeline_ids.to_json
15
+ else
16
+ $stdout.puts pipeline_ids.map { |pipeline|
17
+ [ pipeline['name'], pipeline['id'] ].join("\t")
18
+ }
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def pipeline_ids
25
+ ids = []
26
+
27
+ begin
28
+ result = Fog::AWS[:data_pipeline].list_pipelines
29
+ ids += result['pipelineIdList']
30
+ end while (result['hasMoreResults'] && result['marker'])
31
+
32
+ ids
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
@@ -33,13 +33,9 @@ module Pipely
33
33
  end
34
34
 
35
35
  def task_states_by_scheduled_start
36
- c = Fog::AWS[:data_pipeline]
37
- instances = c.query_objects(pipeline_id, 'INSTANCE')
38
- instance_details = c.describe_objects(pipeline_id, instances['ids'])
39
-
40
36
  task_states_by_scheduled_start = {}
41
37
 
42
- instance_details['pipelineObjects'].each do |pipeline_object|
38
+ all_instances.each do |pipeline_object|
43
39
  component_id = status = scheduled_start = nil
44
40
 
45
41
  pipeline_object['fields'].each do |field|
@@ -62,5 +58,32 @@ module Pipely
62
58
  task_states_by_scheduled_start
63
59
  end
64
60
 
61
+ private
62
+
63
+ def all_instances
64
+ c = Fog::AWS[:data_pipeline]
65
+
66
+ result = {}
67
+ pipeline_objects = []
68
+
69
+ begin
70
+ if result['marker']
71
+ marker = JSON.parse(result['marker'])['primary']
72
+ end
73
+
74
+ result = c.query_objects(
75
+ pipeline_id,
76
+ 'INSTANCE',
77
+ marker: result['marker']
78
+ )
79
+
80
+ instance_details = c.describe_objects(pipeline_id, result['ids'])
81
+ pipeline_objects += instance_details['pipelineObjects']
82
+
83
+ end while (result['hasMoreResults'] && result['marker'])
84
+
85
+ pipeline_objects
86
+ end
87
+
65
88
  end
66
89
  end
@@ -26,22 +26,28 @@ module Pipely
26
26
  RunsReport.new(@task_states_by_scheduled_start).print
27
27
  end
28
28
 
29
- def render_graphs
30
- @task_states_by_scheduled_start.each do |start, task_states|
31
- utc_time = Time.now.to_i
32
- formatted_start = start.gsub(/[:-]/, '').sub('T', '-')
29
+ def render_latest_graph(output_path=nil)
30
+ latest_start = @task_states_by_scheduled_start.keys.max
31
+ task_states = @task_states_by_scheduled_start[latest_start]
32
+ render_graph(latest_start, task_states, output_path)
33
+ end
33
34
 
34
- filename = "graphs/#{@pipeline_id}-#{formatted_start}-#{utc_time}.png"
35
+ def render_graphs(output_path=nil)
36
+ @task_states_by_scheduled_start.map do |start, task_states|
37
+ render_graph(start, task_states, output_path)
38
+ end
39
+ end
35
40
 
36
- if $stdout.tty?
37
- $stdout.puts "Generating #{filename}"
38
- else
39
- $stdout.puts filename
40
- end
41
+ private
41
42
 
42
- Pipely.draw(@definition_json, filename, task_states)
43
- end
43
+ def render_graph(start, task_states, output_path)
44
+ utc_time = Time.now.to_i
45
+ formatted_start = start.gsub(/[:-]/, '').sub('T', '-')
46
+
47
+ output_base = "#{@pipeline_id}-#{formatted_start}-#{utc_time}.png"
48
+ filename = File.join((output_path || 'graphs'), output_base)
44
49
 
50
+ Pipely.draw(@definition_json, filename, task_states)
45
51
  end
46
52
 
47
53
  end
@@ -0,0 +1,47 @@
1
+ require 'optparse'
2
+
3
+ module Pipely
4
+
5
+ # Options for running the CLI
6
+ #
7
+ class Options
8
+
9
+ attr_accessor :pipeline_id, :input_path, :output_path,
10
+ :verbose, :automatic_open, :json_output, :latest_run
11
+
12
+ def self.parse
13
+ options = Pipely::Options.new
14
+
15
+ OptionParser.new do |opts|
16
+ opts.banner = "Usage: pipely [options]"
17
+
18
+ opts.on("-p", "--pipeline-id PIPELINE_ID",
19
+ "ID of a live pipeline to visualize with live statuses") do |id|
20
+ options.pipeline_id = id
21
+ end
22
+
23
+ opts.on("-l", "--latest", "Graph only the latest run") do |latest|
24
+ options.latest_run = latest
25
+ end
26
+
27
+ opts.on("-i", "--input PATH",
28
+ "Path to a JSON pipeline definition file to visualize") do |input|
29
+ options.input_path = input
30
+ end
31
+
32
+ opts.on("-o", "--output PATH",
33
+ "Local or S3 path to write Graphviz PNG file(s)") do |output|
34
+ options.output_path = output
35
+ end
36
+
37
+ opts.on("-j", "--json", "Write STDOUT formatted as JSON") do |json|
38
+ options.json_output = json
39
+ end
40
+ end.parse!
41
+
42
+ options
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,33 @@
1
+ require 'fog/storage'
2
+
3
+ module Pipely
4
+
5
+ # Writes content from a String to an S3 path
6
+ #
7
+ class S3Writer
8
+
9
+ def initialize(s3_path)
10
+ uri = URI.parse(s3_path)
11
+ @host, @path = uri.host, uri.path.gsub(/^\//,'')
12
+ end
13
+
14
+ def directory
15
+ storage = Fog::Storage.new({ provider: 'AWS' })
16
+ directory = storage.directories.detect{ |d| d.key == @host }
17
+
18
+ directory or raise("Couldn't find S3 bucket '#{@host}'")
19
+ end
20
+
21
+ def write(content)
22
+ remote_file = directory.files.create({
23
+ :key => @path,
24
+ :body => content,
25
+ :public => true,
26
+ })
27
+
28
+ remote_file.public_url
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Pipely
2
- VERSION = "0.3.0" unless defined?(::DataPipelineGraphviz::VERSION)
2
+ VERSION = "0.4.0" unless defined?(::DataPipelineGraphviz::VERSION)
3
3
  end
@@ -2,7 +2,7 @@ require 'pipely'
2
2
 
3
3
  describe Pipely do
4
4
  let(:definition_json) { stub }
5
- let(:filename) { stub }
5
+ let(:filename) { 'path/to/graph.png' }
6
6
  let(:definition) { stub }
7
7
 
8
8
  before do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipely
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Gillooly
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-12 00:00:00.000000000 Z
11
+ date: 2014-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-graphviz
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 1.20.0
61
+ version: 1.21.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: 1.20.0
68
+ version: 1.21.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: unf
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -158,6 +158,10 @@ executables:
158
158
  extensions: []
159
159
  extra_rdoc_files: []
160
160
  files:
161
+ - lib/pipely/actions/graph_file_pipeline.rb
162
+ - lib/pipely/actions/graph_live_pipeline.rb
163
+ - lib/pipely/actions/list_live_pipelines.rb
164
+ - lib/pipely/actions.rb
161
165
  - lib/pipely/build/daily_scheduler.rb
162
166
  - lib/pipely/build/definition.rb
163
167
  - lib/pipely/build/environment_config.rb
@@ -174,8 +178,10 @@ files:
174
178
  - lib/pipely/fog_client.rb
175
179
  - lib/pipely/graph_builder.rb
176
180
  - lib/pipely/live_pipeline.rb
181
+ - lib/pipely/options.rb
177
182
  - lib/pipely/reference_list.rb
178
183
  - lib/pipely/runs_report.rb
184
+ - lib/pipely/s3_writer.rb
179
185
  - lib/pipely/shared_examples.rb
180
186
  - lib/pipely/tasks/definition.rb
181
187
  - lib/pipely/tasks/deploy.rb