semaph 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +81 -11
  5. data/lib/semaph/api.rb +37 -4
  6. data/lib/semaph/commands/reload_command.rb +5 -4
  7. data/lib/semaph/commands/rerun_workflow_command.rb +18 -0
  8. data/lib/semaph/commands/stop_workflow_command.rb +18 -0
  9. data/lib/semaph/model/job.rb +43 -1
  10. data/lib/semaph/model/job_collection.rb +17 -4
  11. data/lib/semaph/model/pipeline.rb +27 -1
  12. data/lib/semaph/model/pipeline_collection.rb +0 -1
  13. data/lib/semaph/model/project.rb +1 -1
  14. data/lib/semaph/model/project_collection.rb +0 -1
  15. data/lib/semaph/model/workflow.rb +11 -1
  16. data/lib/semaph/model/workflow_collection.rb +0 -1
  17. data/lib/semaph/shells/organisation/organisation_shell.rb +13 -9
  18. data/lib/semaph/shells/organisation/projects_list_command.rb +1 -0
  19. data/lib/semaph/shells/organisations/organisations_shell.rb +5 -1
  20. data/lib/semaph/shells/pipeline/jobs_list_command.rb +3 -15
  21. data/lib/semaph/shells/pipeline/jobs_logs_command.rb +30 -0
  22. data/lib/semaph/shells/pipeline/jobs_poll_command.rb +37 -0
  23. data/lib/semaph/shells/pipeline/pipeline_shell.rb +80 -7
  24. data/lib/semaph/shells/project/project_shell.rb +31 -18
  25. data/lib/semaph/shells/project/workflows_list_command.rb +1 -0
  26. data/lib/semaph/shells/project/workflows_select_command.rb +10 -3
  27. data/lib/semaph/shells/workflow/pipelines_list_command.rb +2 -1
  28. data/lib/semaph/shells/workflow/pipelines_select_command.rb +9 -3
  29. data/lib/semaph/shells/workflow/workflow_shell.rb +44 -13
  30. data/lib/semaph/version.rb +1 -1
  31. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b22217dbedbfa234279e494e23d64af812563e6fa8d57e2e2b14f185b3fbe52c
4
- data.tar.gz: 36c3a0944ef6408730c18b2f147f734616300023792e9e82b0c5ebc0956bab05
3
+ metadata.gz: 13271774cf750f1f8eedc2d48de45ceeaa164af2593581cac85fc73e6c371d95
4
+ data.tar.gz: 3afba979f087aba88acbeeb3a09e46261fda8ba3afae3cf1690ced82d687d420
5
5
  SHA512:
6
- metadata.gz: 4fdda4999337920b39947b2c2fe09ea2cf62830998f948fed2d835dd74f5436172276dace4d59f0e493f14381aae349aaa0aafaa123b5f452ab4ed6a1fba0db0
7
- data.tar.gz: c5f969a3450d98f8a9b7a9eeb66d134856558e0376259070206ad0a8e76d4e3c38e6a12e3b27312aa272a48cc08af50288e99b443983ffc1d374d5401f82eb85
6
+ metadata.gz: a00c84f6e8e357e0a99f921e316b8a36f8c5cf78a8d9befb33f2e8e25f733801024392401b4329d8faf20a690dace3c7b2fe48a1f31bb71dfa4c25f41987156b
7
+ data.tar.gz: 8c904c17ba321fb240c4bdc1fa8ecb1beac95d6688da8632dd6e7e26446c2c16bd52bca36757eccc389cb06b64d3e1af4fc874ce817d706d632e28eaad2b56b5
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  .DS_Store
2
+ *.log
2
3
 
3
4
  /.bundle/
4
5
  /.yardoc
@@ -7,4 +8,4 @@
7
8
  /doc/
8
9
  /pkg/
9
10
  /spec/reports/
10
- /tmp/
11
+ /tmp/
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- semaph (0.1.0)
4
+ semaph (0.3.0)
5
5
  faraday
6
6
  rainbow
7
7
  shell_shock
data/README.md CHANGED
@@ -1,28 +1,98 @@
1
1
  # Semaph
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/semaph`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ This is command line shell for interacting with [semaphoreci 2.0](http://docs.semaphoreci.com/).
4
+
5
+ It complements the [sem](https://docs.semaphoreci.com/reference/sem-command-line-tool/) tool with some
6
+ overlap in responsibilities.
4
7
 
5
- TODO: Delete this and the text above, and describe your gem
6
8
 
7
9
  ## Installation
8
10
 
9
- Add this line to your application's Gemfile:
11
+ gem install semaph
12
+
13
+ ## Usage
14
+
15
+ To set up authentication to semaphoreci, you can just follow the instructions to install and setup
16
+ [sem](https://docs.semaphoreci.com/reference/sem-command-line-tool/). This will result
17
+ in your authentication details being written to `~/.sem.yaml`.
10
18
 
11
- ```ruby
12
- gem 'semaph'
19
+ You should see something like the following in this file:
20
+
21
+ ```yaml
22
+ active-context: foo_semaphoreci_com
23
+ contexts:
24
+ foo_semaphoreci_com:
25
+ auth:
26
+ token: qwerty
27
+ host: foo.semaphoreci.com
13
28
  ```
