pkg-wizard 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/bin/pkgwiz +24 -0
- data/lib/pkg-wizard/command.rb +42 -0
- data/lib/pkg-wizard/commands/build_bot.rb +108 -0
- data/lib/pkg-wizard/commands/create_srpm.rb +89 -0
- data/lib/pkg-wizard/commands/remote_build.rb +113 -0
- data/lib/pkg-wizard/git.rb +17 -0
- data/lib/pkg-wizard/logger.rb +21 -0
- data/lib/pkg-wizard/mock.rb +45 -0
- data/lib/pkg-wizard/rpm.rb +63 -0
- data/lib/pkg-wizard/streaming_downloader.rb +62 -0
- data/lib/pkg-wizard/streaming_uploader.rb +145 -0
- data/lib/pkg-wizard.rb +65 -0
- data/packages/epel-release-5-4.noarch.rpm +0 -0
- data/packages/epel-release-6-5.noarch.rpm +0 -0
- metadata +216 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "bundler", "~> 1.0.0"
|
10
|
+
gem "jeweler", "~> 1.5.2"
|
11
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Sergio Rubio
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= pkg-wizard
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to pkg-wizard
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 Sergio Rubio. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "pkg-wizard"
|
16
|
+
gem.version = File.read 'VERSION'
|
17
|
+
gem.homepage = "http://github.com/rubiojr/pkg-wizard"
|
18
|
+
gem.license = "MIT"
|
19
|
+
gem.summary = %Q{Package Wizards Tools}
|
20
|
+
gem.description = %Q{Tools to manage,create and build distribution packages}
|
21
|
+
gem.email = "rubiojr@frameos.org"
|
22
|
+
gem.authors = ["Sergio Rubio"]
|
23
|
+
gem.add_runtime_dependency 'SystemTimer'
|
24
|
+
gem.add_runtime_dependency 'resque'
|
25
|
+
gem.add_runtime_dependency 'git'
|
26
|
+
gem.add_runtime_dependency 'sinatra'
|
27
|
+
gem.add_runtime_dependency 'thin'
|
28
|
+
gem.add_runtime_dependency 'rufus-scheduler'
|
29
|
+
gem.add_runtime_dependency 'term-ansicolor'
|
30
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
31
|
+
end
|
32
|
+
Jeweler::RubygemsDotOrgTasks.new
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
37
|
+
|
38
|
+
rdoc.rdoc_dir = 'rdoc'
|
39
|
+
rdoc.title = "pkg-wizard #{version}"
|
40
|
+
rdoc.rdoc_files.include('README*')
|
41
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
42
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.2
|
data/bin/pkgwiz
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
$: << File.join(File.dirname(__FILE__), "/../lib/")
|
5
|
+
|
6
|
+
require 'pkg-wizard'
|
7
|
+
require 'pkg-wizard/logger'
|
8
|
+
include PKGWizard
|
9
|
+
|
10
|
+
log = PKGWizard::Logger.instance
|
11
|
+
|
12
|
+
DEFAULT_SUBCOMMAND_FILES = Dir[File.expand_path(File.join(File.dirname(__FILE__), '/../lib/pkg-wizard/commands/', '*.rb'))]
|
13
|
+
DEFAULT_SUBCOMMAND_REGISTRY =
|
14
|
+
|
15
|
+
DEFAULT_SUBCOMMAND_FILES.each do |sc|
|
16
|
+
require sc
|
17
|
+
end
|
18
|
+
|
19
|
+
Command.registry
|
20
|
+
#begin
|
21
|
+
Command.new.run(ARGV)
|
22
|
+
#rescue Exception => e
|
23
|
+
# puts "\n#{e.message}\n\n" if not e.is_a?(SystemExit)
|
24
|
+
#end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PKGWizard
|
2
|
+
class Command
|
3
|
+
include ::Mixlib::CLI
|
4
|
+
|
5
|
+
option :help,
|
6
|
+
:short => "-h",
|
7
|
+
:long => "--help",
|
8
|
+
:description => "Show this message",
|
9
|
+
:on => :tail,
|
10
|
+
:boolean => true,
|
11
|
+
:show_options => true,
|
12
|
+
:exit => 0
|
13
|
+
|
14
|
+
def self.registry
|
15
|
+
@@registry ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def run(argv)
|
19
|
+
@@argv = argv
|
20
|
+
cmd = argv.shift
|
21
|
+
found = false
|
22
|
+
@@registry.each do |c|
|
23
|
+
if c[:name] == cmd
|
24
|
+
c[:klass].perform
|
25
|
+
found = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
if not found
|
29
|
+
puts
|
30
|
+
puts "USAGE: #{File.basename($0)} command [options]"
|
31
|
+
puts
|
32
|
+
puts "Available Commands:"
|
33
|
+
puts
|
34
|
+
@@registry.each do |c|
|
35
|
+
puts c[:name]
|
36
|
+
end
|
37
|
+
puts
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'pkg-wizard/command'
|
2
|
+
require 'pkg-wizard/rpm'
|
3
|
+
require 'pkg-wizard/logger'
|
4
|
+
require 'pkg-wizard/git'
|
5
|
+
require 'pkg-wizard/mock'
|
6
|
+
require 'tmpdir'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'uri'
|
9
|
+
require 'sinatra/base'
|
10
|
+
require 'rufus/scheduler'
|
11
|
+
require 'term/ansicolor'
|
12
|
+
require 'pp'
|
13
|
+
require 'yaml'
|
14
|
+
|
15
|
+
class String
|
16
|
+
include Term::ANSIColor
|
17
|
+
end
|
18
|
+
|
19
|
+
module PKGWizard
|
20
|
+
class BuildBot < Command
|
21
|
+
|
22
|
+
registry << { :name => 'build-bot', :klass => self }
|
23
|
+
|
24
|
+
option :help,
|
25
|
+
:short => "-h",
|
26
|
+
:long => "--help",
|
27
|
+
:description => "Show this message",
|
28
|
+
:on => :tail,
|
29
|
+
:boolean => true,
|
30
|
+
:show_options => true,
|
31
|
+
:exit => 0
|
32
|
+
|
33
|
+
option :mock_profile,
|
34
|
+
:short => '-m PROF',
|
35
|
+
:long => '--mock-profile PROF'
|
36
|
+
|
37
|
+
class Webapp < Sinatra::Base
|
38
|
+
post '/build/' do
|
39
|
+
pkg = params[:pkg]
|
40
|
+
if pkg.nil?
|
41
|
+
Logger.instance.error '400: Invalid arguments. Needs pkg in post request'
|
42
|
+
status 400
|
43
|
+
"Missing pkg parameter.\n"
|
44
|
+
else
|
45
|
+
incoming_file = "incoming/#{pkg[:filename]}"
|
46
|
+
$stdout.puts "Incoming file".ljust(40).bold.yellow + "#{pkg[:filename]}"
|
47
|
+
FileUtils.cp pkg[:tempfile].path, incoming_file
|
48
|
+
$stdout.puts "File saved".ljust(40).green.bold + "#{pkg[:filename]}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.perform
|
55
|
+
cli = BuildBot.new
|
56
|
+
cli.banner = "\nUsage: rpmwiz build-bot (options)\n\n"
|
57
|
+
cli.parse_options
|
58
|
+
mock_profile = cli.config[:mock_profile]
|
59
|
+
if not mock_profile
|
60
|
+
$stderr.puts 'Invalid mock profile.'
|
61
|
+
$stderr.puts cli.opt_parser.help
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
meta = { :mock_profile => mock_profile }
|
65
|
+
|
66
|
+
Dir.mkdir 'incoming' if not File.exist?('incoming')
|
67
|
+
Dir.mkdir 'output' if not File.exist?('output')
|
68
|
+
Dir.mkdir 'workspace' if not File.exist?('workspace')
|
69
|
+
scheduler = Rufus::Scheduler.start_new
|
70
|
+
scheduler.every '2s', :blocking => true do
|
71
|
+
meta[:start_time] = Time.now
|
72
|
+
queue = Dir['incoming/*.src.rpm'].sort_by {|filename| File.mtime(filename) }
|
73
|
+
if not queue.empty?
|
74
|
+
job_time = Time.now.strftime '%Y%m%d_%H%M%S'
|
75
|
+
$stdout.puts "Job accepted [#{queue.size} Queued]".ljust(40).blue.bold + job_time
|
76
|
+
job_dir = "workspace/job_#{Time.now.strftime '%Y%m%d_%H%M%S'}"
|
77
|
+
result_dir = job_dir + '/result'
|
78
|
+
FileUtils.mkdir_p result_dir
|
79
|
+
meta[:source] = File.basename(queue.first)
|
80
|
+
qfile = File.join(job_dir, File.basename(queue.first))
|
81
|
+
FileUtils.mv queue.first, qfile
|
82
|
+
$stdout.puts "Building pkg [#{job_time}]".ljust(40).yellow.bold + "#{File.basename(qfile)}"
|
83
|
+
|
84
|
+
begin
|
85
|
+
PKGWizard::Mock.srpm :srpm => qfile, :profile => mock_profile, :resultdir => result_dir
|
86
|
+
meta[:status] = 'ok'
|
87
|
+
$stdout.puts "Finished building [#{job_time}]".ljust(40).green.bold + "#{File.basename(qfile)}"
|
88
|
+
rescue Exception => e
|
89
|
+
meta[:status] = 'error'
|
90
|
+
$stdout.puts "Job failed [#{job_time}]".ljust(40).red.bold
|
91
|
+
File.open(job_dir + '/buildbot.log', 'w') do |f|
|
92
|
+
f.puts "#{e.backtrace.join("\n")}"
|
93
|
+
f.puts "#{e.message}"
|
94
|
+
end
|
95
|
+
ensure
|
96
|
+
meta[:endtime] = Time.now
|
97
|
+
File.open(job_dir + '/meta.yml', 'w') do |f|
|
98
|
+
f.puts meta.to_yaml
|
99
|
+
end
|
100
|
+
FileUtils.mv job_dir, 'output/'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
Webapp.run!
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'pkg-wizard/command'
|
2
|
+
require 'pkg-wizard/rpm'
|
3
|
+
require 'pkg-wizard/logger'
|
4
|
+
require 'pkg-wizard/git'
|
5
|
+
require 'tmpdir'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
module PKGWizard
|
10
|
+
class CreateSrpm < Command
|
11
|
+
registry << { :name => 'create-srpm', :klass => self }
|
12
|
+
|
13
|
+
option :help,
|
14
|
+
:short => "-h",
|
15
|
+
:long => "--help",
|
16
|
+
:description => "Show this message",
|
17
|
+
:on => :tail,
|
18
|
+
:boolean => true,
|
19
|
+
:show_options => true,
|
20
|
+
:exit => 0
|
21
|
+
|
22
|
+
option :gitrepo,
|
23
|
+
:short => '-g REPO',
|
24
|
+
:long => '--gitrepo REPO',
|
25
|
+
:description => 'Git repo URL to fetch the package sources from'
|
26
|
+
|
27
|
+
option :workspace,
|
28
|
+
:short => '-w DIR',
|
29
|
+
:long => '--workspace DIR',
|
30
|
+
:description => 'Git repo URL to fetch the package sources from'
|
31
|
+
|
32
|
+
option :resultdir,
|
33
|
+
:short => '-r DIR',
|
34
|
+
:long => '--resultdir DIR',
|
35
|
+
:description => 'Path for resulting files to be put'
|
36
|
+
|
37
|
+
def self.perform
|
38
|
+
cmd = CreateSrpm.new
|
39
|
+
cmd.banner = "\nUsage: rpmwiz create-srpm (options)\n\n"
|
40
|
+
cmd.parse_options
|
41
|
+
repo = cmd.config[:gitrepo]
|
42
|
+
workspace = cmd.config[:workspace] || "/tmp/rpmwiz-#{Time.now.to_i}"
|
43
|
+
FileUtils.mkdir_p(workspace) if not File.exist?(workspace)
|
44
|
+
source_dir = workspace + '/SOURCES'
|
45
|
+
|
46
|
+
resultdir = cmd.config[:resultdir] || workspace + '/SRPMS'
|
47
|
+
if not File.exist?(resultdir)
|
48
|
+
Dir.mkdir(resultdir)
|
49
|
+
end
|
50
|
+
|
51
|
+
if not File.exist?(resultdir)
|
52
|
+
raise Exception.new("resultdir #{resultdir} does not exist.")
|
53
|
+
end
|
54
|
+
if repo
|
55
|
+
begin
|
56
|
+
repo_name = URI.parse(repo).path.split('/').last.gsub(/\.git$/,'')
|
57
|
+
rescue Exception => e
|
58
|
+
raise Exception.new('Invalid Git repo URL')
|
59
|
+
end
|
60
|
+
repo_dir = File.join(source_dir, repo_name)
|
61
|
+
if not File.exist?(repo_dir)
|
62
|
+
FileUtils.mkdir_p repo_dir
|
63
|
+
end
|
64
|
+
GitRPM.fetch(repo, repo_dir)
|
65
|
+
pwd = Dir.pwd
|
66
|
+
Dir.chdir repo_dir
|
67
|
+
output = SRPM.create
|
68
|
+
# FIXME
|
69
|
+
# This is dangerous but SRPM.create does not return
|
70
|
+
# the full filename
|
71
|
+
pkg = output
|
72
|
+
basename = File.basename(pkg)
|
73
|
+
Dir.chdir pwd
|
74
|
+
FileUtils.cp pkg, resultdir
|
75
|
+
$stdout.puts "SRPM created: #{resultdir}/#{basename}"
|
76
|
+
else
|
77
|
+
output = SRPM.create
|
78
|
+
# FIXME
|
79
|
+
# This is dangerous but SRPM.create does not return
|
80
|
+
# the full filename
|
81
|
+
pkg = output
|
82
|
+
basename = File.basename(pkg)
|
83
|
+
FileUtils.cp pkg, resultdir
|
84
|
+
$stdout.puts "SRPM created: #{resultdir}/#{basename}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'pkg-wizard/command'
|
2
|
+
require 'pkg-wizard/logger'
|
3
|
+
require 'pkg-wizard/streaming_downloader'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'uri'
|
7
|
+
require 'term/ansicolor'
|
8
|
+
require 'pkg-wizard/streaming_uploader'
|
9
|
+
require 'pp'
|
10
|
+
|
11
|
+
class String
|
12
|
+
include Term::ANSIColor
|
13
|
+
end
|
14
|
+
|
15
|
+
module PKGWizard
|
16
|
+
class RemoteBuild < Command
|
17
|
+
|
18
|
+
registry << { :name => 'remote-build', :klass => self }
|
19
|
+
|
20
|
+
option :help,
|
21
|
+
:short => "-h",
|
22
|
+
:long => "--help",
|
23
|
+
:description => "Show this message",
|
24
|
+
:on => :tail,
|
25
|
+
:boolean => true,
|
26
|
+
:show_options => true,
|
27
|
+
:exit => 0
|
28
|
+
|
29
|
+
option :buildbot,
|
30
|
+
:short => '-b URL',
|
31
|
+
:description => 'rpmwiz build-bot URL',
|
32
|
+
:long => '--buildbot URL'
|
33
|
+
|
34
|
+
option :tmpdir,
|
35
|
+
:short => '-t TEMP',
|
36
|
+
:long => '--tmpdir TEMP',
|
37
|
+
:description => 'Directory for downloaded files to be put',
|
38
|
+
:default => '/tmp'
|
39
|
+
|
40
|
+
def self.perform
|
41
|
+
cli = RemoteBuild.new
|
42
|
+
cli.banner = "\nUsage: rpmwiz remote-build (options)\n\n"
|
43
|
+
pkgs = cli.parse_options
|
44
|
+
bbot_url = cli.config[:buildbot]
|
45
|
+
if bbot_url.nil?
|
46
|
+
$stderr.puts "\n--buildbot is required.\n"
|
47
|
+
puts cli.opt_parser.help
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
downloaded_pkgs = []
|
51
|
+
pkgs.reject! do |p|
|
52
|
+
if p =~ /http:\/\//
|
53
|
+
pkg = URI.parse(p).path.split("/").last
|
54
|
+
$stdout.puts "Downloading #{pkg}..."
|
55
|
+
downloaded_pkgs << download_from_url(p,cli.config[:tmpdir])
|
56
|
+
true
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
pkgs += downloaded_pkgs
|
62
|
+
|
63
|
+
#
|
64
|
+
# If no packages are specified, we assume we need to create
|
65
|
+
# and SRPM from current dir
|
66
|
+
#
|
67
|
+
created_srpms = []
|
68
|
+
if pkgs.empty? and Dir["*.spec"].size > 0
|
69
|
+
spec = Dir["*.spec"].first
|
70
|
+
$stdout.puts "Creating SRPM for #{spec}..."
|
71
|
+
srpm = SRPM.create
|
72
|
+
created_srpms << srpm
|
73
|
+
end
|
74
|
+
pkgs += created_srpms
|
75
|
+
|
76
|
+
# We need this to show the progress percentage
|
77
|
+
if pkgs.empty?
|
78
|
+
$stderr.puts "\nNo packages found.\n\n"
|
79
|
+
puts cli.opt_parser.help
|
80
|
+
exit 1
|
81
|
+
end
|
82
|
+
pkgs.each do |pkg|
|
83
|
+
fo = File.new(pkg)
|
84
|
+
fsize = File.size(pkg)
|
85
|
+
count = 0
|
86
|
+
$stdout.sync = true
|
87
|
+
line_reset = "\r\e[0K"
|
88
|
+
res = StreamingUploader.post(
|
89
|
+
bbot_url + '/build/',
|
90
|
+
{ 'pkg' => fo }
|
91
|
+
) do |size|
|
92
|
+
count += size
|
93
|
+
per = (100*count)/fsize
|
94
|
+
if per %10 == 0
|
95
|
+
print "#{line_reset}Uploading:".ljust(40) + "#{(100*count)/fsize}% "
|
96
|
+
end
|
97
|
+
end
|
98
|
+
#puts "#{line_reset}Uploading: #{File.basename(pkg).gsub(/-((\d|\.)*)-(.*)\.src\.rpm/,'')} ".ljust(40) + "#{(100*count)/fsize}% [COMPLETE]"
|
99
|
+
puts "#{line_reset}Uploading: #{File.basename(pkg)} ".ljust(40) + "#{(100*count)/fsize}% [COMPLETE]"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.download_from_url(url, tmpdir = '/tmp')
|
104
|
+
uri = URI.parse(url)
|
105
|
+
remote_pkg = uri.path.split('/').last
|
106
|
+
d = StreamingDownloader.new
|
107
|
+
f = "#{tmpdir}/#{remote_pkg}"
|
108
|
+
d.download!(url, File.new(f, 'w'))
|
109
|
+
f
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'delegate'
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module PKGWizard
|
6
|
+
OriginalLogger = Logger
|
7
|
+
class Logger < SimpleDelegator
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@logger = OriginalLogger.new(STDOUT)
|
12
|
+
super @logger
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_output(log_device)
|
17
|
+
@logger = OriginalLogger.new(log_device)
|
18
|
+
__setobj__(@logger)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module PKGWizard
|
2
|
+
class Mock
|
3
|
+
|
4
|
+
#
|
5
|
+
# mandatory args
|
6
|
+
# :profile
|
7
|
+
# :resultdir
|
8
|
+
# :srpm
|
9
|
+
#
|
10
|
+
def self.srpm(args = {})
|
11
|
+
mock_profile = args[:profile]
|
12
|
+
result_dir = args[:resultdir]
|
13
|
+
srpm = args[:srpm]
|
14
|
+
mock_args = args[:mock_args] || ""
|
15
|
+
|
16
|
+
raise ArgumentError.new('Invalid mock profile') if mock_profile.nil?
|
17
|
+
|
18
|
+
if not File.exist?(srpm) or (srpm !~ /src\.rpm$/)
|
19
|
+
raise ArgumentError.new('Invalid SRPM')
|
20
|
+
end
|
21
|
+
|
22
|
+
raise ArgumentError.new('Invalid result dir') if result_dir.nil?
|
23
|
+
|
24
|
+
|
25
|
+
if mock_profile.nil?
|
26
|
+
raise Exception.new "Missing mock profile."
|
27
|
+
end
|
28
|
+
|
29
|
+
if result_dir.nil?
|
30
|
+
raise Exception.new "Missing result_dir."
|
31
|
+
end
|
32
|
+
|
33
|
+
if not File.directory?(result_dir)
|
34
|
+
raise Exception.new "Invalid result_dir #{result_dir}"
|
35
|
+
end
|
36
|
+
|
37
|
+
cmd = "/usr/bin/mock #{mock_args} -r #{mock_profile} --disable-plugin ccache --resultdir #{result_dir} #{srpm}"
|
38
|
+
output = `#{cmd} 2>&1`
|
39
|
+
if $? != 0
|
40
|
+
raise Exception.new(output)
|
41
|
+
end
|
42
|
+
output
|
43
|
+
end
|
44
|
+
end # class
|
45
|
+
end # mod
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module PKGWizard
|
2
|
+
class NoSpecFound < Exception; end
|
3
|
+
class RPMBuildError < Exception; end
|
4
|
+
|
5
|
+
class RPM
|
6
|
+
end
|
7
|
+
|
8
|
+
class SpecFile
|
9
|
+
attr_accessor :name, :release, :version
|
10
|
+
|
11
|
+
def self.parse(file)
|
12
|
+
f = File.read(file)
|
13
|
+
spec = SpecFile.new
|
14
|
+
spec.name = f.match(/Name:(.*?)$/)[1].strip.chomp
|
15
|
+
spec.version = f.match(/Version:(.*?)$/)[1].strip.chomp
|
16
|
+
spec.release = f.match(/Release:(.*?)$/)[1].strip.chomp.gsub(/%\{\?.*\}/, '')
|
17
|
+
spec
|
18
|
+
end
|
19
|
+
|
20
|
+
def pkgname
|
21
|
+
"#{name}-#{version}-#{release}"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class SRPM
|
27
|
+
#
|
28
|
+
# params
|
29
|
+
# rpmbuild_dir: _topdir macro
|
30
|
+
# macros: macros string
|
31
|
+
#
|
32
|
+
def self.create(params = {})
|
33
|
+
rpmbuild_dir = params[:rpmbuild_dir] || "#{ENV['HOME']}/rpmbuild/"
|
34
|
+
macros = params[:macros] || ''
|
35
|
+
rhel5_compat = params[:rhel5_compat] || false
|
36
|
+
specs = Dir["*.spec"]
|
37
|
+
raise NoSpecFound.new 'No spec found in current dir' if specs.empty?
|
38
|
+
pkg_name = File.read(specs.first).match(/Name:(.*?)$/)[1].strip.chomp
|
39
|
+
pkg_ver = File.read(specs.first).match(/Version:(.*?)$/)[1].strip.chomp
|
40
|
+
pkg_release = File.read(specs.first).match(/Release:(.*?)$/)[1].strip.chomp.gsub(/%\{\?.*\}/, '')
|
41
|
+
pkg_full_name = "#{pkg_name}-#{pkg_ver}-#{pkg_release}"
|
42
|
+
%w(SOURCES SRPMS SPECS BUILDROOT RPMS BUILD).each do |d|
|
43
|
+
Dir.mkdir File.join(File.expand_path(rpmbuild_dir), d) if not File.exist?(File.join(rpmbuild_dir, d))
|
44
|
+
end
|
45
|
+
Dir['*'].each do |f|
|
46
|
+
FileUtils.cp(f, "#{rpmbuild_dir}/SOURCES") if not File.directory?(f)
|
47
|
+
end
|
48
|
+
macros << " --define '_topdir #{rpmbuild_dir}'"
|
49
|
+
if rhel5_compat
|
50
|
+
macros << ' --define "_source_filedigest_algorithm 0" --define "_binary_filedigest_algorithm 0"'
|
51
|
+
end
|
52
|
+
output = `rpmbuild --nodeps -bs *.spec #{macros} 2>&1`
|
53
|
+
resulting_pkg = ''
|
54
|
+
output.each_line do |l|
|
55
|
+
if l =~ /Wrote:/
|
56
|
+
resulting_pkg = l.gsub('Wrote: ', '').strip.chomp
|
57
|
+
end
|
58
|
+
end
|
59
|
+
raise RPMBuildError.new(output) if $? != 0
|
60
|
+
resulting_pkg
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module PKGWizard
|
2
|
+
|
3
|
+
#
|
4
|
+
# StreamingDownloader code based on HTTPDownloader
|
5
|
+
# code from http://www.vagrantup.com
|
6
|
+
#
|
7
|
+
class StreamingDownloader
|
8
|
+
def self.match?(uri)
|
9
|
+
# URI.parse barfs on '<drive letter>:\\files \on\ windows'
|
10
|
+
extracted = URI.extract(uri).first
|
11
|
+
extracted && extracted.include?(uri)
|
12
|
+
end
|
13
|
+
|
14
|
+
def report_progress(progress, total, show_parts=true)
|
15
|
+
line_reset = "\r\e[0K"
|
16
|
+
percent = (progress.to_f / total.to_f) * 100
|
17
|
+
line = "Progress: #{percent.to_i}%"
|
18
|
+
line << " (#{progress} / #{total})" if show_parts
|
19
|
+
line = "#{line_reset}#{line}"
|
20
|
+
$stdout.sync = true
|
21
|
+
$stdout.print line
|
22
|
+
end
|
23
|
+
|
24
|
+
def download!(source_url, destination_file)
|
25
|
+
proxy_uri = URI.parse(ENV["http_proxy"] || "")
|
26
|
+
uri = URI.parse(source_url)
|
27
|
+
http = Net::HTTP.new(uri.host, uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
|
28
|
+
|
29
|
+
if uri.scheme == "https"
|
30
|
+
http.use_ssl = true
|
31
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
32
|
+
end
|
33
|
+
|
34
|
+
http.start do |h|
|
35
|
+
h.request_get(uri.request_uri) do |response|
|
36
|
+
total = response.content_length
|
37
|
+
progress = 0
|
38
|
+
segment_count = 0
|
39
|
+
|
40
|
+
response.read_body do |segment|
|
41
|
+
# Report the progress out
|
42
|
+
progress += segment.length
|
43
|
+
segment_count += 1
|
44
|
+
|
45
|
+
# Progress reporting is limited to every 25 segments just so
|
46
|
+
# we're not constantly updating
|
47
|
+
if segment_count % 25 == 0
|
48
|
+
report_progress(progress, total)
|
49
|
+
segment_count = 0
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Store the segment
|
54
|
+
destination_file.write(segment)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
rescue SocketError
|
59
|
+
raise Errors::DownloaderHTTPSocketError.new
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# StreamingUploader Adapted by Sergio Rubio <srubio@abiquo.com> for Abiquo
|
2
|
+
#
|
3
|
+
# inspired by Opscode Chef StreamingCookbookUploader chef/streaming_cookbook_uploader.rb
|
4
|
+
# http://opscode.com
|
5
|
+
#
|
6
|
+
# inspired by/cargo-culted from http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html
|
7
|
+
# On Apr 6, 2010, at 3:00 PM, Stanislav Vitvitskiy wrote:
|
8
|
+
#
|
9
|
+
# It's free to use / modify / distribute. No need to mention anything. Just copy/paste and use.
|
10
|
+
#
|
11
|
+
# Regards,
|
12
|
+
# Stan
|
13
|
+
|
14
|
+
require 'net/http'
|
15
|
+
|
16
|
+
module PKGWizard
|
17
|
+
|
18
|
+
class StreamingUploader
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
def post(to_url, params = {}, &block)
|
23
|
+
boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
|
24
|
+
parts = []
|
25
|
+
content_file = nil
|
26
|
+
|
27
|
+
unless params.nil? || params.empty?
|
28
|
+
params.each do |key, value|
|
29
|
+
if value.kind_of?(File)
|
30
|
+
content_file = value
|
31
|
+
filepath = value.path
|
32
|
+
filename = File.basename(filepath)
|
33
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
34
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
|
35
|
+
"Content-Type: application/octet-stream\r\n\r\n")
|
36
|
+
parts << StreamPart.new(value, File.size(filepath))
|
37
|
+
parts << StringPart.new("\r\n")
|
38
|
+
else
|
39
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
40
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
|
41
|
+
parts << StringPart.new(value.to_s + "\r\n")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
parts << StringPart.new("--" + boundary + "--\r\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
body_stream = MultipartStream.new(parts, block)
|
48
|
+
|
49
|
+
url = URI.parse(to_url)
|
50
|
+
|
51
|
+
headers = { 'accept' => 'application/json' }
|
52
|
+
|
53
|
+
req = Net::HTTP::Post.new(url.path)
|
54
|
+
req.content_length = body_stream.size
|
55
|
+
req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty?
|
56
|
+
req.body_stream = body_stream
|
57
|
+
|
58
|
+
http = Net::HTTP.new(url.host, url.port)
|
59
|
+
res = http.request(req)
|
60
|
+
#res = http.start {|http_proc| http_proc.request(req) }
|
61
|
+
|
62
|
+
res
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class StreamPart
|
68
|
+
def initialize(stream, size)
|
69
|
+
@stream, @size = stream, size
|
70
|
+
end
|
71
|
+
|
72
|
+
def size
|
73
|
+
@size
|
74
|
+
end
|
75
|
+
|
76
|
+
# read the specified amount from the stream
|
77
|
+
def read(offset, how_much)
|
78
|
+
@stream.read(how_much)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class StringPart
|
83
|
+
def initialize(str)
|
84
|
+
@str = str
|
85
|
+
end
|
86
|
+
|
87
|
+
def size
|
88
|
+
@str.length
|
89
|
+
end
|
90
|
+
|
91
|
+
# read the specified amount from the string startiung at the offset
|
92
|
+
def read(offset, how_much)
|
93
|
+
@str[offset, how_much]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class MultipartStream
|
98
|
+
def initialize(parts, blk = nil)
|
99
|
+
@callback = nil
|
100
|
+
if blk
|
101
|
+
@callback = blk
|
102
|
+
end
|
103
|
+
@parts = parts
|
104
|
+
@part_no = 0
|
105
|
+
@part_offset = 0
|
106
|
+
end
|
107
|
+
|
108
|
+
def size
|
109
|
+
@parts.inject(0) {|size, part| size + part.size}
|
110
|
+
end
|
111
|
+
|
112
|
+
def read(how_much)
|
113
|
+
@callback.call(how_much) if @callback
|
114
|
+
return nil if @part_no >= @parts.size
|
115
|
+
|
116
|
+
how_much_current_part = @parts[@part_no].size - @part_offset
|
117
|
+
|
118
|
+
how_much_current_part = if how_much_current_part > how_much
|
119
|
+
how_much
|
120
|
+
else
|
121
|
+
how_much_current_part
|
122
|
+
end
|
123
|
+
|
124
|
+
how_much_next_part = how_much - how_much_current_part
|
125
|
+
|
126
|
+
current_part = @parts[@part_no].read(@part_offset, how_much_current_part)
|
127
|
+
|
128
|
+
# recurse into the next part if the current one was not large enough
|
129
|
+
if how_much_next_part > 0
|
130
|
+
@part_no += 1
|
131
|
+
@part_offset = 0
|
132
|
+
next_part = read(how_much_next_part)
|
133
|
+
current_part + if next_part
|
134
|
+
next_part
|
135
|
+
else
|
136
|
+
''
|
137
|
+
end
|
138
|
+
else
|
139
|
+
@part_offset += how_much_current_part
|
140
|
+
current_part
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/pkg-wizard.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'mixlib/cli'
|
4
|
+
|
5
|
+
module PKGWizard
|
6
|
+
|
7
|
+
class Distribution
|
8
|
+
def self.detect
|
9
|
+
if File.exist?('/etc/redhat-release') and \
|
10
|
+
File.read('/etc/redhat-release') =~ /Fedora/
|
11
|
+
return Fedora.new
|
12
|
+
end
|
13
|
+
if File.exist?('/etc/redhat-release') and \
|
14
|
+
File.read('/etc/redhat-release') =~ /FrameOS|RedHat|CentOS/
|
15
|
+
return RedHat.new
|
16
|
+
end
|
17
|
+
if `lsb_release -i` =~ /Ubuntu/
|
18
|
+
return Ubuntu.new
|
19
|
+
end
|
20
|
+
return UnknownDistro.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class UnknownDistro
|
25
|
+
def prepare_env
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
'unknown'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Ubuntu
|
34
|
+
def prepare_env
|
35
|
+
end
|
36
|
+
def to_s
|
37
|
+
'ubuntu'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class RedHat
|
42
|
+
def prepare_env
|
43
|
+
if `uname -r` =~ /\.el6\./
|
44
|
+
else
|
45
|
+
raise UnsupportedDistribution.new('Unsupported RHEL distribution')
|
46
|
+
end
|
47
|
+
output = `yum install createrepo yum-utils rsync git rpmdevtools wget mock 2>&1`
|
48
|
+
end
|
49
|
+
def to_s
|
50
|
+
'redhat'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Fedora
|
55
|
+
def prepare_env
|
56
|
+
end
|
57
|
+
def to_s
|
58
|
+
'fedora'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class UnsupportedDistribution < Exception
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
Binary file
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pkg-wizard
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Sergio Rubio
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-14 00:00:00 +01:00
|
19
|
+
default_executable: pkgwiz
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 23
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 1.0.0
|
33
|
+
name: bundler
|
34
|
+
prerelease: false
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 7
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 5
|
47
|
+
- 2
|
48
|
+
version: 1.5.2
|
49
|
+
name: jeweler
|
50
|
+
prerelease: false
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
name: SystemTimer
|
64
|
+
prerelease: false
|
65
|
+
type: :runtime
|
66
|
+
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
name: resque
|
78
|
+
prerelease: false
|
79
|
+
type: :runtime
|
80
|
+
version_requirements: *id004
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
name: git
|
92
|
+
prerelease: false
|
93
|
+
type: :runtime
|
94
|
+
version_requirements: *id005
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 3
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
name: sinatra
|
106
|
+
prerelease: false
|
107
|
+
type: :runtime
|
108
|
+
version_requirements: *id006
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: 3
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
version: "0"
|
119
|
+
name: thin
|
120
|
+
prerelease: false
|
121
|
+
type: :runtime
|
122
|
+
version_requirements: *id007
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
hash: 3
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
name: rufus-scheduler
|
134
|
+
prerelease: false
|
135
|
+
type: :runtime
|
136
|
+
version_requirements: *id008
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
hash: 3
|
144
|
+
segments:
|
145
|
+
- 0
|
146
|
+
version: "0"
|
147
|
+
name: term-ansicolor
|
148
|
+
prerelease: false
|
149
|
+
type: :runtime
|
150
|
+
version_requirements: *id009
|
151
|
+
description: Tools to manage,create and build distribution packages
|
152
|
+
email: rubiojr@frameos.org
|
153
|
+
executables:
|
154
|
+
- pkgwiz
|
155
|
+
extensions: []
|
156
|
+
|
157
|
+
extra_rdoc_files:
|
158
|
+
- LICENSE.txt
|
159
|
+
- README.rdoc
|
160
|
+
files:
|
161
|
+
- .document
|
162
|
+
- Gemfile
|
163
|
+
- LICENSE.txt
|
164
|
+
- README.rdoc
|
165
|
+
- Rakefile
|
166
|
+
- VERSION
|
167
|
+
- bin/pkgwiz
|
168
|
+
- lib/pkg-wizard.rb
|
169
|
+
- lib/pkg-wizard/command.rb
|
170
|
+
- lib/pkg-wizard/commands/build_bot.rb
|
171
|
+
- lib/pkg-wizard/commands/create_srpm.rb
|
172
|
+
- lib/pkg-wizard/commands/remote_build.rb
|
173
|
+
- lib/pkg-wizard/git.rb
|
174
|
+
- lib/pkg-wizard/logger.rb
|
175
|
+
- lib/pkg-wizard/mock.rb
|
176
|
+
- lib/pkg-wizard/rpm.rb
|
177
|
+
- lib/pkg-wizard/streaming_downloader.rb
|
178
|
+
- lib/pkg-wizard/streaming_uploader.rb
|
179
|
+
- packages/epel-release-5-4.noarch.rpm
|
180
|
+
- packages/epel-release-6-5.noarch.rpm
|
181
|
+
has_rdoc: true
|
182
|
+
homepage: http://github.com/rubiojr/pkg-wizard
|
183
|
+
licenses:
|
184
|
+
- MIT
|
185
|
+
post_install_message:
|
186
|
+
rdoc_options: []
|
187
|
+
|
188
|
+
require_paths:
|
189
|
+
- lib
|
190
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
none: false
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
hash: 3
|
196
|
+
segments:
|
197
|
+
- 0
|
198
|
+
version: "0"
|
199
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
|
+
none: false
|
201
|
+
requirements:
|
202
|
+
- - ">="
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
hash: 3
|
205
|
+
segments:
|
206
|
+
- 0
|
207
|
+
version: "0"
|
208
|
+
requirements: []
|
209
|
+
|
210
|
+
rubyforge_project:
|
211
|
+
rubygems_version: 1.3.7
|
212
|
+
signing_key:
|
213
|
+
specification_version: 3
|
214
|
+
summary: Package Wizards Tools
|
215
|
+
test_files: []
|
216
|
+
|