rappa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +7 -0
  2. data/bin/rappa +61 -0
  3. data/src/rappa.rb +114 -0
  4. metadata +118 -0
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ rappa = Ruby Application Package Personal Assistant
2
+
3
+ rappa -c config.yml
4
+
5
+
6
+ What should it do?
7
+
data/bin/rappa ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ require 'configliere'
3
+ require File.dirname(File.expand_path(__FILE__)) + '/../src/rappa'
4
+
5
+ Settings.use :commandline
6
+
7
+ Settings.define :input_directory, :flag => 'i', :description => 'Input directory for package e.g. rappa package -i /path/to/project'
8
+ Settings.define :output_directory, :flag => 'o', :description => 'Output directory for package e.g. rappa package -o /path/to/output/location'
9
+ Settings.define :input_archive, :flag => 'a', :description => 'Input .rap archive for expand e.g. rappa expand -a /path/to/.rap'
10
+ Settings.define :output_archive, :flag => 'd', :description => 'Output directory for expand e.g. rappa expand -d /path/to/output/location'
11
+ Settings.define :input_rap, :flag => 'r', :description => 'Input .rap for deploy e.g. rappa deploy -r /path/to/.rap -u http://host/api/deploy -k api_key'
12
+ Settings.define :url, :flag => 'u', :description => 'Url for deploy e.g. rappa deploy -r /path/to/.rap -u http://host/api/deploy -k api_key'
13
+ Settings.define :api_key, :flag => 'k', :description => 'Api key for deploy e.g. rappa deploy -r /path/to/.rap -u http://host/api/deploy -k api_key'
14
+
15
+ Settings.resolve!
16
+
17
+ if Settings.rest.include?('package')
18
+ if Settings[:input_directory].nil?
19
+ puts '[ERROR] You must supply an input directory for package with -i e.g. rappa package -i /path/to/project'
20
+ elsif Settings[:output_directory].nil?
21
+ puts '[ERROR] You must supply an output directory for package with -o e.g. rappa package -o /path/to/output/location'
22
+ else
23
+ begin
24
+ Rappa.new(Settings).package
25
+ puts '[SUCCESS] packaged rap successfully'
26
+ rescue RappaError => e
27
+ puts "[ERROR] Could not continue package because: #{e}"
28
+ end
29
+ end
30
+ elsif Settings.rest.include?('expand')
31
+ if Settings[:input_archive].nil?
32
+ puts '[ERROR] You must supply an input .rap archive for expand with -a e.g. rappa expand -a /path/to/.rap'
33
+ elsif Settings[:output_archive].nil?
34
+ puts '[ERROR] You must supply an output archive directory for expand with -d e.g. rappa expand -d /path/to/output/location'
35
+ else
36
+ begin
37
+ Rappa.new(Settings).expand
38
+ puts '[SUCCESS] expanded rap successfully'
39
+ rescue RappaError => e
40
+ puts "[ERROR] Could not continue expand because: #{e}"
41
+ end
42
+ end
43
+ elsif Settings.rest.include?('generate')
44
+ Rappa.new.generate
45
+ elsif Settings.rest.include?('deploy')
46
+ if Settings[:input_rap].nil?
47
+ puts '[ERROR] You must supply an input .rap archive for deploy with -r e.g. rappa deploy -r /path/to/.rap -u http://host/api/deploy -k api_key'
48
+ elsif Settings[:api_key].nil?
49
+ puts '[ERROR] You must supply an api key for deploy with -k e.g. rappa deploy -r /path/to/.rap -u http://host/api/deploy -k api_key'
50
+ elsif Settings[:url].nil?
51
+ puts '[ERROR] You must supply a url for deploy with -u e.g. rappa deploy -r /path/to/.rap -u http://host/api/deploy -k api_key'
52
+ else
53
+ begin
54
+ Rappa.new(Settings).deploy
55
+ puts "[SUCCESS] deployed rap: #{Settings[:input_rap]} successfully to: #{Settings[:url]}"
56
+ rescue RappaError => e
57
+ puts "[ERROR] Could not continue deploy because: #{e}"
58
+ end
59
+ end
60
+ end
61
+
data/src/rappa.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'zip/zip'
2
+ require 'fileutils'
3
+ require 'yaml'
4
+ require 'rest-client'
5
+
6
+ class RappaError < Exception;
7
+ end
8
+
9
+ class Rappa
10
+
11
+ SUPPORTED_SERVERS = %w(thin unicorn webrick)
12
+
13
+ def initialize(config={},rest_client=RestClient,file=File)
14
+ @config = config
15
+ @file = file
16
+ @rest_client = rest_client
17
+ unless @config[:input_directory].nil?
18
+ @config[:file_name] = (@config[:input_directory] == '.') ? 'default' : @file.basename(@config[:input_directory])
19
+ end
20
+ end
21
+
22
+ def package
23
+ check_property(@config[:input_directory], :input_directory)
24
+ check_property(@config[:output_directory], :output_directory)
25
+ input_directory = append_trailing_slash(@config[:input_directory])
26
+ raise RappaError, "input directory: #{input_directory} does not exist" unless @file.exists?(input_directory)
27
+ output_directory = @config[:output_directory]
28
+ FileUtils.mkdir_p output_directory unless @file.exists?(output_directory)
29
+ name = "#{@config[:output_directory]}/#{@config[:file_name]}.rap"
30
+ raise RappaError, "a rap archive already exists with the name: #{@config[:file_name]}.rap - please remove it and try again" if @file.exists?(name)
31
+ validate(input_directory)
32
+ Zip::ZipFile.open(name, Zip::ZipFile::CREATE) do |zip_file|
33
+ Dir[@file.join(input_directory, '**', '**')].each do |file|
34
+ zip_file.add(file.sub(input_directory, ''), file)
35
+ end
36
+ end
37
+ end
38
+
39
+ def expand
40
+ check_property(@config[:input_archive], :input_archive)
41
+ check_property(@config[:output_archive], :output_archive)
42
+ raise RappaError, "input archive: #{@config[:input_archive]} does not exist" unless @file.exists?(@config[:input_archive])
43
+ validate_is_rap_archive
44
+ output_directory = @config[:output_archive]
45
+ FileUtils.mkdir_p output_directory unless @file.exists?(output_directory)
46
+ Zip::ZipFile.open(@config[:input_archive]) { |zip_file|
47
+ zip_file.each { |f|
48
+ f_path=@file.join(calculate_destination, f.name)
49
+ FileUtils.mkdir_p(@file.dirname(f_path))
50
+ zip_file.extract(f, f_path) { true } unless @file.exist?(f_path) # true will overwrite existing files.
51
+ }
52
+ }
53
+ end
54
+
55
+ def deploy
56
+ check_property(@config[:input_rap], :input_rap)
57
+ check_property(@config[:url], :url)
58
+ check_property(@config[:api_key], :api_key)
59
+ @rest_client.put "#{@config[:url]}?key=#{@config[:api_key]}", :file => @file.new(@config[:input_rap])
60
+ end
61
+
62
+ def generate
63
+ sample = {:server_type => 'thin', :start_script => 'start.sh', :stop_script => 'stop.sh', :pids => 'tmp/pids', :name => 'App Name', :description => 'App Description'}
64
+ @file.open('sample.rap.yml', 'w') { |f| f.puts sample.to_yaml }
65
+ end
66
+
67
+ protected
68
+
69
+ def install
70
+ expand
71
+ validate(calculate_destination)
72
+ end
73
+
74
+ private
75
+
76
+ def check_property(property, property_type)
77
+ raise RappaError, "property #{property_type} is mandatory but was not supplied" if property.nil? or property.empty?
78
+ end
79
+
80
+ def validate(directory)
81
+ rap_file = directory + '/rap.yml'
82
+ if @file.exists?(rap_file)
83
+ rap = YAML.load_file(rap_file)
84
+ raise RappaError, "rap.yml :server_type is required and must be one of: #{SUPPORTED_SERVERS}" if rap[:server_type].nil? or rap[:server_type].empty?
85
+ raise RappaError, "rap.yml :server_type supplied: #{rap[:server_type]} is not in the supported server list: #{SUPPORTED_SERVERS}" unless SUPPORTED_SERVERS.include?(rap[:server_type])
86
+ raise RappaError, 'rap.yml :start_script is required' if rap[:start_script].nil? or rap[:start_script].empty?
87
+ raise RappaError, 'rap.yml :stop_script is required' if rap[:stop_script].nil? or rap[:stop_script].empty?
88
+ raise RappaError, 'rap.yml :pids is required' if rap[:pids].nil? or rap[:pids].empty?
89
+ raise RappaError, 'rap.yml :name is required' if rap[:name].nil? or rap[:name].empty?
90
+ raise RappaError, 'rap.yml :description is required' if rap[:description].nil? or rap[:description].empty?
91
+ raise RappaError, 'rap.yml :version is required' if rap[:version].nil? or rap[:version].empty?
92
+ else
93
+ raise RappaError, 'rap.yml file is required - please run rappa generate to create a sample rap.yml'
94
+ end
95
+ end
96
+
97
+ def validate_is_rap_archive
98
+ base_name = @file.basename(@config[:input_archive])
99
+ extension = @file.extname(base_name)
100
+ raise RappaError, "input archive: #{@config[:input_archive]} is not a valid .rap archive" unless extension == '.rap'
101
+ end
102
+
103
+ def calculate_destination
104
+ base_name = @file.basename(@config[:input_archive])
105
+ name = base_name.chomp(@file.extname(base_name))
106
+ @config[:output_archive] + '/' + name
107
+ end
108
+
109
+ def append_trailing_slash(path)
110
+ path = "#{path}/" if path[-1] != '/'
111
+ path
112
+ end
113
+
114
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rappa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kingsley Hendrickse
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
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: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: configliere
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
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: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubyzip
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: ! 'Easy and simple way to package up your rack based application into
79
+ a .rap (Ruby Application Package) for deployment to a web container that supports
80
+ .rap such as ThunderCat.
81
+
82
+ '
83
+ email: kingsley@masterthought.net
84
+ executables:
85
+ - /rappa
86
+ extensions: []
87
+ extra_rdoc_files:
88
+ - README.md
89
+ files:
90
+ - src/rappa.rb
91
+ - README.md
92
+ - bin/rappa
93
+ homepage: https://github.com/masterthought/rappa
94
+ licenses:
95
+ - Apache 2.0
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - src
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.25
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Ruby Application Package Personal Assistant
118
+ test_files: []