14
29
 
15
- And then execute:
30
+ Now you can run `semaph` and will be presented with a prompt like one of the following:
16
31
 
17
- $ bundle install
32
+ 🏗 >
18
33
 
19
- Or install it yourself as:
34
+ or
20
35
 
21
- $ gem install semaph
36
+ 🏗 foo.semaphoreci.com >
22
37
 
23
- ## Usage
38
+ This is the first of a series of nested shells. Each shell represents a different context
39
+ and has different commands available. To see the commands available, execute `help` and
40
+ to see the details of a particular command, execute `help <command name>`. Once you are
41
+ familar with the commands for each context, you can type the first couple of characters
42
+ and then hit tab to complete the rest. For some commands you can also tab complete the
43
+ parameters. Once you enter a shell, return to the previous shell or exit `semaph`, you can
44
+ press ctrl-d.
45
+
46
+ ### organisations shell
47
+
48
+ 🏗 >
49
+
50
+ You will only see this shell if you have multiple sets of credentials in your `~/.sem.yml` file.
51
+
52
+ From this shell, you can `list-organisations` you are authenticated to and `select-organisation`
53
+ to enter a shell for that organisation.
54
+
55
+ ### organisation shell
56
+
57
+ 🏗 foo.semaphoreci.com >
58
+
59
+ If you have only one set of credentials in `~/.sem.yml` then this will be the initial shell.
60
+
61
+ From here you can `list-projects` and then `select-project` to enter a shell for that project.
62
+
63
+ If new projects have been added/removed while you are using this shell, you can `reload-projects`.
64
+
65
+ ### project shell
66
+
67
+ 🏗 foo.semaphoreci.com my-app >
68
+
69
+ From this shell, you will mostly be interested in `list-workflows <branch>` (where 'branch' is any
70
+ substring of the git branch you want to see workflows for) and then `select-workflow <index>`
71
+ (where 'index' is the number displayed for each workflow `list-workflows` - tab completion on uuids
72
+ seemed a bad idea) to enter a shell for that specific workflow.
73
+
74
+ You can also `open-github` (opens a web browser for the github project associated with the project), `open-project`
75
+ (opens the semaphoreci project in a browser) and `reload-workflows` (to see any new/changed workflows).
76
+
77
+ ### workflow shell
78
+
79
+ 🏗 foo.semaphoreci.com my-app workflowuuid >
80
+
81
+ From this shell, you can `list-pipelines` for the selected workflow. These are the builds usually starting
82
+ from `semaphore.yml` plus any promotion pipelines that might be executed. You can `select-pipeline` to monitor
83
+ what's happening with the pipeline.
84
+
85
+ You can also `open-github-branch`, `open-github-commit` to see the branch/commit in a browser and
86
+ `open-workflow`, `open-branch` to see the semaphore branch/workflow in a browser and `reload-pipelines` to see
87
+ any changes that have happened in semaphore.
88
+
89
+ ### pipeline shell
90
+
91
+ 🏗 foo.semaphoreci.com my-app workflowuuid semaphore.yml >
92
+
93
+ From this shell, you can `list-jobs` and `reload-jobs`.
24
94
 
25
- TODO: Write usage instructions here
95
+ Jobs are displayed with a flattened view of blocks and jobs for compactness.
26
96
 
27
97
  ## Development
28
98
 
@@ -4,12 +4,14 @@ require "json"
4
4
  module Semaph
5
5
  # Refer to https://docs.semaphoreci.com/reference/api-v1alpha/
6
6
  class Api
7
- attr_reader :host
7
+ attr_reader :host, :name
8
8
 
9
9
  def initialize(token, host)
10
10
  @token = token
11
11
  @host = host
12
- @base = "https://#{host}/api/v1alpha"
12
+ @name = host.split(".").first
13
+ @host_url = "https://#{host}"
14
+ @base = "#{@host_url}/api/v1alpha"
13
15
  end
14
16
 
15
17
  def projects
@@ -20,6 +22,18 @@ module Semaph
20
22
  get "plumber-workflows", { project_id: project_id }
21
23
  end
22
24
 
