From 4d684c11f086830053e5c12c00b7b4e21637c4c0 Mon Sep 17 00:00:00 2001 From: Wassim DHIF Date: Tue, 16 May 2017 14:53:20 +0200 Subject: [PATCH] rubocop configuration added, jobs tracking run with follow, helper class added --- .rubocop.yml | 40 +++++ Gemfile | 2 +- Gemfile.lock | 14 ++ Rakefile | 6 +- bin/gitlabci-cli | 4 +- gitlabci-cli.gemspec | 43 +++--- lib/gitlabci/controller.rb | 5 +- lib/gitlabci/controller/cli.rb | 19 ++- lib/gitlabci/controller/helper.rb | 74 ++++++++++ lib/gitlabci/controller/pipeline.rb | 159 ++++++++------------ lib/gitlabci/controller/trigger.rb | 219 +++++++++++----------------- lib/gitlabci/controller/version.rb | 3 +- spec/gitlabci/pipeline_spec.rb | 75 +++++----- spec/gitlabci/trigger_spec.rb | 93 ++++++------ spec/spec_helper.rb | 13 +- 15 files changed, 416 insertions(+), 353 deletions(-) create mode 100644 .rubocop.yml create mode 100644 lib/gitlabci/controller/helper.rb diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..b61a1f9 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,40 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2017-05-16 13:17:04 +0200 using RuboCop version 0.48.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 12 +Metrics/AbcSize: + Max: 50 + +# Offense count: 6 +# Configuration parameters: CountComments, ExcludedMethods. +Metrics/BlockLength: + Max: 200 + +# Offense count: 2 +# Configuration parameters: CountComments. +Metrics/ClassLength: + Max: 200 + +# Offense count: 2 +Metrics/CyclomaticComplexity: + Max: 10 + +# Offense count: 38 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https +Metrics/LineLength: + Max: 160 + +# Offense count: 13 +# Configuration parameters: CountComments. +Metrics/MethodLength: + Max: 50 + +# Offense count: 1 +Metrics/PerceivedComplexity: + Max: 10 diff --git a/Gemfile b/Gemfile index 0fe92fe..5362b14 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source "https://rubygems.org" +source 'https://rubygems.org' # Specify your gem's dependencies in gitlabci-controller.gemspec gemspec diff --git a/Gemfile.lock b/Gemfile.lock index ad25558..017aea4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,6 +13,7 @@ GEM specs: addressable (2.5.1) public_suffix (~> 2.0, >= 2.0.2) + ast (2.3.0) crack (0.4.3) safe_yaml (~> 1.0.0) diff-lcs (1.3) @@ -27,7 +28,12 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) netrc (0.11.0) + parser (2.4.0.0) + ast (~> 2.2) + powerpack (0.1.1) public_suffix (2.0.5) + rainbow (2.2.2) + rake rake (10.5.0) rest-client (2.0.2) http-cookie (>= 1.0.2, < 2.0) @@ -46,6 +52,13 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.8.1) safe_yaml (1.0.4) terminal-table (1.7.3) unicode-display_width (~> 1.1.1) @@ -68,4 +81,5 @@ DEPENDENCIES rake (~> 10.0) rspec (~> 3.0) rspec-mocks + rubocop webmock diff --git a/Rakefile b/Rakefile index b7e9ed5..4c774a2 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,6 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -task :default => :spec +task default: :spec diff --git a/bin/gitlabci-cli b/bin/gitlabci-cli index 2eb7280..6b7a50d 100644 --- a/bin/gitlabci-cli +++ b/bin/gitlabci-cli @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -require "gitlabci/controller" +require 'gitlabci/controller' -Gitlabci::Controller::Cli.start ( ARGV ) +Gitlabci::Controller::Cli.start ARGV diff --git a/gitlabci-cli.gemspec b/gitlabci-cli.gemspec index 2a098fb..71aa85a 100644 --- a/gitlabci-cli.gemspec +++ b/gitlabci-cli.gemspec @@ -1,32 +1,33 @@ # coding: utf-8 -lib = File.expand_path("../lib", __FILE__) + +lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require "gitlabci/controller/version" +require 'gitlabci/controller/version' Gem::Specification.new do |spec| - spec.name = "gitlabci-cli" + spec.name = 'gitlabci-cli' spec.version = Gitlabci::Controller::VERSION - spec.authors = ["Wassim DHIF"] - spec.email = ["wassimdhif@gmail.com"] + spec.authors = ['Wassim DHIF'] + spec.email = ['wassimdhif@gmail.com'] - spec.summary = %q{Control your GitlabCI workflow from your terminal} - spec.description = %q{Control your GitlabCI workflow from your terminal} - spec.homepage = "http://github.com/wdhif/gitlabci-cli" + spec.summary = 'Control your GitlabCI workflow from your terminal' + spec.description = 'Control your GitlabCI workflow from your terminal' + spec.homepage = 'http://github.com/wdhif/gitlabci-cli' spec.files = [] - spec.executables = "gitlabci-cli" - spec.require_paths = ["lib"] - - spec.add_dependency "thor" - spec.add_dependency "rest-client" - spec.add_dependency "json" - spec.add_dependency "json_pure" - spec.add_dependency "terminal-table" + spec.executables = 'gitlabci-cli' + spec.require_paths = ['lib'] - spec.add_development_dependency "bundler" - spec.add_development_dependency "rake", "~> 10.0" - spec.add_development_dependency "rspec", "~> 3.0" - spec.add_development_dependency "rspec-mocks" - spec.add_development_dependency "webmock" + spec.add_dependency 'thor' + spec.add_dependency 'rest-client' + spec.add_dependency 'json' + spec.add_dependency 'json_pure' + spec.add_dependency 'terminal-table' + spec.add_development_dependency 'bundler' + spec.add_development_dependency 'rake', '~> 10.0' + spec.add_development_dependency 'rspec', '~> 3.0' + spec.add_development_dependency 'rspec-mocks' + spec.add_development_dependency 'webmock' + spec.add_development_dependency 'rubocop' end diff --git a/lib/gitlabci/controller.rb b/lib/gitlabci/controller.rb index d21b748..292fa5e 100644 --- a/lib/gitlabci/controller.rb +++ b/lib/gitlabci/controller.rb @@ -1,7 +1,8 @@ -require "gitlabci/controller/version" -require "gitlabci/controller/cli" +require 'gitlabci/controller/cli' +require 'gitlabci/controller/version' module Gitlabci + # Main Controller Class module Controller end end diff --git a/lib/gitlabci/controller/cli.rb b/lib/gitlabci/controller/cli.rb index 2a61402..1cdba70 100644 --- a/lib/gitlabci/controller/cli.rb +++ b/lib/gitlabci/controller/cli.rb @@ -1,15 +1,20 @@ -require "thor" -require "gitlabci/controller/pipeline" -require "gitlabci/controller/trigger" +require 'thor' + +require 'gitlabci/controller/helper' +require 'gitlabci/controller/pipeline' +require 'gitlabci/controller/trigger' module Gitlabci module Controller + # Main CLI Class, with subcommands class Cli < Thor - desc "pipeline SUBCOMMAND", "Interact the pipeline API" - subcommand "pipeline", Pipeline + # RestClient.log = 'stdout' + + desc 'pipeline SUBCOMMAND', 'Interact the pipeline API' + subcommand 'pipeline', Pipeline - desc "trigger SUBCOMMAND", "Interact the trigger API" - subcommand "trigger", Trigger + desc 'trigger SUBCOMMAND', 'Interact the trigger API' + subcommand 'trigger', Trigger end end end diff --git a/lib/gitlabci/controller/helper.rb b/lib/gitlabci/controller/helper.rb new file mode 100644 index 0000000..cc6eb10 --- /dev/null +++ b/lib/gitlabci/controller/helper.rb @@ -0,0 +1,74 @@ +require 'json' +require 'rest-client' + +module Gitlabci + module Controller + # Helper Module + module Helper + module_function + + def get_job_status(id = nil, url = nil, token = nil, pipeline = nil, test = false) + begin + response = RestClient::Request.execute( + method: :get, + headers: { 'PRIVATE-TOKEN' => token }, + url: "#{url}/api/v4/projects/#{id}/pipelines/#{pipeline}/jobs", + verify_ssl: false, + timeout: 60 + ) + jobs = JSON.parse(response) + rescue => e + puts 'API error' + puts e + unless test + sleep 2 + retry + end + end + helper_response = {} + jobs.each do |job| + helper_response[job['name']] = job['status'] + end + helper_response + end + + def follow(options, pipeline) + puts "\e[32mWaiting for pipeline #{pipeline['id']} to finish\e[0m" + jobs = Gitlabci::Controller::Helper.get_job_status(options['id'], options['url'], options['token'], pipeline['id'], false) + puts "\e[32m#{jobs.length} jobs in pipeline\e[0m" + jobs.each_key do |k| + puts "\e[32mJob #{k}\e[0m" + end + time = 0 + loop do + puts 'The api is not responding, wait for next call' if jobs.nil? + + jobs = Gitlabci::Controller::Helper.get_job_status(options['id'], options['url'], options['token'], pipeline['id'], false) + sleep 2 + if (time % 10).zero? + puts "\e[32mStarted since #{time} seconds\e[0m" if time != 0 + jobs.each do |k, v| + puts "#{k} status is #{v}" + end + end + time += 2 + break if !jobs.values.include?('created') && !jobs.values.include?('running') && !jobs.values.include?('pending') && !jobs.nil? + end + + if jobs.values.uniq == ['success'] + puts "\e[32mPipeline passed\e[0m" + jobs.each do |k, v| + puts "\e[32m#{k} status is #{v}\e[0m" + end + exit 0 + else + puts "\e[31mPipeline #{pipeline['id']} failed\e[0m" + jobs.each do |k, v| + puts "\e[31m#{k} status is #{v}\e[0m" + end + end + exit 1 + end + end + end +end diff --git a/lib/gitlabci/controller/pipeline.rb b/lib/gitlabci/controller/pipeline.rb index 89a7a33..132c2aa 100644 --- a/lib/gitlabci/controller/pipeline.rb +++ b/lib/gitlabci/controller/pipeline.rb @@ -1,24 +1,27 @@ -require "thor" -require "rest-client" -require "json" -require "terminal-table" -require "time" +require 'json' +require 'rest-client' +require 'terminal-table' +require 'thor' +require 'time' + +require 'gitlabci/controller/helper' module Gitlabci module Controller + # Pipeline API Class class Pipeline < Thor - desc "list", "List the 20 last pipelines for a project" + desc 'list', 'List the 20 last pipelines for a project' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' method_option :test, boolean: true def list_pipelines begin response = RestClient::Request.execute( method: :get, - headers: {"PRIVATE-TOKEN" => options[:token]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/pipelines/", verify_ssl: false, timeout: 60 @@ -26,7 +29,7 @@ def list_pipelines pipelines = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 @@ -36,32 +39,34 @@ def list_pipelines table = Terminal::Table.new do |t| t.title = "Pipelines for #{options[:id]}" - t.headings = ["Id", "Status", "Branch"] + t.headings = %w[Id Status Branch] pipelines.each do |pipeline| - t.add_row([ - pipeline["id"], - pipeline["status"], - pipeline["ref"], - ]) + t.add_row( + [ + pipeline['id'], + pipeline['status'], + pipeline['ref'] + ] + ) end end puts table end - desc "get", "Get a pipeline status" + desc 'get', 'Get a pipeline status' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" - method_option :pipeline, required: true, aliases: "-p" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' + method_option :pipeline, required: true, aliases: '-p' method_option :test, boolean: true - def get_pipeline_status(id = nil, url = nil, token = nil, pipeline = nil, output = true) + def get_pipeline_status(id = nil, url = nil, _token = nil, pipeline = nil, output = true) # Arguments are used when I call the get_pipeline_status method from the run_pipeline method. begin response = RestClient::Request.execute( method: :get, - headers: {"PRIVATE-TOKEN" => options[:token]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, url: "#{options[:url] || url}/api/v4/projects/#{options[:id] || id}/pipelines/#{options[:pipeline] || pipeline}", verify_ssl: false, timeout: 60 @@ -69,32 +74,32 @@ def get_pipeline_status(id = nil, url = nil, token = nil, pipeline = nil, output pipeline = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - puts pipeline["status"] if output - pipeline["status"] + puts pipeline['status'] if output + pipeline['status'] end - desc "run", "Run a pipeline for a project" + desc 'run', 'Run a pipeline for a project' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" - method_option :branch, default: "master", aliases: "-b" - method_option :follow, boolean: true, aliases: "-f" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' + method_option :branch, default: 'master', aliases: '-b' + method_option :follow, boolean: true, aliases: '-f' method_option :test, boolean: true def run_pipeline begin response = RestClient::Request.execute( method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, - payload: {"ref" => options[:branch]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, + payload: { 'ref' => options[:branch] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/pipeline", verify_ssl: false, timeout: 60 @@ -102,7 +107,7 @@ def run_pipeline pipeline = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 @@ -111,51 +116,34 @@ def run_pipeline end if options[:follow] - puts "Waiting for pipeline job #{pipeline["id"]} to finish" - pipeline_status = get_pipeline_status(options["id"], options["token"], options["url"], pipeline["id"], false) - loop do - puts "The api is not responding, wait for next call" if pipeline_status == nil - - pipeline_status = get_pipeline_status(options["id"], options["token"], options["url"], pipeline["id"], false) - sleep 2 - - break if pipeline_status != "running" && pipeline_status != "pending" && pipeline_status != nil - end - - if pipeline_status == "success" - puts "\e[32mPipeline passed\e[0m" - exit 0 - else - puts "\e[31mPipeline ended with the status #{pipeline_status}\e[0m" - exit 1 - end + Gitlabci::Controller::Helper.follow(options, pipeline) else - puts "Pipeline job #{pipeline["id"]} has been started" + puts "Pipeline job #{pipeline['id']} has been started." end end - desc "retry", "Retry a failed pipeline status" + desc 'retry', 'Retry a failed pipeline status' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" - method_option :pipeline, required: true, aliases: "-p" - method_option :follow, boolean: true, aliases: "-f" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' + method_option :pipeline, required: true, aliases: '-p' + method_option :follow, boolean: true, aliases: '-f' method_option :test, boolean: true def retry_pipeline begin response = RestClient::Request.execute( method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, - url: "#{options[:url]}/api/v4/projects/#{options[:id]}/pipelines/#{options["pipeline"]}/retry", + headers: { 'PRIVATE-TOKEN' => options[:token] }, + url: "#{options[:url]}/api/v4/projects/#{options[:id]}/pipelines/#{options['pipeline']}/retry", verify_ssl: false, timeout: 60 ) pipeline = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 @@ -164,57 +152,38 @@ def retry_pipeline end if options[:follow] - puts "Waiting for pipeline job #{pipeline["id"]} to finish" - pipeline_status = get_pipeline_status(options["id"], options["token"], options["url"], pipeline["id"], false) - loop do - puts "The api is not responding, wait for next call" if pipeline_status == nil - - pipeline_status = get_pipeline_status(options["id"], options["token"], options["url"], pipeline["id"], false) - sleep 2 - - break if pipeline_status != "running" && pipeline_status != "pending" && pipeline_status != nil - end - - if pipeline_status == "success" - puts "\e[32mPipeline passed\e[0m" - exit 0 - else - puts "\e[31mPipeline ended with the status #{pipeline_status}\e[0m" - exit 1 - end + Gitlabci::Controller::Helper.follow(options, pipeline) else - puts "Pipeline job #{pipeline["id"]} has been started" + puts "Pipeline job #{pipeline['id']} has been started." end end - desc "cancel", "Cancel a running pipeline status" + desc 'cancel', 'Cancel a running pipeline status' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" - method_option :pipeline, required: true, aliases: "-p" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' + method_option :pipeline, required: true, aliases: '-p' method_option :test, boolean: true def cancel_pipeline begin - response = RestClient::Request.execute( + RestClient::Request.execute( method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, - url: "#{options[:url]}/api/v4/projects/#{options[:id]}/pipelines/#{options["pipeline"]}/cancel", + headers: { 'PRIVATE-TOKEN' => options[:token] }, + url: "#{options[:url]}/api/v4/projects/#{options[:id]}/pipelines/#{options['pipeline']}/cancel", verify_ssl: false, timeout: 60 ) - - pipeline = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - puts "Pipeline job #{options["pipeline"]} has been canceled" + puts "Pipeline job #{options['pipeline']} has been canceled." end end end diff --git a/lib/gitlabci/controller/trigger.rb b/lib/gitlabci/controller/trigger.rb index ad1d6f4..44230d1 100644 --- a/lib/gitlabci/controller/trigger.rb +++ b/lib/gitlabci/controller/trigger.rb @@ -1,26 +1,27 @@ -require "thor" -require "rest-client" -require "json" -require "terminal-table" -require "time" +require 'json' +require 'rest-client' +require 'terminal-table' +require 'thor' +require 'time' -require "gitlabci/controller/pipeline" # To use Pipeline.get_pipeline_status +require 'gitlabci/controller/helper' module Gitlabci module Controller + # Trigger API Class class Trigger < Thor - desc "list", "List the triggers for a project" + desc 'list', 'List the triggers for a project' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' method_option :test, boolean: true def list_triggers begin response = RestClient::Request.execute( method: :get, - headers: {"PRIVATE-TOKEN" => options[:token]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/triggers", verify_ssl: false, timeout: 60 @@ -28,7 +29,7 @@ def list_triggers triggers = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 @@ -38,35 +39,37 @@ def list_triggers table = Terminal::Table.new do |t| t.title = "Triggers for #{options[:id]}" - t.headings = ["Id", "Token", "Description", "Created by", "Created at", "Last used"] + t.headings = ['Id', 'Token', 'Description', 'Created by', 'Created at', 'Last used'] triggers.each do |trigger| - t.add_row([ - trigger["id"], - trigger["token"], - trigger["description"], - trigger["owner"]["name"], - trigger["created_at"], - trigger["last_used"] - ]) + t.add_row( + [ + trigger['id'], + trigger['token'], + trigger['description'], + trigger['owner']['name'], + trigger['created_at'], + trigger['last_used'] + ] + ) end end puts table end - desc "create", "Create a trigger" + desc 'create', 'Create a trigger' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" - method_option :description, required: true, aliases: "-d" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' + method_option :description, required: true, aliases: '-d' method_option :test, boolean: true def create_trigger begin response = RestClient::Request.execute( method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, - payload: {"description" => options[:description]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, + payload: { 'description' => options[:description] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/triggers", verify_ssl: false, timeout: 60 @@ -74,31 +77,31 @@ def create_trigger trigger = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - puts "Trigger #{trigger["id"]} created" + puts "Trigger #{trigger['id']} created" end - desc "update", "Update a trigger" + desc 'update', 'Update a trigger' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' method_option :trigger_id, required: true - method_option :description, required: true, aliases: "-d" + method_option :description, required: true, aliases: '-d' method_option :test, boolean: true def update_trigger begin response = RestClient::Request.execute( method: :put, - headers: {"PRIVATE-TOKEN" => options[:token]}, - payload: {"description" => options[:description]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, + payload: { 'description' => options[:description] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/triggers/#{options[:trigger_id]}", verify_ssl: false, timeout: 60 @@ -106,21 +109,21 @@ def update_trigger trigger = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - puts "Trigger #{trigger["id"]} updated with description: #{trigger["description"]}" + puts "Trigger #{trigger['id']} updated with description: #{trigger['description']}" end - desc "owner", "Take ownership of a trigger" + desc 'owner', 'Take ownership of a trigger' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' method_option :trigger_id, required: true method_option :test, boolean: true @@ -128,145 +131,101 @@ def ownership_trigger begin response = RestClient::Request.execute( method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/triggers/#{options[:trigger_id]}/take_ownership", verify_ssl: false, timeout: 60 ) - + trigger = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - puts "User #{trigger["owner"]["name"]} took ownership of trigger #{options["trigger_id"]}" + puts "User #{trigger['owner']['name']} took ownership of trigger #{options['trigger_id']}" end - desc "delete", "Delete a trigger" + desc 'delete', 'Delete a trigger' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' method_option :trigger_id, required: true method_option :test, boolean: true def delete_trigger begin - response = RestClient::Request.execute( + RestClient::Request.execute( method: :delete, - headers: {"PRIVATE-TOKEN" => options[:token]}, + headers: { 'PRIVATE-TOKEN' => options[:token] }, url: "#{options[:url]}/api/v4/projects/#{options[:id]}/triggers/#{options[:trigger_id]}", verify_ssl: false, timeout: 60 ) - rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - puts "Trigger #{options["trigger_id"]} deleted" + puts "Trigger #{options['trigger_id']} deleted" end - desc "build", "Build a trigger" + desc 'build', 'Build a trigger' - method_option :id, required: true, aliases: "-i" - method_option :token, required: true, aliases: "-t" - method_option :url, required: true, aliases: "-u" - method_option :trigger_token, required: true, aliases: "-t" - method_option :branch, default: "master", aliases: "-b" - method_option :variables, type: :hash, aliases: "-v" - method_option :follow, boolean: true, aliases: "-f" + method_option :id, required: true, aliases: '-i' + method_option :token, required: true, aliases: '-t' + method_option :url, required: true, aliases: '-u' + method_option :trigger_token, required: true, aliases: '-t' + method_option :branch, default: 'master', aliases: '-b' + method_option :variables, type: :hash, aliases: '-v' + method_option :follow, boolean: true, aliases: '-f' method_option :test, boolean: true def build_trigger begin - if options[:variables] - response = RestClient::Request.execute( - method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, - payload: {"token" => options[:trigger_token], "ref" => options[:branch], "variables" => options[:variables]}, - url: "#{options[:url]}/api/v4/projects/#{options[:id]}/trigger/pipeline", - verify_ssl: false, - timeout: 60 - ) - else - response = RestClient::Request.execute( - method: :post, - headers: {"PRIVATE-TOKEN" => options[:token]}, - payload: {"token" => options[:trigger_token], "ref" => options[:branch]}, - url: "#{options[:url]}/api/v4/projects/#{options[:id]}/trigger/pipeline", - verify_ssl: false, - timeout: 60 - ) - end + response = if options[:variables] + RestClient::Request.execute( + method: :post, + headers: { 'PRIVATE-TOKEN' => options[:token] }, + payload: { 'token' => options[:trigger_token], 'ref' => options[:branch], 'variables' => options[:variables] }, + url: "#{options[:url]}/api/v4/projects/#{options[:id]}/trigger/pipeline", + verify_ssl: false, + timeout: 60 + ) + else + RestClient::Request.execute( + method: :post, + headers: { 'PRIVATE-TOKEN' => options[:token] }, + payload: { 'token' => options[:trigger_token], 'ref' => options[:branch] }, + url: "#{options[:url]}/api/v4/projects/#{options[:id]}/trigger/pipeline", + verify_ssl: false, + timeout: 60 + ) + end pipeline = JSON.parse(response) rescue => e - puts "API error" + puts 'API error' puts e unless options[:test] sleep 2 retry end end - - if options[:follow] - puts "Waiting for pipeline job #{pipeline["id"]} to finish" - pipeline_status = get_pipeline_status(options["id"], options["token"], options["url"], pipeline["id"], false) - loop do - puts "The api is not responding, wait for next call" if pipeline_status == nil - - pipeline_status = get_pipeline_status(options["id"], options["token"], options["url"], pipeline["id"], false) - sleep 2 - break if pipeline_status != "running" && pipeline_status != "pending" && pipeline_status != nil - end - - if pipeline_status == "success" - puts "\e[32mPipeline passed\e[0m" - exit 0 - else - puts "\e[31mPipeline ended with the status #{pipeline_status}\e[0m" - exit 1 - end + if options[:follow] + Gitlabci::Controller::Helper.follow(options, pipeline) else - puts "Pipeline job #{pipeline["id"]} has been started." + puts "Pipeline job #{pipeline['id']} has been started." end end - - no_commands{ - def get_pipeline_status(id = nil, url = nil, token = nil, pipeline = nil, output = true) - # Arguments are used when I call the get_pipeline_status method from the run_pipeline method. - begin - response = RestClient::Request.execute( - method: :get, - headers: {"PRIVATE-TOKEN" => options[:token]}, - url: "#{options[:url] || url}/api/v4/projects/#{options[:id] || id}/pipelines/#{options[:pipeline] || pipeline}", - verify_ssl: false, - timeout: 60 - ) - - pipeline = JSON.parse(response) - rescue => e - puts "API error" - puts e - unless options[:test] - sleep 2 - retry - end - end - puts pipeline["status"] if output - pipeline["status"] - end - } end end end diff --git a/lib/gitlabci/controller/version.rb b/lib/gitlabci/controller/version.rb index 7b6eff6..6fbfb24 100644 --- a/lib/gitlabci/controller/version.rb +++ b/lib/gitlabci/controller/version.rb @@ -1,5 +1,6 @@ +# Version Class module Gitlabci module Controller - VERSION = "2.0.0" + VERSION = '2.0.0'.freeze end end diff --git a/spec/gitlabci/pipeline_spec.rb b/spec/gitlabci/pipeline_spec.rb index 59a8d4c..6128eb0 100644 --- a/spec/gitlabci/pipeline_spec.rb +++ b/spec/gitlabci/pipeline_spec.rb @@ -1,20 +1,19 @@ -require "spec_helper" +require 'spec_helper' -RSpec.describe Gitlabci::Controller::Pipeline, :type => :aruba do - - context "without arguments" do - it "print the help" do +RSpec.describe Gitlabci::Controller::Pipeline, type: :aruba do + context 'without arguments' do + it 'print the help' do expect(Gitlabci::Controller::Pipeline.start).not_to be nil end end - context "with arguments" do - it "print the help" do - args = ["help"] + context 'with arguments' do + it 'print the help' do + args = ['help'] expect(Gitlabci::Controller::Pipeline.start(args)).not_to be nil end - it "list the pipelines" do + it 'list the pipelines' do response = '[ { "id": 1, @@ -31,85 +30,85 @@ pipelines = JSON.parse(response) table = Terminal::Table.new do |t| - t.title = "Pipelines for 1" - t.headings = ["Id", "Status", "Branch"] + t.title = 'Pipelines for 1' + t.headings = %w[Id Status Branch] pipelines.each do |pipeline| t.add_row([ - pipeline["id"], - pipeline["status"], - pipeline["ref"] - ]) + pipeline['id'], + pipeline['status'], + pipeline['ref'] + ]) end end - stub_request(:get, "https://gitlab.fr/api/v4/projects/1/pipelines/") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) + stub_request(:get, 'https://gitlab.fr/api/v4/projects/1/pipelines/') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["list","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--test"] + args = ['list', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--test'] Gitlabci::Controller::Pipeline.start(args) - end.to output(puts table).to_stdout + end.to output(puts(table)).to_stdout end - it "get a pipeline" do + it 'get a pipeline' do response = '{ "status": "running" }' - stub_request(:get, "https://gitlab.fr/api/v4/projects/1/pipelines/1") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) + stub_request(:get, 'https://gitlab.fr/api/v4/projects/1/pipelines/1') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["get","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "-p", 1, "--test"] + args = ['get', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '-p', 1, '--test'] Gitlabci::Controller::Pipeline.start(args) end.to output("running\n").to_stdout end - it "run a pipelines" do + it 'run a pipelines' do response = '{ "id": 1 }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/pipeline") - .with(headers: {"PRIVATE-TOKEN" => "1234"}, body: {"ref" => "master"}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/pipeline') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }, body: { 'ref' => 'master' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["run","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--test"] + args = ['run', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--test'] Gitlabci::Controller::Pipeline.start(args) - end.to output("Pipeline job 1 has been started\n").to_stdout + end.to output("Pipeline job 1 has been started.\n").to_stdout end - it "retry a pipeline" do + it 'retry a pipeline' do response = '{ "id": 1 }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/pipelines/1/retry") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/pipelines/1/retry') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["retry","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "-p", 1, "--test"] + args = ['retry', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '-p', 1, '--test'] Gitlabci::Controller::Pipeline.start(args) - end.to output("Pipeline job 1 has been started\n").to_stdout + end.to output("Pipeline job 1 has been started.\n").to_stdout end - it "cancel a pipeline" do + it 'cancel a pipeline' do response = '{ "id": 1 }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/pipelines/1/cancel") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/pipelines/1/cancel') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["cancel","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "-p", 1, "--test"] + args = ['cancel', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '-p', 1, '--test'] Gitlabci::Controller::Pipeline.start(args) - end.to output("Pipeline job 1 has been canceled\n").to_stdout + end.to output("Pipeline job 1 has been canceled.\n").to_stdout end end end diff --git a/spec/gitlabci/trigger_spec.rb b/spec/gitlabci/trigger_spec.rb index 680a29f..6e1da35 100644 --- a/spec/gitlabci/trigger_spec.rb +++ b/spec/gitlabci/trigger_spec.rb @@ -1,20 +1,19 @@ -require "spec_helper" +require 'spec_helper' -RSpec.describe Gitlabci::Controller::Trigger, :type => :aruba do - - context "without arguments" do - it "print the help" do +RSpec.describe Gitlabci::Controller::Trigger, type: :aruba do + context 'without arguments' do + it 'print the help' do expect(Gitlabci::Controller::Trigger.start).not_to be nil end end - context "with arguments" do - it "print the help" do - args = ["help"] + context 'with arguments' do + it 'print the help' do + args = ['help'] expect(Gitlabci::Controller::Trigger.start(args)).not_to be nil end - it "list the triggers" do + it 'list the triggers' do response = '[ { "id": 1, @@ -51,31 +50,31 @@ triggers = JSON.parse(response) table = Terminal::Table.new do |t| - t.title = "Triggers for 1" - t.headings = ["Id", "Token", "Description", "Created by", "Created at", "Last used"] + t.title = 'Triggers for 1' + t.headings = ['Id', 'Token', 'Description', 'Created by', 'Created at', 'Last used'] triggers.each do |trigger| t.add_row([ - trigger["id"], - trigger["token"], - trigger["description"], - trigger["owner"]["name"], - trigger["created_at"], - trigger["last_used"] - ]) + trigger['id'], + trigger['token'], + trigger['description'], + trigger['owner']['name'], + trigger['created_at'], + trigger['last_used'] + ]) end end - stub_request(:get, "https://gitlab.fr/api/v4/projects/1/triggers") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) + stub_request(:get, 'https://gitlab.fr/api/v4/projects/1/triggers') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["list","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--test"] + args = ['list', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--test'] Gitlabci::Controller::Trigger.start(args) - end.to output(puts table).to_stdout + end.to output(puts(table)).to_stdout end - it "create a trigger" do + it 'create a trigger' do response = '{ "id": 1, "token": "RANDOM_TOKEN", @@ -92,17 +91,17 @@ } }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/triggers") - .with(headers: {"PRIVATE-TOKEN" => "1234"}, body: {"description" => "description"}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/triggers') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }, body: { 'description' => 'description' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["create","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "-d", "description", "--test"] + args = ['create', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '-d', 'description', '--test'] Gitlabci::Controller::Trigger.start(args) end.to output("Trigger 1 created\n").to_stdout end - it "changes the owner of a trigger" do + it 'changes the owner of a trigger' do response = '{ "id": 1, "token": "RANDOM_TOKEN", @@ -119,17 +118,17 @@ } }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/triggers/1/take_ownership") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/triggers/1/take_ownership') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["owner","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--trigger_id", "1", "--test"] + args = ['owner', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--trigger_id', '1', '--test'] Gitlabci::Controller::Trigger.start(args) end.to output("User Kevin Flynn took ownership of trigger 1\n").to_stdout end - it "update a trigger" do + it 'update a trigger' do response = '{ "id": 1, "token": "RANDOM_TOKEN", @@ -146,57 +145,57 @@ } }' - stub_request(:put, "https://gitlab.fr/api/v4/projects/1/triggers/1") - .with(headers: {"PRIVATE-TOKEN" => "1234"}, body: {"description" => "description_updated"}) + stub_request(:put, 'https://gitlab.fr/api/v4/projects/1/triggers/1') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }, body: { 'description' => 'description_updated' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["update","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--trigger_id", "1", "-d", "description_updated", "--test"] + args = ['update', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--trigger_id', '1', '-d', 'description_updated', '--test'] Gitlabci::Controller::Trigger.start(args) end.to output("Trigger 1 updated with description: description_updated\n").to_stdout end - it "delete a trigger" do - stub_request(:delete, "https://gitlab.fr/api/v4/projects/1/triggers/1") - .with(headers: {"PRIVATE-TOKEN" => "1234"}) - .to_return(status: 200, body: "", headers: {}) + it 'delete a trigger' do + stub_request(:delete, 'https://gitlab.fr/api/v4/projects/1/triggers/1') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }) + .to_return(status: 200, body: '', headers: {}) expect do - args = ["delete","-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--trigger_id", "1", "--test"] + args = ['delete', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--trigger_id', '1', '--test'] Gitlabci::Controller::Trigger.start(args) end.to output("Trigger 1 deleted\n").to_stdout end - it "build a trigger" do + it 'build a trigger' do response = '{ "id": 1, "ref": "master", "status": "pending" }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/trigger/pipeline") - .with(headers: {"PRIVATE-TOKEN" => "1234"}, body: {"token" => "TRIGGER_TOKEN", "ref" => "master"}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/trigger/pipeline') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }, body: { 'token' => 'TRIGGER_TOKEN', 'ref' => 'master' }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["build", "-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--trigger_token", "TRIGGER_TOKEN", "--test"] + args = ['build', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--trigger_token', 'TRIGGER_TOKEN', '--test'] Gitlabci::Controller::Trigger.start(args) end.to output("Pipeline job 1 has been started.\n").to_stdout end - it "build a trigger with variables" do + it 'build a trigger with variables' do response = '{ "id": 1, "ref": "master", "status": "pending" }' - stub_request(:post, "https://gitlab.fr/api/v4/projects/1/trigger/pipeline") - .with(headers: {"PRIVATE-TOKEN" => "1234"},body: {"token" => "TRIGGER_TOKEN", "ref" => "master", "variables" => {"k1" => "v1", "k2" => "v2"}}) + stub_request(:post, 'https://gitlab.fr/api/v4/projects/1/trigger/pipeline') + .with(headers: { 'PRIVATE-TOKEN' => '1234' }, body: { 'token' => 'TRIGGER_TOKEN', 'ref' => 'master', 'variables' => { 'k1' => 'v1', 'k2' => 'v2' } }) .to_return(status: 200, body: response, headers: {}) expect do - args = ["build", "-i", "1", "-t", "1234", "-u", "https://gitlab.fr", "--trigger_token", "TRIGGER_TOKEN", "-v=k1:v1", "k2:v2", "--test"] + args = ['build', '-i', '1', '-t', '1234', '-u', 'https://gitlab.fr', '--trigger_token', 'TRIGGER_TOKEN', '-v=k1:v1', 'k2:v2', '--test'] Gitlabci::Controller::Trigger.start(args) end.to output("Pipeline job 1 has been started.\n").to_stdout end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bb4c42a..4a49ada 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,11 @@ -require "bundler/setup" -require "gitlabci/controller" -require "webmock/rspec" +require 'bundler/setup' +require 'webmock/rspec' + +require 'gitlabci/controller' RSpec.configure do |config| # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = ".rspec_status" + config.example_status_persistence_file_path = '.rspec_status' config.expect_with :rspec do |c| c.syntax = :expect @@ -15,8 +16,8 @@ original_stdout = $stdout config.before(:all) do # Redirect stderr and stdout - $stderr = File.open(File::NULL, "w") - $stdout = File.open(File::NULL, "w") + $stderr = File.open(File::NULL, 'w') + $stdout = File.open(File::NULL, 'w') end config.after(:all) do $stderr = original_stderr