polisher 0.3 → 0.4
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/README.rdoc +84 -14
- data/Rakefile +21 -19
- data/TODO +5 -4
- data/bin/server +1 -0
- data/config/polisher.yml +0 -15
- data/db/connection.rb +13 -10
- data/db/migrations/{002_create_managed_gems.rb → 001_create_projects.rb} +4 -5
- data/db/migrations/{001_create_sources.rb → 002_create_sources.rb} +1 -3
- data/db/migrations/003_create_project_source_versions.rb +28 -0
- data/db/migrations/{003_create_events.rb → 004_create_events.rb} +2 -2
- data/db/migrations/005_create_project_dependencies.rb +28 -0
- data/db/models/event.rb +47 -21
- data/db/models/project.rb +110 -0
- data/db/models/project_dependency.rb +27 -0
- data/db/models/project_source_version.rb +31 -0
- data/db/models/source.rb +82 -16
- data/lib/common.rb +37 -5
- data/lib/dsl.rb +292 -0
- data/lib/event_handlers.rb +139 -73
- data/lib/gem_adapter.rb +94 -0
- data/polisher.rb +302 -50
- data/public/stylesheets/style.css +15 -31
- data/spec/common_spec.rb +28 -0
- data/spec/dsl_spec.rb +357 -0
- data/spec/event_handlers_spec.rb +166 -30
- data/spec/gem_adapter_spec.rb +89 -0
- data/spec/models_spec.rb +635 -107
- data/spec/polisher_spec.rb +496 -56
- data/views/layout.haml +3 -5
- data/views/projects/index.haml +42 -0
- data/views/projects/index.html.haml +38 -0
- data/views/result.haml +9 -0
- data/views/sources/index.haml +24 -41
- data/views/sources/index.html.haml +26 -0
- metadata +131 -12
- data/db/models/managed_gem.rb +0 -111
- data/public/javascripts/jquery-1.2.6.min.js +0 -32
- data/public/javascripts/polisher.js +0 -15
- data/views/gems/index.haml +0 -106
@@ -0,0 +1,110 @@
|
|
1
|
+
# Copyright (C) 2010 Red Hat, Inc.
|
2
|
+
# Written by Mohammed Morsi <mmorsi@redhat.com>
|
3
|
+
#
|
4
|
+
# This program is free software, you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License
|
6
|
+
# as published by the Free Software Foundation, either version 3
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# You should have received a copy of the the GNU Affero
|
10
|
+
# General Public License, along with Polisher. If not, see
|
11
|
+
# <http://www.gnu.org/licenses/>
|
12
|
+
|
13
|
+
class Project < ActiveRecord::Base
|
14
|
+
# TODO on delete, destroy these
|
15
|
+
has_many :project_source_versions
|
16
|
+
has_many :sources, :through => :project_source_versions
|
17
|
+
has_many :events
|
18
|
+
|
19
|
+
has_many :project_dependencies
|
20
|
+
has_many :project_dependents, :class_name => "ProjectDependency", :foreign_key => "depends_on_project_id"
|
21
|
+
|
22
|
+
alias :dependencies :project_dependencies
|
23
|
+
alias :dependents :project_dependents
|
24
|
+
|
25
|
+
validates_presence_of :name
|
26
|
+
validates_uniqueness_of :name
|
27
|
+
|
28
|
+
# Download all project sources to specified :dir
|
29
|
+
def download_to(args = {})
|
30
|
+
# If a version isn't specified we can't lookup project_source_versions entry for uri substitutions
|
31
|
+
# FIXME the latter case in this ternary operator should be something along the lines of sources_for_all_versions returning those only associated w/ project_version = nil (also being sure to do uri_params substition) (?)
|
32
|
+
srcs = args.has_key?(:version) ? sources_for_version(args[:version]) : sources
|
33
|
+
srcs.each { |source| source.download_to args }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return all events associated w/ particular version of the project
|
37
|
+
def events_for_version(version)
|
38
|
+
evnts = events
|
39
|
+
evnts.find_all { |event| event.applies_to_version?(version) }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return all dependencies associated w/ particular version of the project
|
43
|
+
def dependencies_for_version(version)
|
44
|
+
deps = project_dependencies
|
45
|
+
deps.find_all { |dep| dep.project_version == version || dep.project_version.nil? }
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return all project_source_versions associated w/ particular version of the project
|
49
|
+
def project_source_versions_for_version(version)
|
50
|
+
psa = project_source_versions
|
51
|
+
psa.find_all { |ps| ps.project_version == version || ps.project_version.nil? }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return all sources associated w/ particular version of the project, each w/ uri formatted
|
55
|
+
# using project_source_versions source_uri_params
|
56
|
+
def sources_for_version(version)
|
57
|
+
project_source_versions_for_version(version).collect { |ps|
|
58
|
+
ps.source.format_uri!(ps.source_uri_params)
|
59
|
+
ps.source
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get the project primary source
|
64
|
+
def primary_source
|
65
|
+
ps = project_source_versions.all.find { |ps| ps.primary_source }
|
66
|
+
# TODO special case if no sources are marked as primary, grab the first ? (also in primary_source_for_version below)
|
67
|
+
return ps.nil? ? nil : ps.source
|
68
|
+
end
|
69
|
+
|
70
|
+
# Set the project primary source
|
71
|
+
def primary_source=(source)
|
72
|
+
project_source_versions << ProjectSourceVersion.new(:project => self, :source => source, :primary_source => true)
|
73
|
+
#source.save! ; save!
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return the primary source for the specified version
|
77
|
+
def primary_source_for_version(version)
|
78
|
+
ps = project_source_versions_for_version(version).find { |ps| ps.primary_source }
|
79
|
+
ps.source.format_uri!(ps.source_uri_params) unless ps.nil?
|
80
|
+
return ps.nil? ? nil : ps.source
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return all versions which we have configured this project for
|
84
|
+
def versions
|
85
|
+
# TODO should we return configured project_depents.depends_on_project_version as well ?
|
86
|
+
(project_source_versions.collect { |ps| ps.project_version } +
|
87
|
+
events.collect { |e| e.version } +
|
88
|
+
project_dependencies.collect { |d| d.project_version }).uniq - [nil]
|
89
|
+
end
|
90
|
+
|
91
|
+
# Release specified project version
|
92
|
+
def released_version(version, args = {})
|
93
|
+
# process dependencies
|
94
|
+
dependencies_for_version(version).each { |dep|
|
95
|
+
dargs = {}
|
96
|
+
dargs = dep.depends_on_project_params.to_h.merge!(args) unless dep.depends_on_project_params.nil?
|
97
|
+
|
98
|
+
# if dep_version.nil? grab all configured depends_on_project versions
|
99
|
+
dep_versions = dep.depends_on_project_version
|
100
|
+
dep_versions = dep_versions.nil? ? dep.depends_on_project.versions : [dep_versions]
|
101
|
+
|
102
|
+
dep_versions.each { |dv| dep.depends_on_project.released_version(dv, dargs) }
|
103
|
+
}
|
104
|
+
|
105
|
+
# process events
|
106
|
+
args[:version] = version
|
107
|
+
events_for_version(version).each { |event| event.run(args) }
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (C) 2010 Red Hat, Inc.
|
2
|
+
# Written by Mohammed Morsi <mmorsi@redhat.com>
|
3
|
+
#
|
4
|
+
# This program is free software, you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License
|
6
|
+
# as published by the Free Software Foundation, either version 3
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# You should have received a copy of the the GNU Affero
|
10
|
+
# General Public License, along with Polisher. If not, see
|
11
|
+
# <http://www.gnu.org/licenses/>
|
12
|
+
|
13
|
+
class ProjectDependency < ActiveRecord::Base
|
14
|
+
belongs_to :project
|
15
|
+
belongs_to :depends_on_project, :class_name => "Project", :foreign_key => "depends_on_project_id"
|
16
|
+
|
17
|
+
validates_presence_of :project_id
|
18
|
+
validates_presence_of :depends_on_project_id
|
19
|
+
|
20
|
+
validates_uniqueness_of :depends_on_project_version, :scope => [:project_id, :depends_on_project_id, :depends_on_project_version]
|
21
|
+
|
22
|
+
before_save :normalize_versions
|
23
|
+
def normalize_versions
|
24
|
+
self.project_version = nil if project_version == ""
|
25
|
+
self.depends_on_project_version = nil if depends_on_project_version == ""
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright (C) 2010 Red Hat, Inc.
|
2
|
+
# Written by Mohammed Morsi <mmorsi@redhat.com>
|
3
|
+
#
|
4
|
+
# This program is free software, you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License
|
6
|
+
# as published by the Free Software Foundation, either version 3
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# You should have received a copy of the the GNU Affero
|
10
|
+
# General Public License, along with Polisher. If not, see
|
11
|
+
# <http://www.gnu.org/licenses/>
|
12
|
+
|
13
|
+
class ProjectSourceVersion < ActiveRecord::Base
|
14
|
+
belongs_to :project
|
15
|
+
belongs_to :source
|
16
|
+
|
17
|
+
# FIXME destroy source on deletion only if no other project_source_versions sharing the source exist
|
18
|
+
|
19
|
+
validates_uniqueness_of :source_id, :scope => [:project_id, :project_version]
|
20
|
+
|
21
|
+
# validate only one primary_source set to 'true' in scope of (project_id, project_version)
|
22
|
+
validates_uniqueness_of :primary_source,
|
23
|
+
:scope => [:project_id, :project_version],
|
24
|
+
:if => Proc.new { |ps| ps.primary_source }
|
25
|
+
|
26
|
+
before_save :normalize_versions
|
27
|
+
def normalize_versions
|
28
|
+
self.project_version = nil if project_version == ""
|
29
|
+
self.source_version = nil if source_version == ""
|
30
|
+
end
|
31
|
+
end
|
data/db/models/source.rb
CHANGED
@@ -10,26 +10,92 @@
|
|
10
10
|
# General Public License, along with Polisher. If not, see
|
11
11
|
# <http://www.gnu.org/licenses/>
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
require 'curl' # requires 'curb' package
|
14
|
+
|
15
15
|
class Source < ActiveRecord::Base
|
16
|
-
|
16
|
+
# TODO on delete, destroy these
|
17
|
+
has_many :project_source_versions
|
18
|
+
has_many :projects, :through => :project_source_versions
|
19
|
+
|
20
|
+
validates_presence_of :name
|
21
|
+
validates_uniqueness_of :name
|
22
|
+
validates_presence_of :source_type
|
23
|
+
validates_presence_of :uri
|
24
|
+
validates_uniqueness_of :uri
|
25
|
+
|
26
|
+
# TODO additional source types
|
27
|
+
|
28
|
+
SOURCE_TYPES = ['archive', 'patch', 'spec', 'gem', 'file', 'git_repo']
|
29
|
+
|
30
|
+
validates_inclusion_of :source_type, :in => SOURCE_TYPES
|
31
|
+
|
32
|
+
# Extract filename of this source from path
|
33
|
+
def filename
|
34
|
+
URI::parse(uri).path.split('/').last
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return all project_source_versions associated w/ particular version of the source
|
38
|
+
def project_source_versions_for_version(version)
|
39
|
+
psa = project_source_versions
|
40
|
+
psa.find_all { |ps| ps.source_version == version || ps.source_version.nil? }
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return all projects associated w/ particular version of the source
|
44
|
+
def projects_for_version(version)
|
45
|
+
project_source_versions_for_version(version).collect { |ps| ps.project }
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return all versions which we have configured this project for
|
49
|
+
def versions
|
50
|
+
(project_source_versions.collect { |ps| ps.source_version }).uniq - [nil]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Swap any occurence of the specified hash
|
54
|
+
# keys w/ their cooresponding values in the local source uri
|
55
|
+
def format_uri!(variables)
|
56
|
+
params = {}
|
57
|
+
if variables.class == String
|
58
|
+
params = variables.to_h
|
59
|
+
elsif variables.class == Hash
|
60
|
+
params = variables
|
61
|
+
else
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
turi = uri
|
66
|
+
params.each { |k,v| turi.gsub!("%{#{k}}", v.to_s) }
|
67
|
+
uri = turi
|
68
|
+
end
|
69
|
+
|
70
|
+
# Download source, args may contain any of the following
|
71
|
+
# * :path path to download source to
|
72
|
+
# * :dir directory to download source to, filename will be generated from the last part of the uri
|
73
|
+
def download_to(args = {})
|
74
|
+
# TODO handle source_type == git_repo
|
75
|
+
|
76
|
+
path = args.has_key?(:path) ? args[:path] : nil
|
77
|
+
dir = args.has_key?(:dir) ? args[:dir] : nil
|
78
|
+
|
79
|
+
# format the uri w/ any additional params
|
80
|
+
format_uri! args
|
17
81
|
|
18
|
-
|
82
|
+
begin
|
83
|
+
# generate path which to d/l the file to
|
84
|
+
fn = filename
|
85
|
+
path = "#{dir}/#{fn}" if path.nil?
|
86
|
+
dir = File.dirname(path)
|
87
|
+
raise ArgumentError unless File.writable?(dir)
|
19
88
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
89
|
+
# d/l the file
|
90
|
+
curl = Curl::Easy.new(uri)
|
91
|
+
curl.follow_location = true # follow redirects
|
92
|
+
curl.perform
|
93
|
+
File.write path, curl.body_str
|
24
94
|
|
25
|
-
|
95
|
+
rescue Exception => e
|
96
|
+
raise RuntimeError, "could not download project source from #{uri} to #{path}"
|
97
|
+
end
|
26
98
|
|
27
|
-
|
28
|
-
# makes sure it satisfiest gem API requests
|
29
|
-
|
30
|
-
# remove trailing slash in uri if present
|
31
|
-
before_save :clean_uri!
|
32
|
-
def clean_uri!
|
33
|
-
self.uri = self.uri[0...self.uri.size-1] if self.uri[-1].chr == '/'
|
99
|
+
return path
|
34
100
|
end
|
35
101
|
end
|
data/lib/common.rb
CHANGED
@@ -12,24 +12,23 @@
|
|
12
12
|
# General Public License, along with Polisher. If not, see
|
13
13
|
# <http://www.gnu.org/licenses/>
|
14
14
|
|
15
|
-
#
|
15
|
+
# Read entire file into string
|
16
16
|
def File.read_all(path)
|
17
17
|
File.open(path, 'rb') {|file| return file.read }
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
20
|
+
# Write contents of file from string
|
21
21
|
def File.write(path, str)
|
22
22
|
File.open(path, 'wb') {|file| file.write str }
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# Create any missing directories
|
26
26
|
def create_missing_polisher_dirs(args = {})
|
27
27
|
artifacts_dir = args[:artifacts_dir]
|
28
28
|
db_data_dir = args[:db_data_dir]
|
29
29
|
log_dir = args[:log_dir]
|
30
30
|
|
31
|
-
[artifacts_dir + '/
|
32
|
-
artifacts_dir + '/repos',
|
31
|
+
[artifacts_dir + '/repos',
|
33
32
|
artifacts_dir + '/SOURCES',
|
34
33
|
artifacts_dir + '/SPECS',
|
35
34
|
artifacts_dir + '/templates',
|
@@ -37,3 +36,36 @@ def create_missing_polisher_dirs(args = {})
|
|
37
36
|
FileUtils.mkdir_p(dir) unless File.directory? dir
|
38
37
|
}
|
39
38
|
end
|
39
|
+
|
40
|
+
# Set up and return polisher config from application
|
41
|
+
def load_polisher_config(app)
|
42
|
+
config = {}
|
43
|
+
loaded_config = YAML::load(File.open(app.polisher_config))[app.environment.to_s]
|
44
|
+
config.merge!(loaded_config) unless loaded_config.nil?
|
45
|
+
|
46
|
+
# Attempt to parse gem api key from ~/.gem/credentials if missing
|
47
|
+
if config["gem_api_key"].nil?
|
48
|
+
gcfile = File.expand_path("~/.gem/credentials")
|
49
|
+
if File.exists?(gcfile)
|
50
|
+
config["gem_api_key"] = File.read_all(gcfile).scan(/:rubygems_api_key:\s(.*)/).to_s
|
51
|
+
end
|
52
|
+
end
|
53
|
+
return config
|
54
|
+
end
|
55
|
+
|
56
|
+
class String
|
57
|
+
|
58
|
+
# Parse/split string around element delimiters (;) and
|
59
|
+
# key/value delimiters (=) and convert to hash.
|
60
|
+
def to_h
|
61
|
+
ret = {}
|
62
|
+
split(';').each { |p| u = p.split('='); ret[u[0]] = u[1] }
|
63
|
+
ret
|
64
|
+
end
|
65
|
+
|
66
|
+
# Convert hash into string
|
67
|
+
def self.from_h(hash)
|
68
|
+
hash.keys.collect { |k| k.to_s + "=" + hash[k].to_s }.join(";")
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/lib/dsl.rb
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
# Polisher dsl
|
2
|
+
#
|
3
|
+
# Copyright (C) 2010 Red Hat, Inc.
|
4
|
+
# Written by Mohammed Morsi <mmorsi@redhat.com>
|
5
|
+
#
|
6
|
+
# This program is free software, you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation, either version 3
|
9
|
+
# of the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# You should have received a copy of the the GNU Affero
|
12
|
+
# General Public License, along with Polisher. If not, see
|
13
|
+
# <http://www.gnu.org/licenses/>
|
14
|
+
|
15
|
+
require 'libxml'
|
16
|
+
require 'rest_client'
|
17
|
+
|
18
|
+
module Polisher
|
19
|
+
|
20
|
+
# Helper method to handle (print) xml status response
|
21
|
+
def handle_response(operation, response, exception_on_fail = false)
|
22
|
+
rr = LibXML::XML::Document.string(response.body).root
|
23
|
+
success = rr.children.find { |c| c.name == "success" }.content.strip == "true"
|
24
|
+
msg = rr.children.find { |c| c.name == "message" }.content.strip
|
25
|
+
puts "#{operation} returned w/ success = #{success} and the message: #{msg}"
|
26
|
+
raise RuntimeError, "#{operation} returned w/ failed status: #{msg}" if exception_on_fail && !success
|
27
|
+
end
|
28
|
+
module_function :handle_response
|
29
|
+
|
30
|
+
# DSL representations of model classes (so as to not require db connection on client side)
|
31
|
+
|
32
|
+
# DSL project
|
33
|
+
class Project
|
34
|
+
# Project attributes
|
35
|
+
attr_accessor :id, :name
|
36
|
+
|
37
|
+
# Means to store project version and dependency params to be used when setting up project_source_versions and deps
|
38
|
+
attr_accessor :project_version, :dependency_params
|
39
|
+
|
40
|
+
def initialize(args = {})
|
41
|
+
args = {:id => nil, :name => nil}.merge(args)
|
42
|
+
@id = args[:id] ; @name = args[:name]
|
43
|
+
@dependency_params = {}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Add a method to project for each source type, eg add_archive, add_path, add_repo, etc.
|
47
|
+
# TODO maintain as source_types are added (or put this this in a seperate module)
|
48
|
+
# XXX ran into this when doing it metaprogramatically http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby-18/
|
49
|
+
def add_archive args = {}, █ add_source('archive', args, &block); end
|
50
|
+
def add_patch args = {}, █ add_source('patch', args, &block); end
|
51
|
+
def add_gem args = {}, █ add_source('gem', args, &block); end
|
52
|
+
def add_file args = {}, █ add_source('file', args, &block); end
|
53
|
+
|
54
|
+
def add_source type, args = {}, &block
|
55
|
+
args[:source_type] = type # automatically set the source type
|
56
|
+
src = source(args)
|
57
|
+
|
58
|
+
# Dispatch source to caller blocker to register specific project/source versions.
|
59
|
+
if !block.nil?
|
60
|
+
block.call src
|
61
|
+
|
62
|
+
# If no block is given register default */* project/source version
|
63
|
+
# TODO should this execute regardless of whether there is a block or not, eg only if no project/source versions were created/exist (need to perform a new query to get that info)
|
64
|
+
else
|
65
|
+
version nil, :corresponds_to => src
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Create Project from xml and return
|
70
|
+
def self.from_xml(xml_str)
|
71
|
+
project = Polisher::Project.new
|
72
|
+
|
73
|
+
xml = LibXML::XML::Document.string(xml_str).root
|
74
|
+
project.id = xml.children.find { |c| c.name == "id" }.content.to_i
|
75
|
+
project.name = xml.children.find { |c| c.name == "name" }.content.strip
|
76
|
+
# TODO associated versions, sources, events
|
77
|
+
#xml.children.find { |c| c.name == "version" }.children.each { |c|
|
78
|
+
#uri = c.children.find { |c| c.name == "uri"}
|
79
|
+
#project.sources << uri.content.strip unless uri.nil?
|
80
|
+
#}
|
81
|
+
|
82
|
+
return project
|
83
|
+
end
|
84
|
+
|
85
|
+
# Retrieve and return all projects
|
86
|
+
def self.all
|
87
|
+
projects = []
|
88
|
+
RestClient.get("#{$polisher_uri}/projects") { |response|
|
89
|
+
xml = LibXML::XML::Document.string(response.body).root
|
90
|
+
xml.children.find_all { |c| c.name == "project" }.each { |s|
|
91
|
+
projects << Polisher::Project.from_xml(s.to_s)
|
92
|
+
}
|
93
|
+
}
|
94
|
+
return projects
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create project
|
98
|
+
def create
|
99
|
+
RestClient.post("#{$polisher_uri}/projects/create", :name => name) { |response| Polisher.handle_response('create project', response, true) }
|
100
|
+
end
|
101
|
+
|
102
|
+
# Delete project
|
103
|
+
def delete
|
104
|
+
RestClient.delete("#{$polisher_uri}/projects/destroy/#{id}") { |response| Polisher.handle_response('delete project', response, true) }
|
105
|
+
end
|
106
|
+
|
107
|
+
# Create new Event w/ the specified version qualifier, version, process, and process options
|
108
|
+
def on_version(*args)
|
109
|
+
args.unshift nil unless ['', '=', '>', '<', '>=', '<='].include?(args[0]) # XXX don't like having to replicate entire event version qualifiers, but don't want the activerecord dependency
|
110
|
+
version_qualifier = args[0]
|
111
|
+
version = args[1]
|
112
|
+
process = args[2]
|
113
|
+
process_options = args[3]
|
114
|
+
process_options = "" if process_options.nil?
|
115
|
+
process_options += ";" + String.from_h(args[4]) if args.size == 5
|
116
|
+
|
117
|
+
process.gsub!(/\s/, '_')
|
118
|
+
|
119
|
+
RestClient.post("#{$polisher_uri}/events/create",
|
120
|
+
:project_id => id, :process => process, :version => version,
|
121
|
+
:version_qualifier => version_qualifier, :process_options => process_options) { |response| Polisher.handle_response('create event', response) }
|
122
|
+
end
|
123
|
+
|
124
|
+
# Associate specified project version w/ corresponding source version if specified,
|
125
|
+
# else if not just return self
|
126
|
+
def version(version, args = {})
|
127
|
+
version = nil if version == "*"
|
128
|
+
@project_version = version
|
129
|
+
@dependency_params = args unless args.empty?
|
130
|
+
|
131
|
+
if args.has_key?(:corresponds_to)
|
132
|
+
# dispatch to source.version so we don't have to implement twice
|
133
|
+
source = args[:corresponds_to]
|
134
|
+
source.version source.source_version, :corresponds_to => self
|
135
|
+
|
136
|
+
elsif args.has_key?(:depends_on)
|
137
|
+
project = args.delete(:depends_on)
|
138
|
+
args = project.dependency_params.merge(args) unless project.dependency_params.empty?
|
139
|
+
depends_on_args = String.from_h(args) unless args.empty?
|
140
|
+
args = {:project_id => id, :project_version => version,
|
141
|
+
:depends_on_project_id => project.id, :depends_on_project_version => project.project_version,
|
142
|
+
:depends_on_project_params => depends_on_args}
|
143
|
+
RestClient.post("#{$polisher_uri}/project_dependencies/create", args) { |response| Polisher.handle_response('created project dependency', response) }
|
144
|
+
|
145
|
+
else
|
146
|
+
return self
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Test fire project released event for specified version
|
151
|
+
def released(version, params = {})
|
152
|
+
resource = RestClient::Resource.new("#{$polisher_uri}/projects/released", :timeout => 1000) # give event handlers plenty of time to run
|
153
|
+
|
154
|
+
sparams = "name=#{name}&version=#{version}"
|
155
|
+
params.each { |k,v| sparams += "&#{k}=#{v}" }
|
156
|
+
resource.post sparams do |response|
|
157
|
+
Polisher.handle_response('released project', response)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# DSL Source
|
163
|
+
class Source
|
164
|
+
# Source attributes
|
165
|
+
attr_accessor :id, :name, :uri, :source_type
|
166
|
+
|
167
|
+
# Means to store source version and optional uri params to be used when setting up project sources
|
168
|
+
attr_accessor :source_version, :uri_args
|
169
|
+
|
170
|
+
# Means to store primary_source value when creating projects sources
|
171
|
+
attr_accessor :primary_source
|
172
|
+
|
173
|
+
def initialize(args = {})
|
174
|
+
args = { :id => nil, :name => nil, :uri => nil, :source_type => nil, :primary_source => false}.merge(args)
|
175
|
+
@id = args[:id] ; @name = args[:name] ; @uri = args[:uri] ; @source_type = args[:source_type] ; @primary_sources = args[:primary_source]
|
176
|
+
@uri_args = '' ; @primary_source = false
|
177
|
+
end
|
178
|
+
|
179
|
+
# Create Source from xml and return
|
180
|
+
def self.from_xml(xml_str)
|
181
|
+
source = Polisher::Source.new
|
182
|
+
|
183
|
+
xml = LibXML::XML::Document.string(xml_str).root
|
184
|
+
source.id = xml.children.find { |c| c.name == "id" }.content.to_i
|
185
|
+
source.name = xml.children.find { |c| c.name == "name" }.content.strip
|
186
|
+
source.uri = xml.children.find { |c| c.name == "uri" }.content.strip
|
187
|
+
source.source_type = xml.children.find { |c| c.name == "source_type" }.content.strip
|
188
|
+
# TODO associated versions, projects, events
|
189
|
+
|
190
|
+
return source
|
191
|
+
end
|
192
|
+
|
193
|
+
# Retrieve and return all sources
|
194
|
+
def self.all
|
195
|
+
sources = []
|
196
|
+
RestClient.get("#{$polisher_uri}/sources") { |response|
|
197
|
+
xml = LibXML::XML::Document.string(response.body).root
|
198
|
+
xml.children.find_all { |c| c.name == "source" }.each { |s|
|
199
|
+
sources << Polisher::Source.from_xml(s.to_s)
|
200
|
+
}
|
201
|
+
}
|
202
|
+
return sources
|
203
|
+
end
|
204
|
+
|
205
|
+
# Create source
|
206
|
+
def create
|
207
|
+
RestClient.post("#{$polisher_uri}/sources/create", :name => name, :uri => uri, :source_type => source_type) { |response| Polisher.handle_response('create project', response, true) }
|
208
|
+
end
|
209
|
+
|
210
|
+
# Associate specified project source w/ corresponding source version if specified,
|
211
|
+
# else if not just return self
|
212
|
+
def version(version, args = {})
|
213
|
+
version = nil if version == "*"
|
214
|
+
project = args.delete(:corresponds_to)
|
215
|
+
|
216
|
+
@uri_args = String.from_h(args) unless args.empty?
|
217
|
+
|
218
|
+
if project.nil?
|
219
|
+
@source_version = version
|
220
|
+
return self
|
221
|
+
end
|
222
|
+
|
223
|
+
args = {:project_id => project.id, :project_version => project.project_version,
|
224
|
+
:source_id => id, :source_version => version, :source_uri_params => @uri_args,
|
225
|
+
:primary_source => @primary_source }
|
226
|
+
RestClient.post("#{$polisher_uri}/project_source_versions/create", args) { |response| Polisher.handle_response('created project source', response) }
|
227
|
+
end
|
228
|
+
|
229
|
+
# Set source as primary in project/source associations
|
230
|
+
def is_the_primary_source
|
231
|
+
@primary_source = true
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
end # module Polisher
|
236
|
+
|
237
|
+
# Set polisher uri for all connections
|
238
|
+
def polisher(uri)
|
239
|
+
# XXX do this better
|
240
|
+
$polisher_uri = uri
|
241
|
+
end
|
242
|
+
|
243
|
+
# Retrieve list of all projects, invoking yield w/ each, before returning the list
|
244
|
+
def projects
|
245
|
+
projects = Polisher::Project.all
|
246
|
+
projects.each { |project| yield project if block_given? }
|
247
|
+
return projects
|
248
|
+
end
|
249
|
+
|
250
|
+
# Find or create new project w/ specified args
|
251
|
+
def project(args = {})
|
252
|
+
projects { |project|
|
253
|
+
project = nil if (args.has_key?(:name) && args[:name] != project.name) ||
|
254
|
+
(args.has_key?(:id) && args[:id] != project.id)
|
255
|
+
unless project.nil?
|
256
|
+
yield project if block_given?
|
257
|
+
return project
|
258
|
+
end
|
259
|
+
}
|
260
|
+
proj = Polisher::Project.new args
|
261
|
+
proj.create
|
262
|
+
proj = project(args)
|
263
|
+
yield proj if block_given?
|
264
|
+
return proj
|
265
|
+
end
|
266
|
+
|
267
|
+
# Retrieve list of all sources, invoking yield w/ each, before returning the list
|
268
|
+
def sources
|
269
|
+
sources = Polisher::Source.all
|
270
|
+
sources.each { |source| yield source if block_given? }
|
271
|
+
return sources
|
272
|
+
end
|
273
|
+
|
274
|
+
# Find or create new source w/ specified args
|
275
|
+
def source(args = {})
|
276
|
+
sources { |src|
|
277
|
+
src = nil if (args.has_key?(:name) && args[:name] != src.name) ||
|
278
|
+
(args.has_key?(:id) && args[:id] != src.id) ||
|
279
|
+
(args.has_key?(:source_type) && args[:source_type] != src.source_type) ||
|
280
|
+
(args.has_key?(:uri) && args[:uri] != src.uri)
|
281
|
+
unless src.nil?
|
282
|
+
yield src if block_given?
|
283
|
+
return src
|
284
|
+
end
|
285
|
+
}
|
286
|
+
src = Polisher::Source.new args
|
287
|
+
src.create
|
288
|
+
src = source(args)
|
289
|
+
src.primary_source = args[:primary_source] if args.has_key?(:primary_source) # XXX ugly hack
|
290
|
+
yield src if block_given?
|
291
|
+
return src
|
292
|
+
end
|