25
+ def workflow(workflow_id)
26
+ get "plumber-workflows/#{workflow_id}"
27
+ end
28
+
29
+ def stop_workflow(workflow_id)
30
+ post "plumber-workflows/#{workflow_id}/terminate"
31
+ end
32
+
33
+ def rerun_workflow(workflow_id)
34
+ post "plumber-workflows/#{workflow_id}/reschedule?request_token=#{workflow_id}"
35
+ end
36
+
23
37
  def pipelines(options)
24
38
  get "pipelines", options
25
39
  end
@@ -32,13 +46,32 @@ module Semaph
32
46
  get "jobs/#{id}"
33
47
  end
34
48
 
49
+ def job_log(id)
50
+ get_raw "jobs/#{id}/plain_logs.json"
51
+ end
52
+
35
53
  private
36
54
 
55
+ def get_raw(path, params = {})
56
+ url = "#{@host_url}/#{path}"
57
+ puts url if ENV["SEMAPH_DEBUG"]
58
+ response = Faraday.get(url, params, { "Authorization" => "Token #{@token}" })
59
+ check_response(response, url)
60
+ end
61
+
37
62
  def get(path, params = {})
38
63
  url = "#{@base}/#{path}"
39
64
  puts url if ENV["SEMAPH_DEBUG"]
40
65
  response = Faraday.get(url, params, headers)
41
- check_response(response, url).tap do |hash|
66
+ JSON.parse(check_response(response, url)).tap do |hash|
67
+ pp hash if ENV["SEMAPH_DEBUG"]
68
+ end
69
+ end
70
+
71
+ def post(path, params = {})
72
+ url = "#{@base}/#{path}"
73
+ response = Faraday.post(url, params.to_json, headers)
74
+ JSON.parse(check_response(response, url)).tap do |hash|
42
75
  pp hash if ENV["SEMAPH_DEBUG"]
43
76
  end
44
77
  end
@@ -52,7 +85,7 @@ module Semaph
52
85
  end
53
86
 
54
87
  def check_response(response, url)
55
- return JSON.parse(response.body) if response.status == 200
88
+ return response.body if response.status == 200
56
89
 
57
90
  puts "http response #{response.status} received for #{url}:\n#{response.body}"
58
91
  exit 1
@@ -3,13 +3,14 @@ module Semaph
3
3
  class ReloadCommand
4
4
  attr_reader :help
5
5
 
6
- def initialize(entity, help)
7
- @entity = entity
8
- @help = help
6
+ def initialize
7
+ @help = "reload all code"
9
8
  end
10
9
 
11
10
  def execute(_whatever)
12
- @entity.reload
11
+ Dir["lib/**/*.rb"].each do |path|
12
+ load path
13
+ end
13
14
  end
14
15
  end
15
16
  end
@@ -0,0 +1,18 @@
1
+ require "semaph/shells/workflow/workflow_shell"
2
+
3
+ module Semaph
4
+ module Commands
5
+ class RerunWorkflowCommand
6
+ attr_reader :help
7
+
8
+ def initialize(workflow)
9
+ @workflow = workflow
10
+ @help = "rerun workflow"
11
+ end
12
+
13
+ def execute(_whatever)
14
+ ::Semaph::Shells::Workflow::WorkflowShell.new(@workflow.rerun).push
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require "semaph/shells/workflow/workflow_shell"
2
+
3
+ module Semaph
4
+ module Commands
5
+ class StopWorkflowCommand
6
+ attr_reader :help
7
+
8
+ def initialize(workflow)
9
+ @workflow = workflow
10
+ @help = "stop workflow"
11
+ end
12
+
13
+ def execute(_whatever)
14
+ @workflow.stop
15
+ end
16
+ end
17
+ end
18
+ end
@@ -20,6 +20,49 @@ module Semaph
20
20
  assign_from_block(raw_block)
21
21
  end
22
22
 
23
+ def log
24
+ pipeline.workflow.project.client.job_log(id)
25
+ end
26
+
27
+ def description
28
+ [
29
+ block_icon,
30
+ @block_name,
31
+ job_icon,
32
+ @name,
33
+ ].compact.join(" ")
34
+ end
35
+
36
+ # block_state can be waiting/running/done
37
+ # block_result can be passed/failed/canceled/stopped
38
+ def block_icon
39
+ return "🟠" if @block_state == "waiting"
40
+
41
+ return "🔵" if @block_state == "running"
42
+
43
+ return "⚪" if @block_result == "canceled"
44
+
45
+ return "⛔" if @block_result == "stopped"
46
+
47
+ return "🟢" if @block_result == "passed"
48
+
49
+ "🔴"
50
+ end
51
+
52
+ # status can be FINISHED/RUNNING
53
+ # result can be PASSED/FAILED/STOPPED
54
+ def job_icon
55
+ return nil unless @status
56
+
57
+ return "🔵" unless @status == "FINISHED"
58
+
59
+ return "⛔" if @result == "STOPPED"
60
+
61
+ return "🟢" if @result == "PASSED"
62
+
63
+ "🔴"
64
+ end
65
+
23
66
  private
24
67
 
25
68
  def assign_from_job(raw)
@@ -37,4 +80,3 @@ module Semaph
37
80
  end
38
81
  end
39
82
  end
40
-
@@ -7,7 +7,6 @@ module Semaph
7
7
 
8
8
  def initialize(pipeline)
9
9
  @pipeline = pipeline
10
- reload
11
10
  end
12
11
 
13
12
  def reload
@@ -16,6 +15,14 @@ module Semaph
16
15
  @all = build_jobs(project.client.pipeline(@pipeline.id))
17
16
  end
18
17
 
18
+ def incomplete
19
+ @all.reject { |job| job.status == "FINISHED" }
20
+ end
21
+
22
+ def failed
23
+ @all.select { |job| job.result == "FAILED" }
24
+ end
25
+
19
26
  private
20
27
 
21
28
  def build_jobs(content)
@@ -23,12 +30,18 @@ module Semaph
23
30
  blocks = content.delete("blocks")
24
31
  blocks.each do |block|
25
32
  jobs = block.delete("jobs").sort_by { |job| job["index"] }
26
- jobs.each do |job|
27
- result << Job.new(@pipeline, block, job)
28
- end
33
+ append_jobs(result, block, jobs)
29
34
  end
30
35
  result
31
36
  end
37
+
38
+ def append_jobs(result, block, jobs)
39
+ if jobs.count.positive?
40
+ jobs.each { |job| result << Job.new(@pipeline, block, job) }
41
+ else
42
+ result << Job.new(@pipeline, block, {})
43
+ end
44
+ end
32
45
  end
33
46
  end
34
47
  end
@@ -12,10 +12,36 @@ module Semaph
12
12
  @yaml = raw["yaml_file_name"]
13
13
  @state = raw["state"]
14
14
  @result = raw["result"]
15
+ %w[created done pending queuing running stopping].each do |name|
16
+ extract_time(name)
17
+ end
15
18
  end
16
19
 
17
20
  def job_collection
18
- JobCollection.new(self)
21
+ @job_collection ||= JobCollection.new(self)
22
+ end
23
+
24
+ def description
25
+ "#{icon} #{yaml}"
26
+ end
27
+
28
+ def icon
29
+ return "🔵" unless @state == "DONE"
30
+
31
+ return "⛔" if @result == "STOPPED"
32
+
33
+ return "🟢" if @result == "PASSED"
34
+
35
+ "🔴"
36
+ end
37
+
38
+ private
39
+
40
+ def extract_time(name)
41
+ key = "#{name}_at"
42
+ return if raw[key]["seconds"].zero?
43
+
44
+ instance_variable_set("@#{key}", Time.at(raw[key]["seconds"]))
19
45
  end
20
46
  end
21
47
  end
@@ -7,7 +7,6 @@ module Semaph
7
7
 
8
8
  def initialize(workflow)
9
9
  @workflow = workflow
10
- reload
11
10
  end
12
11
 
13
12
  def reload
@@ -27,7 +27,7 @@ module Semaph
27
27
  end
28
28
 
29
29
  def workflow_collection
30
- WorkflowCollection.new(self)
30
+ @workflow_collection ||= WorkflowCollection.new(self)
31
31
  end
32
32
  end
33
33
  end
@@ -7,7 +7,6 @@ module Semaph
7
7
 
8
8
  def initialize(client)
9
9
  @client = client
10
- reload
11
10
  end
12
11
 
13
12
  def reload
@@ -17,7 +17,17 @@ module Semaph
17
17
  end
18
18
 
19
19
  def pipeline_collection
20
- PipelineCollection.new(self)
20
+ @pipeline_collection ||= PipelineCollection.new(self)
21
+ end
22
+
23
+ def rerun
24
+ rerun_response = project.client.rerun_workflow(@id)
25
+ workflow_response = project.client.workflow(rerun_response["wf_id"])
26
+ Workflow.new(project, workflow_response["workflow"])
27
+ end
28
+
29
+ def stop
30
+ project.client.stop_workflow(@id)
21
31
  end
22
32
  end
23
33
  end
@@ -7,7 +7,6 @@ module Semaph
7
7
 
8
8
  def initialize(project)
9
9
  @project = project
10
- reload
11
10
  end
12
11
 
13
12
  def reload
@@ -12,16 +12,20 @@ module Semaph
12
12
  include ShellShock::Context
13
13
 
14
14
  def initialize(organisation)
