rappa 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []