go_figure 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in go_figure.gemspec
4
+ gemspec
data/README.textile ADDED
@@ -0,0 +1,45 @@
1
+ h2. Go Figure Gem
2
+
3
+ This gem generates configuration for Go server - basically given a stage/pipeline
4
+ group this gem will configure for default pipeline and a simple test stage
5
+
6
+ h2. Installation
7
+
8
+ <pre>$ [sudo] gem install go_figure</pre>
9
+
10
+ h2. Usage
11
+
12
+ <pre>
13
+ require 'go_figure'
14
+ endpoint = GoFigure::GoConfigEndpoint.new(:host => 'example.com', :port => 8153)
15
+ config = endpoint.get_config
16
+ config.set_pipeline('http://github.com/user/repo.git', 'rails_working_dir')
17
+ endpoint.update_config(config)
18
+ </pre>
19
+
20
+ h2. License
21
+
22
+ Go Figure Gem is MIT Licensed
23
+
24
+ The MIT License
25
+
26
+ Copyright (c) 2012 ThoughtWorks, Inc. (http://thoughtworks.com)
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ of this software and associated documentation files (the "Software"), to deal
30
+ in the Software without restriction, including without limitation the rights
31
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ copies of the Software, and to permit persons to whom the Software is
33
+ furnished to do so, subject to the following conditions:
34
+
35
+ The above copyright notice and this permission notice shall be included in
36
+ all copies or substantial portions of the Software.
37
+
38
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ THE SOFTWARE.
45
+
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :test do
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.test_files = FileList['test/**/*test.rb']
8
+ t.verbose = true
9
+ end
10
+ end
11
+
12
+ task :default => :test
13
+
data/go_figure.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "go_figure/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "go_figure"
7
+ s.version = GoFigure::VERSION
8
+ s.authors = ["Ketan Padegaonkar"]
9
+ s.email = ["KetanPadegaonkar@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A Ruby DSL to write a configuration file for the a go server.}
12
+ s.description = %q{This provides a ruby DSL to create a configuration file for the go server (thoughtworks-studios.com/go)}
13
+
14
+ s.rubyforge_project = "go_figure"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+
22
+ # specify any dependencies here; for example:
23
+ # s.add_development_dependency "rspec"
24
+ s.add_runtime_dependency "nokogiri", "~> 1.5.0"
25
+ end
@@ -0,0 +1,32 @@
1
+ <pipelines group="defaultGroup">
2
+ <pipeline name="defaultPipeline">
3
+ <materials>
4
+ <git url="<%= @git_url %>" />
5
+ </materials>
6
+ <stage name="Units">
7
+ <jobs>
8
+ <job name="Test">
9
+ <tasks>
10
+ <exec command="bundle" workingdir="<%= @working_dir %>">
11
+ <arg>install</arg>
12
+ <arg>--local</arg>
13
+ <runif status="passed" />
14
+ </exec>
15
+ <exec command="bundle" workingdir="<%= @working_dir %>">
16
+ <arg>exec</arg>
17
+ <arg>rake</arg>
18
+ <arg>db:create</arg>
19
+ <arg>db:migrate</arg>
20
+ <runif status="passed" />
21
+ </exec>
22
+ <exec command="bundle" workingdir="<%= @working_dir %>">
23
+ <arg>exec</arg>
24
+ <arg>rake</arg>
25
+ <runif status="passed" />
26
+ </exec>
27
+ </tasks>
28
+ </job>
29
+ </jobs>
30
+ </stage>
31
+ </pipeline>
32
+ </pipelines>
@@ -0,0 +1,51 @@
1
+ require 'nokogiri'
2
+ require 'erb'
3
+
4
+ module GoFigure
5
+ class GoConfig
6
+ attr_accessor :original_md5
7
+ attr_reader :original_xml
8
+
9
+ def initialize(options = {})
10
+ @original_md5 = options[:md5]
11
+ @original_xml = options[:xml]
12
+ @doc = Nokogiri.XML(@original_xml, nil, 'utf-8')
13
+ end
14
+
15
+ def set_pipeline(git_url, working_dir)
16
+ @doc.root.xpath('pipelines').remove
17
+ agents = @doc.root.xpath('agents')
18
+
19
+ if agents.any?
20
+ agents.before(pipeline_template(git_url, working_dir))
21
+ else
22
+ @doc.root << pipeline_template(git_url, working_dir)
23
+ end
24
+
25
+ @doc = Nokogiri.XML(@doc.to_s) do |config|
26
+ config.default_xml.noblanks
27
+ end
28
+ end
29
+
30
+ def pipeline_template(git_url, working_dir)
31
+ template = ERB.new(File.read(File.expand_path('../../go-pipelines.xml.erb', __FILE__)))
32
+ template.result(PipelineConfig.new(git_url, working_dir).get_binding)
33
+ end
34
+
35
+ def xml_content
36
+ @doc.to_s
37
+ end
38
+
39
+ class PipelineConfig
40
+ def initialize(git_url, working_dir)
41
+ @git_url = git_url
42
+ @working_dir = working_dir
43
+ end
44
+
45
+ def get_binding
46
+ binding
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ module GoFigure
2
+
3
+ class GoConfigEndpoint
4
+
5
+ DEFAULT_OPTIONS = {
6
+ :host => 'localhost',
7
+ :port => 8153
8
+ }
9
+
10
+ attr_accessor *DEFAULT_OPTIONS.keys
11
+ attr_accessor :http_fetcher
12
+
13
+ def initialize(options)
14
+ DEFAULT_OPTIONS.each do |k, v|
15
+ self.send("#{k}=", options[k] || v)
16
+ end
17
+ end
18
+
19
+ def get_config
20
+ response = http_fetcher.get(config_xml_url)
21
+ if response.status == 200
22
+ return GoConfig.new(:md5 => response['X-CRUISE-CONFIG-MD5'], :xml => response.body)
23
+ else
24
+ raise "Could not fetch the go config file"
25
+ end
26
+ end
27
+
28
+ def update_config(go_config)
29
+ http_fetcher.post(config_xml_url, :xmlFile => go_config.xml_content, :md5 => go_config.original_md5)
30
+ end
31
+
32
+ def http_fetcher
33
+ @http_fetcher || HttpFetcher.new
34
+ end
35
+
36
+ private
37
+ def config_xml_url
38
+ "http://#{host}:#{port}/go/api/admin/config.xml"
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,27 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+
4
+ module UserImport
5
+ class HttpFetcher
6
+
7
+ def fetch(url, user, pass)
8
+ url = URI.parse(url)
9
+
10
+ http = Net::HTTP.new(url.host, url.port)
11
+ http.use_ssl = url.scheme == 'https'
12
+
13
+ res = http.start do |http|
14
+ req = Net::HTTP::Get.new(url.path)
15
+ req.basic_auth user, pass
16
+ http.request(req)
17
+ end
18
+
19
+ case res
20
+ when Net::HTTPSuccess
21
+ return res.body
22
+ end
23
+ res.error!
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,3 @@
1
+ module GoFigure
2
+ VERSION = "0.0.1"
3
+ end
data/lib/go_figure.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "go_figure/version"
2
+ require "go_figure/go_config"
3
+ require "go_figure/http_fetcher"
4
+ require "go_figure/go_config_endpoint"
5
+
6
+ module GoFigure
7
+ # Your code goes here...
8
+ end
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <cruise xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:say="com.thoughtworks.cruise.task.plugin.say" xsi:noNamespaceSchemaLocation="cruise-config.xsd" xsi:schemaLocation="com.thoughtworks.cruise.task.plugin.say bundle://1.0:1/say-config.xsd" schemaVersion="52">
3
+ <pipelines group="defaultGroup1">
4
+ <pipeline name="MyPipeline">
5
+ <materials>
6
+ <git url="git@go-saas.github.com:ThoughtWorksInc/go-saas.git" />
7
+ </materials>
8
+ <stage name="Units">
9
+ <jobs>
10
+ <job name="UnitTest">
11
+ <tasks>
12
+ <exec command="bundle" workingdir="rails">
13
+ <arg>install</arg>
14
+ <arg>--local</arg>
15
+ <runif status="passed" />
16
+ </exec>
17
+ <exec command="bundle" workingdir="rails">
18
+ <arg>exec</arg>
19
+ <arg>rake</arg>
20
+ <arg>db:create</arg>
21
+ <arg>db:migrate</arg>
22
+ <runif status="passed" />
23
+ </exec>
24
+ <rake workingdir="rails" />
25
+ </tasks>
26
+ </job>
27
+ </jobs>
28
+ </stage>
29
+ </pipeline>
30
+ </pipelines>
31
+ <agents>
32
+ <agent hostname="ika.corporate.thoughtworks.com" ipaddress="10.12.1.229" uuid="de494931-c26c-44ef-a94d-8835166a3e88" />
33
+ </agents>
34
+ </cruise>
35
+
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+
4
+ module GoFigure
5
+ class GoConfigEndpointTest < Test::Unit::TestCase
6
+
7
+ def test_should_fetch_xml_config_on_localhost
8
+ md5 = '7455edff001e2f262beb7c13f10ff7cb'
9
+ endpoint = GoConfigEndpoint.new(:host => 'example.com', :port => 1234)
10
+ endpoint.http_fetcher = fetcher_with_config_file('foo.xml', md5, config_endpoint)
11
+
12
+ config = endpoint.get_config
13
+ assert_equal config_file('foo.xml'), config.original_xml
14
+ assert_equal md5, config.original_md5
15
+ end
16
+
17
+ def test_should_post_back_new_config_xml_content_with_original_md5
18
+ md5 = '7455edff001e2f262beb7c13f10ff7cb'
19
+ endpoint = GoConfigEndpoint.new(:host => 'example.com', :port => 1234)
20
+ endpoint.http_fetcher = fetcher_with_config_file('foo.xml', md5, config_endpoint)
21
+
22
+ config = endpoint.get_config
23
+ config.set_pipeline("http://git.example.com/foo/bar.git", "my_rails_app")
24
+
25
+ endpoint.http_fetcher.register_content("OK", config_endpoint, :post, :md5 => config.original_md5, :xmlFile => config.xml_content)
26
+
27
+ endpoint.update_config(config)
28
+ assert endpoint.http_fetcher.invoked?(config_endpoint, :post, :md5 => config.original_md5, :xmlFile => config.xml_content)
29
+ end
30
+
31
+ def config_endpoint
32
+ "http://example.com:1234/go/api/admin/config.xml"
33
+ end
34
+
35
+ def fetcher_with_config_file(file_name, md5, url)
36
+ endpoint = StubHttpFetcher.new
37
+ endpoint.register_content(config_file(file_name), config_endpoint, :get, 'X-CRUISE-CONFIG-MD5' => md5)
38
+ endpoint
39
+ end
40
+
41
+ def config_file(file_name)
42
+ File.read("test/fixtures/#{file_name}")
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ module GoFigure
4
+ class GoConfigTest < Test::Unit::TestCase
5
+
6
+ def test_should_set_pipeline_in_a_config_file_with_no_pipelines_and_no_agents
7
+ assert_pipeline_template %Q{<?xml version="1.0" encoding="utf-8"?>
8
+ <cruise />
9
+ }
10
+ end
11
+
12
+ def test_should_set_pipeline_in_a_config_file_with_pipelines_and_no_agents
13
+
14
+ assert_pipeline_template %Q{<?xml version="1.0" encoding="utf-8"?>
15
+ <cruise>
16
+ <pipelines group="1">
17
+ </pipelines>
18
+
19
+ <pipelines group="2">
20
+ </pipelines>
21
+ </cruise>
22
+ }
23
+ end
24
+
25
+ def test_should_set_pipeline_in_a_config_file_with_no_pipelines_and_agents
26
+ assert_pipeline_template %Q{<?xml version="1.0" encoding="utf-8"?>
27
+ <cruise>
28
+ <agents />
29
+ </cruise>
30
+ }
31
+ end
32
+
33
+ def test_should_set_pipelines_in_a_config_file_with_pipelines_and_agents
34
+ assert_pipeline_template %Q{<?xml version="1.0" encoding="utf-8"?>
35
+ <cruise>
36
+ <pipelines group="1">
37
+ </pipelines>
38
+
39
+ <pipelines group="2">
40
+ </pipelines>
41
+ <agents />
42
+ </cruise>
43
+ }
44
+ end
45
+
46
+
47
+ def assert_pipeline_template(xml)
48
+ config = GoConfig.new(:xml => xml)
49
+ config.set_pipeline('http://git.example.com/my_project/atlas.git', 'atlas_rails')
50
+ assert config.xml_content =~ %r{<pipelines group="defaultGroup">}
51
+ assert config.xml_content =~ %r{<git url="http://git.example.com/my_project/atlas.git"/>}
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,88 @@
1
+ require 'ostruct'
2
+ class StubHttpFetcher
3
+ # Careful : this will respond to any call with nil
4
+ class HashStruct < OpenStruct
5
+ def [](key)
6
+ self.headers[key]
7
+ end
8
+ end
9
+
10
+ module Response
11
+ def invoked!
12
+ @invoked = true
13
+ end
14
+
15
+ def invoked?
16
+ !!@invoked
17
+ end
18
+ end
19
+
20
+ class StringResponse
21
+ include Response
22
+ def initialize(content, status = 200, headers = {})
23
+ @content = content
24
+ @status = 200
25
+ @headers = headers
26
+ end
27
+
28
+ def execute
29
+ HashStruct.new(:body => @content, :status => @status, :headers => @headers)
30
+ end
31
+
32
+ end
33
+
34
+ class ErrorResponse
35
+ include Response
36
+ def initialize(error)
37
+ @error = error
38
+ end
39
+
40
+ def execute
41
+ raise @error
42
+ end
43
+ end
44
+
45
+ def get(url)
46
+ if body = interweb[:get][url]
47
+ body.invoked!
48
+ return body.execute
49
+ else
50
+ raise "404 - Could not find #{url}. Available URLs are #{@interweb[:get].keys.inspect}"
51
+ end
52
+ end
53
+
54
+ def post(url, params = {})
55
+ if body = interweb[:post][url]
56
+ response = body.execute
57
+ if response.headers == params
58
+ body.invoked!
59
+ return response
60
+ end
61
+ end
62
+
63
+ raise "404 - Could not find a url listening to #{url.inspect} that responds to post params #{params.inspect}. Available URLs are #{@interweb[:post].keys.inspect}"
64
+ end
65
+
66
+ def invoked?(url, type = :get, params = {})
67
+ if body = interweb[type][url]
68
+ response = body.execute
69
+ if response.headers == params
70
+ body.invoked?
71
+ end
72
+ end
73
+ end
74
+
75
+ def register_content(content, url, type = :get, headers = {})
76
+ interweb[type][url] = StringResponse.new(content, 200, headers)
77
+ end
78
+
79
+ def register_error(url, type = :get, error)
80
+ interweb[type][url] = ErrorResponse.new(error)
81
+ end
82
+
83
+ def interweb
84
+ @interweb ||= {:get => {}, :post => {}}
85
+ end
86
+
87
+ end
88
+
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+ require 'stub_http_fetcher'
3
+
4
+ require 'go_figure'
5
+
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: go_figure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ketan Padegaonkar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-14 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &70114218851080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.5.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70114218851080
25
+ description: This provides a ruby DSL to create a configuration file for the go server
26
+ (thoughtworks-studios.com/go)
27
+ email:
28
+ - KetanPadegaonkar@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - README.textile
36
+ - Rakefile
37
+ - go_figure.gemspec
38
+ - lib/go-pipelines.xml.erb
39
+ - lib/go_figure.rb
40
+ - lib/go_figure/go_config.rb
41
+ - lib/go_figure/go_config_endpoint.rb
42
+ - lib/go_figure/http_fetcher.rb
43
+ - lib/go_figure/version.rb
44
+ - test/fixtures/foo.xml
45
+ - test/go_figure/go_config_endpoint_test.rb
46
+ - test/go_figure/go_config_test.rb
47
+ - test/stub_http_fetcher.rb
48
+ - test/test_helper.rb
49
+ homepage: ''
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project: go_figure
69
+ rubygems_version: 1.8.15
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: A Ruby DSL to write a configuration file for the a go server.
73
+ test_files:
74
+ - test/fixtures/foo.xml
75
+ - test/go_figure/go_config_endpoint_test.rb
76
+ - test/go_figure/go_config_test.rb
77
+ - test/stub_http_fetcher.rb
78
+ - test/test_helper.rb