15
- host = organisation["host"]
16
- @prompt = "🏗 #{host} > "
17
- client = ::Semaph::Api.new(organisation["auth"]["token"], host)
18
- project_collection = ::Semaph::Model::ProjectCollection.new(client)
19
- add_command ProjectsListCommand.new(project_collection), "list-projects"
15
+ @client = ::Semaph::Api.new(organisation["auth"]["token"], organisation["host"])
16
+ @prompt = "🏗 #{@client.name} > "
17
+ add_commands
18
+ @project_list_command.execute("")
19
+ end
20
+
21
+ private
22
+
23
+ def add_commands
24
+ project_collection = ::Semaph::Model::ProjectCollection.new(@client)
25
+ @project_list_command = ProjectsListCommand.new(project_collection)
26
+ add_command @project_list_command, "list-projects"
20
27
  add_command ProjectsSelectCommand.new(project_collection), "select-project"
21
- add_command(
22
- ::Semaph::Commands::ReloadCommand.new(project_collection, "reload projects"),
23
- "reload-projects",
24
- )
28
+ add_command ::Semaph::Commands::ReloadCommand.new, "reload" if ENV["SEMAPH_RELOAD"]
25
29
  end
26
30
  end
27
31
  end
@@ -10,6 +10,7 @@ module Semaph
10
10
  end
11
11
 
12
12
  def execute(_whatever)
13
+ @project_collection.reload
13
14
  @project_collection.all.each do |project|
14
15
  puts project.name
15
16
  end
@@ -1,3 +1,4 @@
1
+ require "semaph/commands/reload_command"
1
2
  require "semaph/shells/organisations/organisations_list_command"
2
3
  require "semaph/shells/organisations/organisations_select_command"
3
4
  require "shell_shock/context"
@@ -11,8 +12,11 @@ module Semaph
11
12
  def initialize(organisations)
12
13
  @organisations = organisations
13
14
  @prompt = "🏗 > "
14
- add_command OrganisationsListCommand.new(organisations), "list-organisations"
15
+ organisations_list_command = OrganisationsListCommand.new(organisations)
16
+ add_command organisations_list_command, "list-organisations"
15
17
  add_command OrganisationsSelectCommand.new(organisations), "select-organisation"
18
+ add_command ::Semaph::Commands::ReloadCommand.new, "reload" if ENV["SEMAPH_RELOAD"]
19
+ organisations_list_command.execute("")
16
20
  end
17
21
  end
18
22
  end
@@ -10,23 +10,11 @@ module Semaph
10
10
  end
11
11
 
12
12
  def execute(_whatever)
13
- @job_collection.all.each do |job|
14
- puts description(job)
13
+ @job_collection.reload
14
+ @job_collection.all.each_with_index do |job, index|
15
+ puts "#{index + 1} #{job.description}"
15
16
  end
16
17
  end
17
-
18
- private
19
-
20
- def description(job)
21
- [
22
- job.block_name,
23
- job.block_state,
24
- job.block_result,
25
- job.name,
26
- job.status,
27
- job.result,
28
- ].join(" ")
29
- end
30
18
  end
31
19
  end
32
20
  end
@@ -0,0 +1,30 @@
1
+ module Semaph
2
+ module Shells
3
+ module Pipeline
4
+ class JobsLogsCommand
5
+ attr_reader :usage, :help
6
+
7
+ def initialize(job_collection)
8
+ @job_collection = job_collection
9
+ @usage = "<job index>"
10
+ @help = "retrieve log for job"
11
+ end
12
+
13
+ def execute(index_string)
14
+ index = index_string.to_i - 1
15
+
16
+ job = @job_collection.all[index]
17
+
18
+ unless job
19
+ puts "There is no job at position #{index}"
20
+ return
21
+ end
22
+
23
+ filename = "#{job.id}.log"
24
+ File.open(filename, "w") { |file| file.puts job.log } unless File.exist?(filename)
25
+ system("less #{filename}")
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ module Semaph
2
+ module Shells
3
+ module Pipeline
4
+ class JobsPollCommand
5
+ attr_reader :usage, :help
6
+
7
+ def initialize(job_collection)
8
+ @job_collection = job_collection
9
+ @help = "poll jobs"
10
+ @can_notify = !`which terminal-notifier`.chomp.empty?
11
+ end
12
+
13
+ def execute(_whatever)
14
+ incomplete_jobs = @job_collection.incomplete
15
+ while incomplete_jobs.count.positive?
16
+ puts "#{incomplete_jobs.count} incomplete jobs remaining:"
17
+ incomplete_jobs.each { |job| puts job.description }
18
+ failed_jobs = @job_collection.failed
19
+ if failed_jobs.count.positive?
20
+ puts "Some jobs have already failed:"
21
+ failed_jobs.each { |job| puts job.description }
22
+ `terminal-notifier -group semaph -message "#{failed_jobs.count} jobs have failed" -title "Job failures"` if @can_notify
23
+ return
24
+ end
25
+ sleep 20
26
+ @job_collection.reload
27
+ incomplete_jobs = @job_collection.incomplete
28
+ end
29
+ @job_collection.all.each_with_index do |job, index|
30
+ puts "#{index + 1} #{job.description}"
31
+ end
32
+ `terminal-notifier -group semaph -message "All jobs have completed" -title "Workflow completed"` if @can_notify
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,23 +1,96 @@
1
+ require "semaph/commands/reload_command"
2
+ require "semaph/commands/rerun_workflow_command"
1
3
  require "semaph/shells/pipeline/jobs_list_command"
