deployman 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/deployman ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # ruby -Ilib bin/deployman -i repoOwner,repoName,v3.0.0,https://api.github.com/repos/repoOwner/repoName/zipball/v3.0.0,/sandbox/liveserver/customerName/software/repoOwner/repoName/releases/v3.0.0 --auth github_user,password --config customer,customerName
4
+
5
+ require 'deployman'
6
+ require 'deployman/app'
7
+ require 'deployman/app/install'
8
+ require 'deployman/app/optionparser'
9
+ require 'deployman/app/configuration'
10
+ require 'deployman/app/postsetup'
11
+ require 'deployman/component'
12
+ require 'deployman/component/downloader'
13
+ require 'deployman/component/spinningclock'
14
+ require 'deployman/component/output'
15
+ require 'deployman/net'
16
+ require 'deployman/net/post'
17
+ require 'deployman/extractor'
18
+ require 'deployman/extractor/zip'
19
+
20
+ Deployman::App.run
data/lib/deployman.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Deployman
2
+
3
+ end
4
+
@@ -0,0 +1,40 @@
1
+ module Deployman::App
2
+
3
+ def self.run (args = nil)
4
+ args ||= ARGV.dup.map! { |v| v.dup }
5
+
6
+ # parse all options of command-line
7
+ options = Deployman::App::Optionparser.parse args
8
+
9
+ if options[:callback]
10
+
11
+ # redirect output (stdout, stderr) to tempfiles
12
+ Deployman::Component::Output.redirect_output
13
+
14
+ # deactivate spinningclock for clear output
15
+ Deployman::Component::Spinningclock.set_active false
16
+
17
+ begin
18
+ # call <Application> (e.g. http://localhost:8000/callback/install)
19
+ Deployman::Net::Post.send options[:callback], { "status" => "running", "stdout" => nil, "stderr" => nil }
20
+ # run deploy with parsed options
21
+ Deployman::App::Install.run options
22
+ # call <Application>
23
+ Deployman::Net::Post.send options[:callback], { "status" => "finished", "stdout" => Deployman::Component::Output.get_stdout, "stderr" => Deployman::Component::Output.get_stderr }
24
+ rescue Exception => e
25
+ warn "ERROR: #{e.message}"
26
+ # call <Application>
27
+ Deployman::Net::Post.send options[:callback], { "status" => "error", "stdout" => Deployman::Component::Output.get_stdout, "stderr" => Deployman::Component::Output.get_stderr }
28
+ end
29
+
30
+ else
31
+ begin
32
+ # run deploy with parsed options
33
+ Deployman::App::Install.run options
34
+ rescue Exception => e
35
+ warn "ERROR: #{e.message}"
36
+ end
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,27 @@
1
+ require 'yaml'
2
+
3
+ module Deployman::App::Configuration
4
+
5
+ # create
6
+ # path = "/sandbox/liveserver/customerName/software/repoOnwer/repoName/releases/v2.2.0"
7
+ def self.create(path, values)
8
+ # if exists, file will be overwritten
9
+ File.open(path + '/deployman.yml', 'wb') do |file|
10
+ file.write(values.to_yaml)
11
+ file.close
12
+ end
13
+ end
14
+
15
+ # delete
16
+ def self.delete(path)
17
+ File.delete(path + '/deployman.yml')
18
+ end
19
+
20
+ # get
21
+ def self.get(path)
22
+ config = YAML::load_file(path + '/deployman.yml')
23
+ end
24
+
25
+ end
26
+
27
+
@@ -0,0 +1,128 @@
1
+ require 'fileutils'
2
+ require 'date'
3
+
4
+ module Deployman::App::Install
5
+
6
+ DL_DIR = "/tmp/"
7
+ @@options = {}
8
+
9
+ def self.run (options)
10
+
11
+ @@options = options
12
+
13
+ if options[:install]
14
+ puts "> Installation started!"
15
+ install(options[:install][0],options[:install][1],options[:install][2],options[:install][3],options[:install][4],options[:auth])
16
+ puts "> Installation finished!"
17
+ elsif options[:uninstall]
18
+ puts "> Uninstall started!"
19
+ uninstall(options[:uninstall])
20
+ puts "> Uninstall finished!"
21
+ else
22
+ puts "Unknown command. Type --help for more information!", true
23
+ end
24
+
25
+ end
26
+
27
+ # INSTALL
28
+ # owner = "repoOwner"
29
+ # software = "repoName"
30
+ # release = "v2.2.0"
31
+ # zip_url = "https://api.github.com/repos/repoOnwer/repoName/zipball/v2.2.0"
32
+ # dest = "/sandbox/liveserver/customerName/software/repoOnwer/repoName/releases/v2.2.0"
33
+ #
34
+ def self.install (owner, software, release, zip_url, dest, auth = false)
35
+
36
+ # check if release already installed
37
+ if !File.directory?(dest)
38
+
39
+ zip_path = DL_DIR << owner << "-" << software << "-" << release << ".zip"
40
+
41
+ begin
42
+
43
+ # download zip file
44
+ print "> Downloading..."
45
+ Deployman::Component::Downloader.download_file(zip_url, zip_path, auth)
46
+ puts "done!"
47
+
48
+ # unzip zip file
49
+ print "> Unzipping..."
50
+ Deployman::Extractor::Zip.extract_file(zip_path, dest)
51
+ puts "done!"
52
+
53
+ # create configuration file
54
+ print "> Creating Configfile..."
55
+ create_configfile(owner, software, release, zip_url, dest)
56
+ puts "done!"
57
+
58
+ # run deploy.rb
59
+ print "> Deploying..."
60
+ deployrb(dest)
61
+ puts "done!"
62
+
63
+ # create postsetup.json file
64
+ print "> Creating Postsetupfile..."
65
+ Deployman::App::Postsetup.createPostsetupFile dest
66
+ puts "done!"
67
+
68
+ rescue Exception => e
69
+ warn "ERROR: #{e.message}"
70
+ raise "Installation failed!"
71
+ end
72
+
73
+ else
74
+ puts "> Release already installed!"
75
+ end
76
+ end
77
+
78
+ # UNINSTALL
79
+ # release_path = "/sandbox/liveserver/customerName/software/repoOnwer/repoName/releases/v2.2.0"
80
+ #
81
+ def self.uninstall (release_path)
82
+ FileUtils.rm_rf(release_path)
83
+ end
84
+
85
+ def self.create_configfile (owner, software, release, zip_url, dest)
86
+ begin
87
+ config = {
88
+ "owner" => owner,
89
+ "software" => software,
90
+ "version" => release,
91
+ "installed_at" => DateTime.now.strftime("%b %d, %Y %H:%M"),
92
+ "zip_url" => zip_url,
93
+ "dest" => dest
94
+ }
95
+ config.merge! @@options[:config]
96
+ Deployman::App::Configuration.create(dest, config)
97
+ rescue Exception => e
98
+ warn "ERROR: #{e.message}"
99
+ raise "Creating Configfile failed!"
100
+ end
101
+ end
102
+
103
+ # RUN_DEPLOYRB
104
+ # dest = "/sandbox/liveserver/customerName/software/repoOnwer/repoName/releases/v2.2.0"
105
+ #
106
+ def self.deployrb (dest)
107
+ begin
108
+ deployrb_path = dest + "/deploy.rb"
109
+
110
+ if File.exist?(deployrb_path)
111
+ # execute deploy.rb
112
+ Deployman::Component::Spinningclock.show_clock {
113
+ # get config
114
+ $config = Deployman::App::Configuration.get(dest)
115
+ # change to release dir
116
+ Dir.chdir dest
117
+ # run deploy.rb
118
+ load deployrb_path
119
+ }
120
+ else
121
+ print "(no deploy.rb file)..."
122
+ end
123
+ rescue Exception => e
124
+ warn "ERROR: #{e.message}"
125
+ raise "Deploying failed!"
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,88 @@
1
+ require 'optparse' # OptionParser
2
+
3
+ module Deployman::App::Optionparser
4
+
5
+ def self.parse (args)
6
+
7
+ # This hash will hold all of the options parsed from the command-line by OptionParser.
8
+ options = {}
9
+
10
+ optparse = OptionParser.new do |opts|
11
+
12
+ # Set a banner, displayed at the top of the help screen.
13
+ opts.banner = "Usage: deployman [option1] param1,param2 [optionN] paramN ...\r\n\r\n"
14
+
15
+ # install
16
+ options[:install] = false
17
+ opts.on('--install OWNER,SOFTWARE,RELEASE,ZIP_URL,DEST', Array, "Install" ) do |setting|
18
+ argumentLength = 5
19
+ raise OptionParser::MissingArgument if setting.length < argumentLength
20
+ raise OptionParser::NeedlessArgument if setting.length > argumentLength
21
+ options[:install] = setting
22
+ end
23
+
24
+ # uninstall
25
+ options[:uninstall] = false
26
+ opts.on('--uninstall PATH', "Uninstall") do |setting|
27
+ options[:uninstall] = setting
28
+ end
29
+
30
+ # auth
31
+ options[:auth] = false
32
+ opts.on('--auth USER,PASS', Array, "HTTP Authentication for Github API (works only in combination with --install)") do |setting|
33
+ argumentLength = 2
34
+ raise OptionParser::MissingArgument if setting.length < argumentLength
35
+ raise OptionParser::NeedlessArgument if setting.length > argumentLength
36
+ options[:auth] = setting
37
+ end
38
+
39
+ # config
40
+ options[:config] = {}
41
+ opts.on('--config VALUES', Array, "add custom config values (works only in combination with --install)") do |setting|
42
+ raise OptionParser::MissingArgument if setting.length % 2 != 0
43
+ # create key-value pairs from setting
44
+ config = {}
45
+ setting.each_slice(2) do |key, value|
46
+ config.store(key, value)
47
+ end
48
+ options[:config] = config
49
+ end
50
+
51
+ # callback
52
+ options[:callback] = false
53
+ opts.on('--callback URL', "callbacks status of installation (running/finished/error), stdout, stderr - as json object") do |setting|
54
+ options[:callback] = setting
55
+ end
56
+
57
+ # help
58
+ opts.on( '-h', '--help', 'Display help screen' ) do
59
+ puts opts
60
+ puts "\r\n"
61
+ exit
62
+ end
63
+
64
+ end
65
+
66
+ # Parse the command-line. Remember there are two forms
67
+ # of the parse method. The 'parse' method simply parses
68
+ # ARGV, while the 'parse!' method parses ARGV and removes
69
+ # any options found there, as well as any parameters for
70
+ # the options. What's left is the list of files to resize.
71
+ begin
72
+ optparse.parse! args
73
+ # return the parsed options
74
+ return options
75
+ rescue OptionParser::InvalidOption => e
76
+ warn "Error! #{e}"
77
+ exit
78
+ rescue OptionParser::MissingArgument => e
79
+ warn "Error! #{e}"
80
+ exit
81
+ rescue OptionParser::NeedlessArgument => e
82
+ warn "Error! #{e}"
83
+ exit
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,92 @@
1
+ require 'json'
2
+ require 'oj'
3
+
4
+ module Deployman::App::Postsetup
5
+
6
+ @@tasks = []
7
+
8
+ # task class
9
+ #
10
+ class Task
11
+ attr_accessor :title, :desc, :commands
12
+
13
+ def initialize
14
+ @title = ""
15
+ @desc = ""
16
+ @commands = []
17
+ end
18
+ end
19
+
20
+ # add new task to tasks
21
+ #
22
+ def self.newTask
23
+ task = Task.new
24
+ @@tasks.push(task)
25
+ return task
26
+ end
27
+
28
+ # get array of all tasks
29
+ #
30
+ def self.getTasks
31
+ @@tasks
32
+ end
33
+
34
+ # create postsetup.json file
35
+ # path = "/sandbox/liveserver/customerName/software/repoOwner/repoName/releases/v2.2.0"
36
+ #
37
+ def self.createPostsetupFile (path)
38
+ if not @@tasks.empty?
39
+ # if exists, file will be overwritten
40
+ File.open(path + '/postsetup.json', 'wb') do |file|
41
+ file.write(Oj::dump @@tasks, :indent => 2)
42
+ file.close
43
+ end
44
+ else
45
+ print "(no tasks found)..."
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ # # postsetup tasks
52
+ # task = newTask
53
+ # task.title = "database"
54
+ # task.desc = "do database stuff"
55
+ # task.commands = [
56
+ # "php app/console doctrine:database:create",
57
+ # "php app/console doctrine:schema:update --dump-sql",
58
+ # "php app/console doctrine:schema:update --force",
59
+ # "echo 'y' | php app/console doctrine:fixtures:load"
60
+ # ]
61
+
62
+ # task = newTask
63
+ # task.title = "other stuff"
64
+ # task.desc = "just do the other stuff"
65
+ # task.commands = [
66
+ # "php otherstuff"
67
+ # ]
68
+
69
+
70
+ # [
71
+ # {
72
+ # "^o":"Deployman::App::Postsetup::Task",
73
+ # "title":"database",
74
+ # "desc":"do database stuff",
75
+ # "commands":[
76
+ # "php app/console doctrine:database:create",
77
+ # "php app/console doctrine:schema:update --dump-sql",
78
+ # "php app/console doctrine:schema:update --force",
79
+ # "echo 'y' | php app/console doctrine:fixtures:load"
80
+ # ]
81
+ # },
82
+ # {
83
+ # "^o":"Deployman::App::Postsetup::Task",
84
+ # "title":"other stuff",
85
+ # "desc":"just do the other stuff",
86
+ # "commands":[
87
+ # "php otherstuff"
88
+ # ]
89
+ # }
90
+ # ]
91
+
92
+
@@ -0,0 +1,3 @@
1
+ module Deployman::Component
2
+
3
+ end
@@ -0,0 +1,100 @@
1
+ require 'net/http'
2
+ require 'net/https' if RUBY_VERSION < '1.9'
3
+ require 'net/ftp'
4
+ require 'fileutils'
5
+ require 'tempfile'
6
+
7
+ module Deployman::Component::Downloader
8
+
9
+ def self.download_file(url, full_path, auth = false)
10
+ Main.new.download_file(url, full_path, auth)
11
+ end
12
+
13
+ class Main
14
+
15
+ def download_file(url, full_path, auth = false, redirects = 3)
16
+ if File.exist?(full_path)
17
+ print "(file already exists)..."
18
+ return
19
+ end
20
+
21
+ uri = URI.parse(url)
22
+ case uri.scheme.downcase
23
+ when /ftp/
24
+ puts "ftp not supported yet"
25
+ return false
26
+ when /http|https/
27
+ Main::http_download(url, full_path, auth, redirects)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # download over http, https
34
+ # redirects = how many redirects to follow
35
+ #
36
+ def self.http_download(url, full_path, auth, redirects)
37
+
38
+ begin
39
+ uri = URI.parse(url)
40
+
41
+ filename = File.basename(uri.path)
42
+
43
+ # http
44
+ http = Net::HTTP.new(uri.host, uri.port)
45
+ if uri.scheme.downcase == 'https'
46
+ http.use_ssl = true
47
+ end
48
+
49
+ # request
50
+ request = Net::HTTP::Get.new(uri.request_uri)
51
+ request.basic_auth(auth[0], auth[1]) if auth
52
+
53
+ # do request
54
+ http.request(request) do |response|
55
+ case response
56
+ when Net::HTTPNotFound
57
+ # puts "404 - Not Found"
58
+ # return false
59
+ raise "404 - Not Found"
60
+
61
+ when Net::HTTPClientError
62
+ # puts "Error: Client Error: #{response.inspect}"
63
+ # return false
64
+ raise "Error: Client Error: #{response.inspect}"
65
+
66
+ when Net::HTTPRedirection
67
+ raise "Too many redirections for the original URL, halting." if redirects <= 0
68
+ url = response["location"]
69
+ return http_download(url, full_path, auth, redirects - 1)
70
+
71
+ when Net::HTTPOK
72
+ # create Tempfile
73
+ temp_file = Tempfile.new("download-#{filename}")
74
+ temp_file.binmode
75
+
76
+ # download and write into tempfile
77
+ Deployman::Component::Spinningclock.show_clock {
78
+ response.read_body do |chunk|
79
+ # write in Tempfile
80
+ temp_file << chunk
81
+ end
82
+ }
83
+
84
+ # close Tempfile
85
+ temp_file.close
86
+
87
+ # rename Tempfile in destination filename
88
+ File.unlink full_path if File.exists?(full_path)
89
+ FileUtils.mkdir_p File.dirname(full_path)
90
+ FileUtils.mv temp_file.path, full_path, :force => true
91
+ end
92
+ end
93
+ rescue Exception => e
94
+ File.unlink full_path if File.exists?(full_path)
95
+ warn "ERROR: #{e.message}"
96
+ raise "Downloading failed!"
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,53 @@
1
+ require 'tempfile'
2
+
3
+ module Deployman::Component::Output
4
+
5
+ # redirect outputs into tempfiles
6
+ #
7
+ def self.redirect_output
8
+
9
+ # backup original outputs
10
+ @@stdout = $stdout.dup
11
+ @@stderr = $stderr.dup
12
+
13
+ # open tempfiles
14
+ # will create temp files in /tmp/
15
+ @@stdout_temp = Tempfile.open 'stdout-redirect'
16
+ @@stderr_temp = Tempfile.open 'stderr-redirect'
17
+
18
+ # redirect outputs to tempfiles
19
+ $stdout.reopen @@stdout_temp.path, 'a'
20
+ $stderr.reopen @@stderr_temp.path, 'a'
21
+ end
22
+
23
+ # get both outputs from tempfiles
24
+ # will destroy tempfiles after read
25
+ #
26
+ def self.get_output
27
+ # restore original output (will write all outputs to tempfiles)
28
+ $stdout.reopen @@stdout
29
+ $stderr.reopen @@stderr
30
+ # return tempfile content
31
+ {'stdout' => @@stdout_temp.read, 'stderr' => @@stderr_temp.read}
32
+ end
33
+
34
+ # get stdout from tempfile
35
+ # will destroy tempfile after read
36
+ #
37
+ def self.get_stdout
38
+ # restore original output (will write all outputs to tempfiles)
39
+ $stdout.reopen @@stdout
40
+ # return tempfile content
41
+ @@stdout_temp.read
42
+ end
43
+
44
+ # get stderr from tempfile
45
+ # will destroy tempfile after read
46
+ #
47
+ def self.get_stderr
48
+ # restore original output (will write all outputs to tempfiles)
49
+ $stderr.reopen @@stderr
50
+ # return tempfile content
51
+ @@stderr_temp.read
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ module Deployman::Component::Spinningclock
2
+
3
+ @@active = true;
4
+
5
+ def self.show_clock(fps = 10)
6
+
7
+ if @@active
8
+ chars = %w[| / - \\]
9
+ delay = 1.0/fps
10
+ iter = 0
11
+ clock = Thread.new do
12
+ while iter do # Keep spinning until told otherwise
13
+ print chars[(iter+=1) % chars.length]
14
+ sleep delay
15
+ print "\b"
16
+ end
17
+ end
18
+ yield.tap { # After yielding to the block, save the return value
19
+ iter = false # Tell the thread to exit, cleaning up after itself…
20
+ clock.join # …and wait for it to do so.
21
+ } # Use the block's return value as the method's
22
+ else
23
+ # just execute the block
24
+ yield
25
+ end
26
+
27
+ end
28
+
29
+ def self.set_active(active = true)
30
+ @@active = active
31
+ end
32
+
33
+ end
@@ -0,0 +1,3 @@
1
+ module Deployman::Extractor
2
+
3
+ end
@@ -0,0 +1,56 @@
1
+ require 'zip'
2
+ require 'fileutils'
3
+
4
+ module Deployman::Extractor::Zip
5
+
6
+ # extract_file
7
+ # file: "/tmp/repoOnwer-repoName-v2.2.0-0-gb98bf98.zip"
8
+ # dest: ".../customerName/software/repoOnwer/repoName/releases/v2.2.0"
9
+ #
10
+ def self.extract_file (file, dest)
11
+
12
+ # dest = "/sandbox/liveserver/customerName/software/repoOnwer/repoName/releases/v2.2.0"
13
+ # dest_dir = "v2.2.0"
14
+ # dest_path = "/sandbox/liveserver/customerName/software/repoOwner/repoName/releases/"
15
+ dest_dir = dest.split("/").last
16
+ dest_path = dest.chomp(dest_dir)
17
+ root_folder = false
18
+
19
+ begin
20
+
21
+ # get the full path to the real unzipped folder
22
+ # e.g. "/sandbox/liveserver/.../releases/repoOnwer-repoName-3940226/"
23
+ root_folder = File.join(dest_path, Zip::File.open(file).first.name)
24
+
25
+ # lets create all needed dirs
26
+ FileUtils.mkdir_p(dest_path)
27
+
28
+ # unzip
29
+ Zip::File.open(file) do |zip_file|
30
+
31
+ Deployman::Component::Spinningclock.show_clock {
32
+ # unzip
33
+ zip_file.each do |f|
34
+ f_path=File.join(dest_path, f.name)
35
+ FileUtils.mkdir_p(File.dirname(f_path))
36
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
37
+ end
38
+ }
39
+
40
+ end
41
+
42
+ # rename the unzipped root folder
43
+ File.rename(root_folder, dest)
44
+
45
+ rescue Exception => e
46
+ FileUtils.rm_rf(root_folder) if root_folder && File.exists?(root_folder)
47
+ FileUtils.rm_rf(dest) if File.exists?(dest)
48
+ warn "ERROR: #{e.message}"
49
+ raise "Unzipping failed!"
50
+ end
51
+
52
+
53
+ end
54
+
55
+
56
+ end
@@ -0,0 +1,3 @@
1
+ module Deployman::Net
2
+
3
+ end
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+
3
+ module Deployman::Net::Post
4
+
5
+ def self.send (url, data)
6
+
7
+ # create http object
8
+ # e.g. url = 'http://localhost:8000/callback/install'
9
+ uri = URI.parse(url)
10
+ http = Net::HTTP.new(uri.host, uri.port)
11
+
12
+ # create request object
13
+ request = Net::HTTP::Post.new(uri.request_uri)
14
+ # request.basic_auth(auth[0], auth[1]) if auth
15
+
16
+ # set request data
17
+ # e.g. data = { "mydata" => "funzt" }
18
+ request.body = JSON.generate(data, quirks_mode: true)
19
+
20
+ # do request and get response
21
+ response = http.request(request)
22
+
23
+ # return response data
24
+ resp_data = JSON.parse(response.body)
25
+
26
+ end
27
+
28
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deployman
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rafael Schmitt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: oj
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.10'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.10'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rubyzip
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.1'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.1'
46
+ description: tool to deploy software projects
47
+ email: rafael.schmitt@gogol-publishing.de
48
+ executables:
49
+ - deployman
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/deployman.rb
54
+ - lib/deployman/net.rb
55
+ - lib/deployman/component/downloader.rb
56
+ - lib/deployman/component/spinningclock.rb
57
+ - lib/deployman/component/output.rb
58
+ - lib/deployman/app/postsetup.rb
59
+ - lib/deployman/app/optionparser.rb
60
+ - lib/deployman/app/configuration.rb
61
+ - lib/deployman/app/install.rb
62
+ - lib/deployman/extractor.rb
63
+ - lib/deployman/component.rb
64
+ - lib/deployman/extractor/zip.rb
65
+ - lib/deployman/net/post.rb
66
+ - lib/deployman/app.rb
67
+ - bin/deployman
68
+ homepage: http://rubygems.org/gems/deployman
69
+ licenses:
70
+ - MIT
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.23
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: deployman
93
+ test_files: []