Permalink
Browse files

Refactored from a client singleton.

  • Loading branch information...
dblock committed Apr 26, 2012
1 parent c168bb9 commit 4a9871bf13801de7f9b66ec19678a73a1a52faee
View
@@ -21,26 +21,28 @@ Or install it yourself as:
In rails add an initialiser like this
``` ruby
-Jenkins::Client.configure do |c|
- c.username = "user"
- c.password = "pass"
- c.url = "http://jenkinsurl.com"
-end
+client = Jenkins::Client.new
+client.username = "user"
+client.password = "pass"
+client.url = "http://jenkinsurl.com"
```
Then you can issue the following commands in your app.
-### All
+### Jobs
-`Jenkins::Client::Job.all` pulls back a list of objects that represent all the Jenkins jobs on the server.
+`client.jobs` returns a hash of jobs with the job name as key.
-### Find
+#### Create
-`Jenkins::Client::Job.find("job_name")` pulls back a single Jenkins job based on the job name.
+Create a new Jenkins job on the server with a given configuration.
-### Create
+``` ruby
+job = Jenkins::Client::Job.new({name: "job_name"})
+job.create!(config)
+```
-`Jenkins::Client::Job.create("job_name", config).should be_true` will create a new Jenkins job on the server based on the config you pass in. Jenkins uses XML config files on the server and this is what you should send as the config. Example
+Jenkins uses XML config files on the server and this is what you should send as the config. Example:
``` xml
<?xml version='1.0' encoding='UTF-8'?>
@@ -64,13 +66,31 @@ Then you can issue the following commands in your app.
To export an existing config simply look in the jobs path inside your Jenkins server and pull back a job's `config.xml` file.
-### Start
+#### Start
+
+Starts a job.
+
+job = Jenkins::Client::Job.new({name: "job_name"})
+job.start!
+
+#### Delete
+
+Delete a Jenkins job on the server.
+
+``` ruby
+job = Jenkins::Client::Job.new({name: "job_name"})
+job.delete!
+```
+
+#### Last Build
-`Jenkins::Client::Job.start("job_name")` will start a build for the job whose name is passed by parameter
+`job.last_build` will return the last build.
+`job.last_successful_build` will return the last successful build.
+`job.last_failed_build` will return the last failed build.
-### LastBuild
+### Build
-`Jenkins::Client::Job.lastBuild("job_name")` will return information about the last build of the job whose name is passed by parameter
+`build.console_text` will return the build's console text.
## Contributing
View
@@ -1,2 +1,7 @@
+require "faraday"
+require "faraday_middleware"
+require 'rash'
require "jenkins-client/version"
-require "jenkins-client/job"
+require "jenkins-client/client"
+require "jenkins-client/job"
+require "jenkins-client/build"
@@ -0,0 +1,11 @@
+module Jenkins
+ class Client
+ class Build < Hashie::Rash
+ attr_accessor :job
+
+ def console_text
+ job.client.get("#{url}consoleText", job.client.raw_connection).body
+ end
+ end
+ end
+end
@@ -1,47 +1,61 @@
-require "faraday"
-require "faraday_middleware"
-require 'rash'
-
module Jenkins
class Client
- class << self
- attr_accessor :username, :password, :url, :connection
+ attr_accessor :username, :password, :url
- def configure
- yield self
- setup_connection
- end
+ def configure
+ yield self
+ end
- @connection
- def setup_connection
- @connection = Faraday.new(:url => url) do |builder|
+ def connection
+ @connection ||= begin
+ c = Faraday.new(:url => url) do |builder|
builder.use FaradayMiddleware::Rashify
builder.use FaradayMiddleware::ParseJson
- builder.adapter :net_http
+ builder.adapter :net_http
end
- @connection.basic_auth username, password
+ c.basic_auth username, password
+ c
end
-
- def get(path)
- normalized_path = normalize_path path
- connection.get(normalized_path)
- end
-
- def post(path, body)
- normalized_path = normalize_path path
- resp = @connection.post do |req|
- req.headers['Content-Type'] = 'application/xml'
- req.url normalized_path
- req.body = body
+ end
+
+ def raw_connection
+ @raw_connection ||= begin
+ c = Faraday.new(:url => url) do |builder|
+ builder.adapter :net_http
end
- resp.status == 200
+ c.basic_auth username, password
+ c
end
+ end
+
+ def get(path, use_connection = connection)
+ normalized_path = normalize_path path
+ use_connection.get(normalized_path)
+ end
- private
- def normalize_path path
- return @connection.path_prefix+path unless @connection.path_prefix == '/'
- path
+ def post(path, body, use_connection = connection)
+ normalized_path = normalize_path path
+ resp = use_connection.post do |req|
+ req.headers['Content-Type'] = 'application/xml'
+ req.url normalized_path
+ req.body = body
end
+ resp.status == 200
+ end
+
+ def jobs
+ Hash[get("/api/json").body.jobs.map do |data|
+ job = Jenkins::Client::Job.new(data)
+ job.client = self
+ [ job.name, job ]
+ end]
+ end
+
+ private
+
+ def normalize_path path
+ return @connection.path_prefix+path unless @connection.path_prefix == '/'
+ path
end
end
View
@@ -1,32 +1,34 @@
-require "jenkins-client/client"
-
module Jenkins
class Client
- class Job
- def self.all
- resp = Jenkins::Client.get "/api/json"
- resp.body.jobs
+ class Job < Hashie::Rash
+ attr_accessor :client
+
+ def create!(config)
+ client.post("/createItem/api/xml?name=#{CGI.escape(name)}", config)
end
-
- def self.find(name)
- all.select{|j| j.name == name}.first
+
+ def delete!
+ client.post("/job/#{name}/doDelete", "")
end
-
- def self.create(name, config)
- Jenkins::Client.post("/createItem/api/xml?name=#{CGI.escape(name)}", config)
+
+ def start!
+ client.post("/job/#{name}/build", "")
end
-
- def self.delete(name)
- Jenkins::Client.post("/job/#{name}/doDelete", "")
+
+ def last_build(status = "")
+ build = Jenkins::Client::Build.new(client.get("/job/#{name}/last#{status.capitalize}Build/api/json").body)
+ build.job = self
+ build
end
-
- def self.start(name)
- Jenkins::Client.post("/job/#{name}/build", "")
+
+ def last_failed_build
+ last_build(:failed)
end
-
- def self.lastBuild(name)
- Jenkins::Client::get("/job/#{name}/lastBuild/api/json")
+
+ def last_successful_build
+ last_build(:successful)
end
+
end
end
end
No changes.
@@ -0,0 +1,57 @@
+require "spec_helper"
+
+describe Jenkins::Client do
+
+ before(:each) do
+ jenkins_config("https://jenkinstest.com")
+ end
+
+ before(:each) do
+ body = '{"assignedLabels":[{}],"mode":"NORMAL","nodeDescription":"the master Jenkins node","nodeName":"","numExecutors":2,"description":null,"jobs":[
+ {"name":"foo-bar","url":"https://testjenkins.com/job/foo-bar/","color":"blue"},
+ {"name":"woohoo","url":"https://jenkinstest.com/job/woohoo/","color":"red"},
+ {"name":"wat","url":"https://jenkinstest.com/job/wat/","color":"red"},
+ {"name":"fudge","url":"https://jenkinstest.com/job/fudge/","color":"blue"},
+ {"name":"amaze","url":"https://jenkinstest.com/job/amaze/","color":"blue"}]}'
+ stub_request(:get, "https://testuser:testpass@jenkinstest.com/api/json").
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
+ to_return(:status => 200, :body => body, :headers => {})
+ end
+
+ before(:each) do
+ body = '{"assignedLabels":[{}],"mode":"NORMAL","nodeDescription":"the master Jenkins node","nodeName":"","numExecutors":2,"description":null,"jobs":[]}'
+ stub_request(:get, "https://testuser:testpass@emptyjenkinstest.com/api/json").
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
+ to_return(:status => 200, :body => body, :headers => {})
+ end
+
+ describe ".jobs" do
+ context "given some jobs are available" do
+ let(:jobs) { @client.jobs }
+
+ it "will return a list of jobs" do
+ jobs.should have(5).items
+ end
+
+ it "will contain an expected job" do
+ jobs.should include(
+ "foo-bar" => {
+ "name"=>"foo-bar",
+ "url"=>"https://testjenkins.com/job/foo-bar/",
+ "color"=>"blue"
+ })
+ end
+ end
+
+ context "given no jobs" do
+ before(:each) do
+ empty_jenkins_config
+ end
+
+ it "will have no jobs" do
+ @client.jobs.should be_empty
+ end
+ end
+ end
+
+end
Oops, something went wrong.

0 comments on commit 4a9871b

Please sign in to comment.