4
+ require "semaph/shells/pipeline/jobs_logs_command"
5
+ require "semaph/shells/pipeline/jobs_poll_command"
2
6
  require "shell_shock/context"
3
7
 
4
8
  module Semaph
5
9
  module Shells
6
10
  module Pipeline
7
11
  class PipelineShell
12
+ attr_reader :pipeline
13
+
8
14
  include ShellShock::Context
9
15
 
10
16
  def initialize(pipeline)
11
17
  @pipeline = pipeline
12
- workflow = pipeline.workflow
13
- project = workflow.project
14
- @prompt = "🏗 #{project.client.host} #{project.name} #{workflow.id} #{pipeline.yaml} > "
15
- job_collection = pipeline.job_collection
18
+ @prompt = "🏗 #{project.client.name} #{project.name} #{workflow.id} #{pipeline.yaml} > "
19
+ add_commands
20
+ @jobs_list_command.execute("")
21
+ end
22
+
23
+ private
24
+
25
+ def project
26
+ workflow.project
27
+ end
28
+
29
+ def workflow
30
+ pipeline.workflow
31
+ end
32
+
33
+ def job_collection
34
+ pipeline.job_collection
35
+ end
36
+
37
+ def add_commands
38
+ @jobs_list_command = JobsListCommand.new(job_collection)
39
+ add_command @jobs_list_command, "list-jobs"
40
+ add_command JobsPollCommand.new(job_collection), "poll-jobs"
41
+ add_command JobsLogsCommand.new(job_collection), "jobs-logs"
42
+ add_command ::Semaph::Commands::RerunWorkflowCommand.new(workflow), "rerun"
43
+ add_open_branch_command
44
+ add_open_workflow_command
45
+ add_github_commands
46
+ add_command ::Semaph::Commands::ReloadCommand.new, "reload" if ENV["SEMAPH_RELOAD"]
47
+ end
48
+
49
+ def add_open_workflow_command
50
+ add_command(
51
+ ::Semaph::Commands::VisitUrlCommand.new(
52
+ "https://#{project.client.host}/workflows/#{workflow.id}",
53
+ "browse to workflow",
54
+ ),
55
+ "open-workflow",
56
+ )
57
+ end
58
+
59
+ def add_open_branch_command
60
+ add_command(
61
+ ::Semaph::Commands::VisitUrlCommand.new(
62
+ "https://#{project.client.host}/branches/#{workflow.branch_id}",
63
+ "browse to branch in semaphore",
64
+ ),
65
+ "open-branch",
66
+ )
67
+ end
68
+
69
+ def add_github_commands
70
+ return unless workflow.project.github_url
71
+
72
+ add_github_branch
73
+ add_github_commit
74
+ end
75
+
76
+ def add_github_branch
77
+ add_command(
78
+ ::Semaph::Commands::VisitUrlCommand.new(
79
+ "#{workflow.project.github_url}/tree/#{workflow.branch}",
80
+ "browse to the branch in github",
81
+ ),
82
+ "open-github-branch",
83
+ )
84
+ end
85
+
86
+ def add_github_commit
16
87
  add_command(
17
- ::Semaph::Commands::ReloadCommand.new(job_collection, "reload jobs"),
18
- "reload-jobs",
88
+ ::Semaph::Commands::VisitUrlCommand.new(
89
+ "#{workflow.project.github_url}/commit/#{workflow.sha}",
90
+ "browse to the commit in github",
91
+ ),
92
+ "open-github-commit",
19
93
  )
20
- add_command JobsListCommand.new(job_collection), "list-jobs"
21
94
  end
22
95
  end
23
96
  end
@@ -1,5 +1,5 @@
1
- require "semaph/commands/visit_url_command"
2
1
  require "semaph/commands/reload_command"
2
+ require "semaph/commands/visit_url_command"
3
3
  require "semaph/shells/project/workflows_list_command"
4
4
  require "semaph/shells/project/workflows_select_command"
5
5
  require "shell_shock/context"
@@ -8,30 +8,33 @@ module Semaph
8
8
  module Shells
9
9
  module Project
10
10
  class ProjectShell
11
+ attr_reader :project
12
+
11
13
  include ShellShock::Context
12
14
 
13
15
  def initialize(project)
14
- @prompt = "🏗 #{project.client.host} #{project.name} > "
15
- workflow_collection = project.workflow_collection
16
- add_github_command(project)
17
- add_command(
18
- ::Semaph::Commands::ReloadCommand.new(workflow_collection, "reload workflows"),
19
- "reload-workflows",
20
- )
21
- add_command(
22
- ::Semaph::Commands::VisitUrlCommand.new(
23
- "https://#{project.client.host}/projects/#{project.name}",
24
- "browse to project",
25
- ),
26
- "open-project",
27
- )
28
- add_command WorkflowsListCommand.new(workflow_collection), "list-workflows"
29
- add_command WorkflowsSelectCommand.new(workflow_collection), "select-workflow"
16
+ @project = project
17
+ @prompt = "🏗 #{project.client.name} #{project.name} > "
18
+ add_commands
19
+ @workflows_list_command.execute("")
30
20
  end
31
21
 
32
22
  private
33
23
 
34
- def add_github_command(project)
24
+ def workflow_collection
25
+ project.workflow_collection
26
+ end
27
+
28
+ def add_commands
29
+ add_github_command
30
+ add_open_project_command
31
+ @workflows_list_command = WorkflowsListCommand.new(workflow_collection)
32
+ add_command @workflows_list_command, "list-workflows"
33
+ add_command WorkflowsSelectCommand.new(workflow_collection), "select-workflow"
34
+ add_command ::Semaph::Commands::ReloadCommand.new, "reload" if ENV["SEMAPH_RELOAD"]
35
+ end
36
+
37
+ def add_github_command
35
38
  return unless project.github_url
36
39
 
37
40
  add_command(
@@ -42,6 +45,16 @@ module Semaph
42
45
  "open-github",
43
46
  )
44
47
  end
48
+
49
+ def add_open_project_command
50
+ add_command(
51
+ ::Semaph::Commands::VisitUrlCommand.new(
52
+ "https://#{project.client.host}/projects/#{project.name}",
53
+ "browse to project",
54
+ ),
55
+ "open-project",
56
+ )
57
+ end
45
58
  end
46
59
  end
47
60
  end
@@ -13,6 +13,7 @@ module Semaph
13
13
  end
14
14
 
15
15
  def execute(branch)
16
+ @workflow_collection.reload
16
17
  @workflow_collection.all.each_with_index do |workflow, index|
17
18
  next unless workflow.branch.include?(branch)
18
19
 
@@ -1,4 +1,5 @@
1
1
  require "semaph/shells/workflow/workflow_shell"
2
+ require "semaph/shells/pipeline/pipeline_shell"
2
3
 
3
4
  module Semaph
4
5
  module Shells
@@ -14,9 +15,15 @@ module Semaph
14
15
 
15
16
  def execute(index_string)
16
17
  index = index_string.to_i - 1
17
- ::Semaph::Shells::Workflow::WorkflowShell.new(
18
- @workflow_collection.all[index],
19
- ).push
18
+
19
+ workflow = @workflow_collection.all[index]
20
+
21
+ unless workflow
22
+ puts "There is no workflow at position #{index}"
23
+ return
24
+ end
25
+
26
+ ::Semaph::Shells::Workflow::WorkflowShell.new(workflow).push
20
27
  end
21
28
  end
22
29
  end
@@ -10,8 +10,9 @@ module Semaph
10
10
  end
11
11
 
12
12
  def execute(_whatever)
13
+ @pipeline_collection.reload
13
14
  @pipeline_collection.all.each_with_index do |pipeline, index|
14
- puts "#{index + 1} #{pipeline.yaml} #{pipeline.state} #{pipeline.result}"
15
+ puts "#{index + 1} #{pipeline.description}"
15
16
  end
16
17
  end
17
18
  end
@@ -14,9 +14,15 @@ module Semaph
14
14
 
15
15
  def execute(index_string)
16
16
  index = index_string.to_i - 1
17
- ::Semaph::Shells::Pipeline::PipelineShell.new(
18
- @pipeline_collection.all[index],
19
- ).push
17
+
18
+ pipeline = @pipeline_collection.all[index]
19
+
20
+ unless pipeline
21
+ puts "There is no pipeline at position #{index}"
22
+ return
23
+ end
24
+
25
+ ::Semaph::Shells::Pipeline::PipelineShell.new(pipeline).push
20
26
  end
21
27
  end
22
28
  end
@@ -1,5 +1,7 @@
1
- require "semaph/commands/visit_url_command"
2
1
  require "semaph/commands/reload_command"
2
+ require "semaph/commands/rerun_workflow_command"
3
+ require "semaph/commands/stop_workflow_command"
4
+ require "semaph/commands/visit_url_command"
3
5
  require "semaph/shells/workflow/pipelines_list_command"
4
6
  require "semaph/shells/workflow/pipelines_select_command"
5
7
  require "shell_shock/context"
@@ -8,15 +10,40 @@ module Semaph
8
10
  module Shells
9
11
  module Workflow
10
12
  class WorkflowShell
13
+ attr_reader :workflow
14
+
11
15
  include ShellShock::Context
12
16
 
13
17
  def initialize(workflow)
14
18
  @workflow = workflow
15
- project = @workflow.project
16
- @prompt = "🏗 #{project.client.host} #{project.name} #{workflow.id} > "
17
- pipeline_collection = workflow.pipeline_collection
18
- add_command PipelinesListCommand.new(pipeline_collection), "list-pipelines"
19
+ @prompt = "🏗 #{project.client.name} #{project.name} #{workflow.id} > "
20
+ add_commands
21
+ @list_command.execute("")
22
+ end
23
+
24
+ private
25
+
26
+ def project
27
+ @workflow.project
28
+ end
29
+
30
+ def pipeline_collection
31
+ @workflow.pipeline_collection
32
+ end
33
+
34
+ def add_commands
35
+ @list_command = PipelinesListCommand.new(pipeline_collection)
36
+ add_command @list_command, "list-pipelines"
19
37
  add_command PipelinesSelectCommand.new(pipeline_collection), "select-pipeline"
38
+ add_command ::Semaph::Commands::RerunWorkflowCommand.new(workflow), "rerun"
39
+ add_command ::Semaph::Commands::StopWorkflowCommand.new(workflow), "stop"
40
+ add_open_branch_command
41
+ add_open_workflow_command
42
+ add_github_commands
43
+ add_command ::Semaph::Commands::ReloadCommand.new, "reload" if ENV["SEMAPH_RELOAD"]
44
+ end
45
+
46
+ def add_open_workflow_command
20
47
  add_command(
21
48
  ::Semaph::Commands::VisitUrlCommand.new(
22
49
  "https://#{project.client.host}/workflows/#{workflow.id}",
@@ -24,6 +51,9 @@ module Semaph
24
51
  ),
25
52
  "open-workflow",
26
53
  )
54
+ end
55
+
56
+ def add_open_branch_command
27
57
  add_command(
28
58
  ::Semaph::Commands::VisitUrlCommand.new(
29
59
  "https://#{project.client.host}/branches/#{workflow.branch_id}",
@@ -31,18 +61,16 @@ module Semaph
31
61
  ),
32
62
  "open-branch",
33
63
  )
34
- add_github_commands(workflow)
35
- add_command(
36
- ::Semaph::Commands::ReloadCommand.new(pipeline_collection, "reload pipelines"),
37
- "reload-pipelines",
38
- )
39
64
  end
40
65
 
41
- private
42
-
43
- def add_github_commands(workflow)
66
+ def add_github_commands
44
67
  return unless workflow.project.github_url
45
68
 
69
+ add_github_branch
70
+ add_github_commit
71
+ end
72
+
73
+ def add_github_branch
46
74
  add_command(
47
75
  ::Semaph::Commands::VisitUrlCommand.new(
48
76
  "#{workflow.project.github_url}/tree/#{workflow.branch}",
@@ -50,6 +78,9 @@ module Semaph
50
78
  ),
51
79
  "open-github-branch",
52
80
  )
81
+ end
82
+
83
+ def add_github_commit
53
84
  add_command(
54
85
  ::Semaph::Commands::VisitUrlCommand.new(
55
86
  "#{workflow.project.github_url}/commit/#{workflow.sha}",
@@ -1,3 +1,3 @@
1
1
  module Semaph
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semaph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Ryall
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-30 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -91,6 +91,8 @@ files:
91
91
  - lib/semaph.rb
92
92
  - lib/semaph/api.rb
93
93
  - lib/semaph/commands/reload_command.rb
94
+ - lib/semaph/commands/rerun_workflow_command.rb
95
+ - lib/semaph/commands/stop_workflow_command.rb
94
96
  - lib/semaph/commands/visit_url_command.rb
95
97
  - lib/semaph/formatting.rb
96
98
  - lib/semaph/model/job.rb
@@ -108,6 +110,8 @@ files:
108
110
  - lib/semaph/shells/organisations/organisations_select_command.rb
109
111
  - lib/semaph/shells/organisations/organisations_shell.rb
110
112
  - lib/semaph/shells/pipeline/jobs_list_command.rb
113
+ - lib/semaph/shells/pipeline/jobs_logs_command.rb
114
+ - lib/semaph/shells/pipeline/jobs_poll_command.rb
111
115
  - lib/semaph/shells/pipeline/pipeline_shell.rb
112
116
  - lib/semaph/shells/project/project_shell.rb
113
117
  - lib/semaph/shells/project/workflows_list_command.rb