vhost_generator 0.1.0
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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +69 -0
- data/Rakefile +11 -0
- data/bin/vhost-generator +6 -0
- data/features/help.feature +12 -0
- data/features/output-nginx.feature +171 -0
- data/features/step_definitions/dev_steps.rb +3 -0
- data/features/support/env.rb +1 -0
- data/features/version.feature +12 -0
- data/lib/vhost_generator/application.rb +150 -0
- data/lib/vhost_generator/nginx_generator.rb +66 -0
- data/lib/vhost_generator/version.rb +3 -0
- data/lib/vhost_generator/vhost_configuration.rb +108 -0
- data/lib/vhost_generator/vhost_generator_module.rb +18 -0
- data/lib/vhost_generator.rb +6 -0
- data/spec/application_env_spec.rb +29 -0
- data/spec/application_options_spec.rb +31 -0
- data/spec/nginx_generator_spec.rb +61 -0
- data/spec/vhost_configuration_spec.rb +127 -0
- data/vhost_generator.gemspec +28 -0
- metadata +165 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Julien Pervillé
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# VhostGenerator
|
2
|
+
|
3
|
+
This gem outputs a general-purpose VirtualHost configuration file
|
4
|
+
to run your web application behind an nginx or apache frontend.
|
5
|
+
|
6
|
+
The motivation of this gem is to automate that tedious task the first time, but
|
7
|
+
also every time the virtualhost parameters (such as the number of instances to
|
8
|
+
run and the ports where the instances are listening).
|
9
|
+
|
10
|
+
The gem features tries to integrate with the [foreman][1] gem by:
|
11
|
+
* reading configuration parameters from `ENV` (or from the `.env` file if present)
|
12
|
+
* detecting whether to proxy to tcp or unix socket from `Procfile` if present
|
13
|
+
* reading configuration from foreman's standard environment variables to allow
|
14
|
+
for generating a virtualhost that matches the last `foreman export`.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
gem 'vhost_generator'
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install vhost_generator
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
Basic usage:
|
33
|
+
|
34
|
+
$ bundle exec vhost-generator -l 80 -s myapp.com -p 5000,5001,5002
|
35
|
+
|
36
|
+
Advanced usage: all command-line switches have their equivalent environment variables. See note in `bundle exec vhost-generator --help`.
|
37
|
+
|
38
|
+
$ SERVER_PORTS=80 SERVER_NAMES=myapp.com INSTANCE_PORTS=5000,5001,5002 bundle exec vhost-generator
|
39
|
+
|
40
|
+
Advanced usage for lazy people: environment variables may be saved into the `.env` file or into another file whose name is given in `ENV['DOTENV']`.
|
41
|
+
This last option is nice, as it allows to store the environment in a file and reuse it later to generate the same virtualhost configurations.
|
42
|
+
|
43
|
+
$ echo "SERVER_PORTS=80\nSERVER_NAMES=myapp.com\nINSTANCE_PORTS=5000,5001,5002" >> my.env
|
44
|
+
$ DOTENV=my.env bundle exec vhost-generator
|
45
|
+
|
46
|
+
More advanced usages: see `features/` directory or run:
|
47
|
+
|
48
|
+
$ bundle exec vhost-generator --help
|
49
|
+
|
50
|
+
## Tips
|
51
|
+
|
52
|
+
Protip: pipe with `sudo tee` to save the configuration in your nginx sites-enabled directory.
|
53
|
+
|
54
|
+
$ bundle exec vhost-generator -l 80 -s myapp.com -p 5000,5001,5002 | sudo tee /etc/nginx/sites-enabled/myapp
|
55
|
+
|
56
|
+
Protip: run through `foreman run` to leverage your application's `.env` (DRY and handy when having a configured `RAILS_RELATIVE_URL_ROOT` for example)
|
57
|
+
|
58
|
+
$ echo RAILS_RELATIVE_URL_ROOT='/myapp' >> .env
|
59
|
+
$ bundle exec foreman run vhost-generator -l 80 -s myapp.com -p 5000,5001,5002
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
68
|
+
|
69
|
+
[1]: https://github.com/ddollar/foreman "Foreman"
|
data/Rakefile
ADDED
data/bin/vhost-generator
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Feature: Output help summary
|
2
|
+
|
3
|
+
In order to know how to invoke the program
|
4
|
+
As a user of the library
|
5
|
+
I want to display the program's help summary.
|
6
|
+
|
7
|
+
Scenario: output program help summary
|
8
|
+
When I run `bundle exec vhost-generator --help`
|
9
|
+
Then it should pass with:
|
10
|
+
"""
|
11
|
+
Display this help message.
|
12
|
+
"""
|
@@ -0,0 +1,171 @@
|
|
1
|
+
Feature: Output nginx configuration file
|
2
|
+
|
3
|
+
In order to run my application as an nginx virtualhost
|
4
|
+
As a user of the library
|
5
|
+
I want to output a nginx virtualhost configuration.
|
6
|
+
|
7
|
+
Scenario: using command-line options
|
8
|
+
When I run `bundle exec vhost-generator -g nginx -o upstream=myupstream -f html -l 80,81 -s localhost,my.server -p 5000,5001,5002 -r /myapp`
|
9
|
+
Then the output should match /FILE GENERATED BY.*EDIT AT YOUR OWN RISK/
|
10
|
+
And the output should contain:
|
11
|
+
"""
|
12
|
+
upstream myupstream {
|
13
|
+
server localhost:5000 fail_timeout=0;
|
14
|
+
server localhost:5001 fail_timeout=0;
|
15
|
+
server localhost:5002 fail_timeout=0;
|
16
|
+
}
|
17
|
+
"""
|
18
|
+
And the output should contain:
|
19
|
+
"""
|
20
|
+
server {
|
21
|
+
listen 80;
|
22
|
+
listen 81;
|
23
|
+
"""
|
24
|
+
And the output should contain:
|
25
|
+
"""
|
26
|
+
server_name localhost, my.server;
|
27
|
+
"""
|
28
|
+
And the output should match /root.*html;/
|
29
|
+
And the output should contain:
|
30
|
+
"""
|
31
|
+
try_files $uri/index.html $uri @upstream;
|
32
|
+
location @upstream {
|
33
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
34
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
35
|
+
proxy_set_header Host $http_host;
|
36
|
+
proxy_redirect off;
|
37
|
+
proxy_pass http://myupstream;
|
38
|
+
}
|
39
|
+
"""
|
40
|
+
And the output should contain:
|
41
|
+
"""
|
42
|
+
location /myapp/assets {
|
43
|
+
gzip_static on; # to serve pre-gzipped version
|
44
|
+
expires 60d;
|
45
|
+
add_header Cache-Control public;
|
46
|
+
}
|
47
|
+
"""
|
48
|
+
And the output should contain:
|
49
|
+
"""
|
50
|
+
error_page 500 502 503 504 /500.html;
|
51
|
+
client_max_body_size 4G;
|
52
|
+
keepalive_timeout 10;
|
53
|
+
}
|
54
|
+
"""
|
55
|
+
|
56
|
+
Scenario: using dotenv
|
57
|
+
Given a file named "tmpdir/my.env" with:
|
58
|
+
"""
|
59
|
+
GENERATOR=nginx
|
60
|
+
GENERATOR_OPTIONS=upstream=myupstream
|
61
|
+
STATIC_FOLDER=html
|
62
|
+
SERVER_PORTS=80,81
|
63
|
+
SERVER_NAMES=localhost,my.server
|
64
|
+
INSTANCE_PORTS=5000,5001,5002
|
65
|
+
RAILS_RELATIVE_URL_ROOT=/myapp
|
66
|
+
"""
|
67
|
+
When I cd to "tmpdir"
|
68
|
+
And I set env variable "DOTENV" to "my.env"
|
69
|
+
And I run `bundle exec vhost-generator`
|
70
|
+
Then the output should match /FILE GENERATED BY.*EDIT AT YOUR OWN RISK/
|
71
|
+
And the output should contain:
|
72
|
+
"""
|
73
|
+
upstream myupstream {
|
74
|
+
server localhost:5000 fail_timeout=0;
|
75
|
+
server localhost:5001 fail_timeout=0;
|
76
|
+
server localhost:5002 fail_timeout=0;
|
77
|
+
}
|
78
|
+
"""
|
79
|
+
And the output should contain:
|
80
|
+
"""
|
81
|
+
server {
|
82
|
+
listen 80;
|
83
|
+
listen 81;
|
84
|
+
"""
|
85
|
+
And the output should contain:
|
86
|
+
"""
|
87
|
+
server_name localhost, my.server;
|
88
|
+
"""
|
89
|
+
And the output should match /root.*html;/
|
90
|
+
And the output should contain:
|
91
|
+
"""
|
92
|
+
try_files $uri/index.html $uri @upstream;
|
93
|
+
location @upstream {
|
94
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
95
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
96
|
+
proxy_set_header Host $http_host;
|
97
|
+
proxy_redirect off;
|
98
|
+
proxy_pass http://myupstream;
|
99
|
+
}
|
100
|
+
"""
|
101
|
+
And the output should contain:
|
102
|
+
"""
|
103
|
+
location /myapp/assets {
|
104
|
+
gzip_static on; # to serve pre-gzipped version
|
105
|
+
expires 60d;
|
106
|
+
add_header Cache-Control public;
|
107
|
+
}
|
108
|
+
"""
|
109
|
+
And the output should contain:
|
110
|
+
"""
|
111
|
+
error_page 500 502 503 504 /500.html;
|
112
|
+
client_max_body_size 4G;
|
113
|
+
keepalive_timeout 10;
|
114
|
+
}
|
115
|
+
"""
|
116
|
+
|
117
|
+
Scenario: using environment variables
|
118
|
+
When I set env variable "GENERATOR" to "nginx"
|
119
|
+
And I set env variable "GENERATOR_OPTIONS" to "upstream=myupstream"
|
120
|
+
And I set env variable "STATIC_FOLDER" to "html"
|
121
|
+
And I set env variable "SERVER_PORTS" to "80,81"
|
122
|
+
And I set env variable "SERVER_NAMES" to "localhost,my.server"
|
123
|
+
And I set env variable "INSTANCE_PORTS" to "5000,5001,5002"
|
124
|
+
And I set env variable "RAILS_RELATIVE_URL_ROOT" to "/myapp"
|
125
|
+
And I run `bundle exec vhost-generator`
|
126
|
+
Then the output should match /FILE GENERATED BY.*EDIT AT YOUR OWN RISK/
|
127
|
+
And the output should contain:
|
128
|
+
"""
|
129
|
+
upstream myupstream {
|
130
|
+
server localhost:5000 fail_timeout=0;
|
131
|
+
server localhost:5001 fail_timeout=0;
|
132
|
+
server localhost:5002 fail_timeout=0;
|
133
|
+
}
|
134
|
+
"""
|
135
|
+
And the output should contain:
|
136
|
+
"""
|
137
|
+
server {
|
138
|
+
listen 80;
|
139
|
+
listen 81;
|
140
|
+
"""
|
141
|
+
And the output should contain:
|
142
|
+
"""
|
143
|
+
server_name localhost, my.server;
|
144
|
+
"""
|
145
|
+
And the output should match /root.*html;/
|
146
|
+
And the output should contain:
|
147
|
+
"""
|
148
|
+
try_files $uri/index.html $uri @upstream;
|
149
|
+
location @upstream {
|
150
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
151
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
152
|
+
proxy_set_header Host $http_host;
|
153
|
+
proxy_redirect off;
|
154
|
+
proxy_pass http://myupstream;
|
155
|
+
}
|
156
|
+
"""
|
157
|
+
And the output should contain:
|
158
|
+
"""
|
159
|
+
location /myapp/assets {
|
160
|
+
gzip_static on; # to serve pre-gzipped version
|
161
|
+
expires 60d;
|
162
|
+
add_header Cache-Control public;
|
163
|
+
}
|
164
|
+
"""
|
165
|
+
And the output should contain:
|
166
|
+
"""
|
167
|
+
error_page 500 502 503 504 /500.html;
|
168
|
+
client_max_body_size 4G;
|
169
|
+
keepalive_timeout 10;
|
170
|
+
}
|
171
|
+
"""
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'aruba/cucumber'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Feature: Output program version
|
2
|
+
|
3
|
+
In order to know if I am up to date
|
4
|
+
As a user of the library
|
5
|
+
I want to know the current version of vhost-generator.
|
6
|
+
|
7
|
+
Scenario: output program version
|
8
|
+
When I run `bundle exec vhost-generator --version`
|
9
|
+
Then it should pass with:
|
10
|
+
"""
|
11
|
+
vhost-generator, version 0.1.0
|
12
|
+
"""
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'vhost_generator/version'
|
2
|
+
require 'vhost_generator/vhost_configuration'
|
3
|
+
require 'optparse'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'dotenv'
|
6
|
+
|
7
|
+
module VhostGenerator
|
8
|
+
|
9
|
+
###########################################################################
|
10
|
+
# VhostGenerator main application object. When invoking +vhost-generator+
|
11
|
+
# from the command line, a VhostGenerator::Application object is created
|
12
|
+
# and run.
|
13
|
+
#
|
14
|
+
class Application
|
15
|
+
attr_writer :config
|
16
|
+
|
17
|
+
def initialize(output_stream=$stdout)
|
18
|
+
@name = File.basename($0 || 'vhost-generator')
|
19
|
+
@output_stream = output_stream
|
20
|
+
end
|
21
|
+
|
22
|
+
# Run the VhostGenerator application.
|
23
|
+
def run
|
24
|
+
standard_exception_handling do
|
25
|
+
# load serialized environment variables from DOTENV files if present.
|
26
|
+
dotenvs = ['.env', ENV['DOTENV']]
|
27
|
+
dotenvs.compact.each { |f| Dotenv.load(f) }
|
28
|
+
handle_env(ENV)
|
29
|
+
handle_options(ARGV)
|
30
|
+
config.cmdline << ['cd', Dir.pwd]
|
31
|
+
config.cmdline << [$0] + ARGV
|
32
|
+
@output_stream.puts config.output
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def config(configurator=VhostGenerator::VhostConfiguration)
|
37
|
+
@config ||= configurator.new # XXX
|
38
|
+
end
|
39
|
+
|
40
|
+
def handle_env(env)
|
41
|
+
if path = env['STATIC_FOLDER']
|
42
|
+
config.static_folder = path
|
43
|
+
end
|
44
|
+
if ports = env['SERVER_PORTS']
|
45
|
+
config.server_ports = ports
|
46
|
+
end
|
47
|
+
if names = env['SERVER_NAMES']
|
48
|
+
config.server_names = names
|
49
|
+
end
|
50
|
+
if ports = env['INSTANCE_PORTS']
|
51
|
+
config.instance_ports = ports
|
52
|
+
end
|
53
|
+
if root = env['RAILS_RELATIVE_URL_ROOT']
|
54
|
+
config.relative_root = root
|
55
|
+
end
|
56
|
+
if generator = env['GENERATOR']
|
57
|
+
config.generator = generator
|
58
|
+
end
|
59
|
+
if options = env['GENERATOR_OPTIONS']
|
60
|
+
config.generator_options = options
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def handle_options(argv)
|
65
|
+
OptionParser.new do |opts|
|
66
|
+
opts.banner = "Usage: #{@name} [options]"
|
67
|
+
|
68
|
+
opts.separator ""
|
69
|
+
opts.separator ['Note: all command-line options below also exist as ' \
|
70
|
+
'environment variables.', 'You may try to setenv all ' \
|
71
|
+
'uppercase names in the rest of this summary, eg.',
|
72
|
+
'`export RAILS_RELATIVE_URL_ROOT=/myapp`.'].join($/)
|
73
|
+
|
74
|
+
opts.separator ""
|
75
|
+
opts.separator "Application options:"
|
76
|
+
application_options.each { |args| opts.on(*args) }
|
77
|
+
|
78
|
+
opts.separator ""
|
79
|
+
opts.separator "Generator options:"
|
80
|
+
generator_options.each { |args| opts.on(*args) }
|
81
|
+
|
82
|
+
opts.separator ""
|
83
|
+
|
84
|
+
opts.on_tail("-v", "--version", "Display the program version.") do
|
85
|
+
@output_stream.puts "#{@name}, version #{VhostGenerator::VERSION}"
|
86
|
+
exit(true)
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on_tail("-h", "--help", "-H", "Display this help message.") do
|
90
|
+
@output_stream.puts opts
|
91
|
+
exit(true)
|
92
|
+
end
|
93
|
+
end.parse(argv)
|
94
|
+
end
|
95
|
+
|
96
|
+
def application_options
|
97
|
+
[
|
98
|
+
['-f', '--static-folder STATIC_FOLDER',
|
99
|
+
%q{Path of your application's static folder (e.g. public/)},
|
100
|
+
lambda { |value| config.static_folder = value }],
|
101
|
+
['-l', '--listen SERVER_PORTS',
|
102
|
+
%q{Public ports to listen on (e.g. 80,81)},
|
103
|
+
lambda { |value| config.server_ports = value }],
|
104
|
+
['-s', '--server-name SERVER_NAMES',
|
105
|
+
%q{Server names to listen on (e.g. localhost,example.com)},
|
106
|
+
lambda { |value| config.server_names = value }],
|
107
|
+
['-p', '--instance-port INSTANCE_PORTS',
|
108
|
+
%q{Internal ports where instances listen on (e.g. 5000,5001)},
|
109
|
+
lambda { |value| config.instance_ports = value }],
|
110
|
+
['-r', '--relative-root RAILS_RELATIVE_URL_ROOT',
|
111
|
+
lambda { |value| config.relative_root = value }],
|
112
|
+
]
|
113
|
+
end
|
114
|
+
|
115
|
+
def generator_options
|
116
|
+
[
|
117
|
+
['-g', '--generator GENERATOR',
|
118
|
+
%q{Generator to use to output virtualhost configuration file},
|
119
|
+
lambda { |value| config.generator = value }],
|
120
|
+
['-o', '--generator-options GENERATOR_OPTIONS',
|
121
|
+
%q{Generator options as comma-separated list of key=value},
|
122
|
+
lambda { |value| config.generator_options = value }],
|
123
|
+
].freeze
|
124
|
+
end
|
125
|
+
|
126
|
+
# Provide standard exception handling for the given block.
|
127
|
+
def standard_exception_handling
|
128
|
+
begin
|
129
|
+
yield
|
130
|
+
rescue SystemExit => ex
|
131
|
+
# Exit silently with current status
|
132
|
+
raise
|
133
|
+
rescue OptionParser::InvalidOption => ex
|
134
|
+
$stderr.puts ex.message
|
135
|
+
exit(false)
|
136
|
+
rescue Exception => ex
|
137
|
+
# Exit with error message
|
138
|
+
display_error_message(ex)
|
139
|
+
exit(false)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Display the error message that caused the exception.
|
144
|
+
def display_error_message(ex)
|
145
|
+
$stderr.puts "#{@name} aborted!"
|
146
|
+
$stderr.puts ex.message
|
147
|
+
$stderr.puts ex.backtrace.join("\n")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module VhostGenerator
|
5
|
+
|
6
|
+
# Nginx VhostGenerator
|
7
|
+
#
|
8
|
+
class NginxGenerator
|
9
|
+
attr_reader :cfg, :options
|
10
|
+
def initialize(cfg, options={})
|
11
|
+
@cfg = cfg
|
12
|
+
@options = OpenStruct.new(default_options.merge(options)).freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def render
|
16
|
+
template.result(binding)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def default_options
|
22
|
+
Hash[ 'client_max_body_size' => '4G', 'keepalive_timeout' => '10',
|
23
|
+
'assets_expire_in' => '60d', 'upstream' => 'appservers' ].freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def template
|
29
|
+
@template ||= ERB.new <<EOF
|
30
|
+
#### FILE GENERATED BY `<%= String(cfg.cmdline) %>`, EDIT AT YOUR OWN RISK ####
|
31
|
+
|
32
|
+
upstream <%= options.upstream %> {
|
33
|
+
<% cfg.instance_ports.each do |p| %> server localhost:<%= p %> fail_timeout=0;
|
34
|
+
<% end %>}
|
35
|
+
|
36
|
+
server {
|
37
|
+
<% cfg.server_ports.each do |p| %>listen <%= p %>;
|
38
|
+
<% end %>
|
39
|
+
<% unless cfg.server_names.empty? %>server_name <%=
|
40
|
+
cfg.server_names.join(', ') %>;<% end %>
|
41
|
+
|
42
|
+
root <%= cfg.static_folder %>;
|
43
|
+
|
44
|
+
try_files $uri/index.html $uri @upstream;
|
45
|
+
location @upstream {
|
46
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
47
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
48
|
+
proxy_set_header Host $http_host;
|
49
|
+
proxy_redirect off;
|
50
|
+
proxy_pass http://<%= options.upstream %>;
|
51
|
+
}
|
52
|
+
|
53
|
+
location <%= cfg.relative_root %>assets {
|
54
|
+
gzip_static on; # to serve pre-gzipped version
|
55
|
+
expires <%= options.assets_expire_in %>;
|
56
|
+
add_header Cache-Control public;
|
57
|
+
}
|
58
|
+
|
59
|
+
error_page 500 502 503 504 /500.html;
|
60
|
+
client_max_body_size <%= options.client_max_body_size %>;
|
61
|
+
keepalive_timeout <%= options.keepalive_timeout %>;
|
62
|
+
}
|
63
|
+
EOF
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'vhost_generator/nginx_generator'
|
2
|
+
require 'shellwords'
|
3
|
+
|
4
|
+
module VhostGenerator
|
5
|
+
|
6
|
+
# Represents a Shell command line (to display in vhost comments)
|
7
|
+
# TODO: make it a real class with a more narrow interface than Array
|
8
|
+
class ShellCmdLine < Array
|
9
|
+
def to_str
|
10
|
+
parts = self.collect { |cmd| Shellwords.join(cmd) }
|
11
|
+
if parts.length > 1
|
12
|
+
"(" + parts.join(' && ') + ")"
|
13
|
+
else
|
14
|
+
parts.join
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
###########################################################################
|
20
|
+
# VhostConfiguration stores all the configuration values (to read from)
|
21
|
+
# +env+ or +cmdline+ needed to render the configuration template.
|
22
|
+
#
|
23
|
+
class VhostConfiguration
|
24
|
+
attr_reader :static_folder, :server_ports, :server_names,
|
25
|
+
:instance_ports, :relative_root, :cmdline,
|
26
|
+
:generator, :generator_options
|
27
|
+
|
28
|
+
def initialize(static_folder='public', server_ports='80',
|
29
|
+
server_names='localhost', instance_ports='', relative_root='/',
|
30
|
+
cmdlinebuilder=ShellCmdLine, generator='nginx', generator_options='')
|
31
|
+
self.static_folder = static_folder
|
32
|
+
self.server_ports = server_ports
|
33
|
+
self.server_names = server_names
|
34
|
+
self.instance_ports = instance_ports
|
35
|
+
self.relative_root = relative_root
|
36
|
+
self.cmdline = cmdlinebuilder.new
|
37
|
+
self.generator = generator
|
38
|
+
self.generator_options = generator_options
|
39
|
+
end
|
40
|
+
|
41
|
+
def static_folder=(folder)
|
42
|
+
@static_folder = File.expand_path(folder)
|
43
|
+
end
|
44
|
+
|
45
|
+
def server_ports=(ports)
|
46
|
+
@server_ports = parse_integer_list(ports)
|
47
|
+
end
|
48
|
+
|
49
|
+
def server_names=(names)
|
50
|
+
@server_names = parse_word_list(names)
|
51
|
+
end
|
52
|
+
|
53
|
+
def instance_ports=(ports)
|
54
|
+
@instance_ports = parse_integer_list(ports)
|
55
|
+
end
|
56
|
+
|
57
|
+
def relative_root=(root)
|
58
|
+
@relative_root = (String(root) + '/').gsub(%r{/+}, '/')
|
59
|
+
end
|
60
|
+
|
61
|
+
def generator=(name)
|
62
|
+
@generator = generator_for(name)
|
63
|
+
end
|
64
|
+
|
65
|
+
def generator_options=(options)
|
66
|
+
@generator_options = parse_option_list(options)
|
67
|
+
end
|
68
|
+
|
69
|
+
def configure!(parser)
|
70
|
+
parser.parse(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def output
|
74
|
+
self.generator.new(self, self.generator_options).render
|
75
|
+
end
|
76
|
+
|
77
|
+
protected
|
78
|
+
|
79
|
+
attr_writer :cmdline
|
80
|
+
|
81
|
+
def generator_for(name)
|
82
|
+
raise ArgumentError, "unsupported generator: %s, try any of %s." % [
|
83
|
+
name.inspect, registry.keys.inspect
|
84
|
+
] unless registry.has_key?(name)
|
85
|
+
registry[name]
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
attr_writer :registry
|
91
|
+
def registry
|
92
|
+
# XXX use a real registry to reduce coupling
|
93
|
+
@registry ||= {'nginx' => VhostGenerator::NginxGenerator}
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_word_list(s)
|
97
|
+
String(s).split(/[,\s]+/)
|
98
|
+
end
|
99
|
+
|
100
|
+
def parse_option_list(s)
|
101
|
+
Hash[ parse_word_list(s).map { |i| i.split('=', 2) } ]
|
102
|
+
end
|
103
|
+
|
104
|
+
def parse_integer_list(s)
|
105
|
+
parse_word_list(s).map { |i| Integer(i) }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'vhost_generator/application'
|
2
|
+
|
3
|
+
module VhostGenerator
|
4
|
+
|
5
|
+
# VhostGenerator module singleton methods.
|
6
|
+
#
|
7
|
+
class << self
|
8
|
+
# Current VhostGenerator Application
|
9
|
+
def application
|
10
|
+
@application ||= VhostGenerator::Application.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set the current VhostGenerator application object.
|
14
|
+
def application=(app)
|
15
|
+
@application = app
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'vhost_generator/application'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe VhostGenerator::Application do
|
5
|
+
describe "Env" do
|
6
|
+
let(:config) { OpenStruct.new }
|
7
|
+
before { subject.config = config }
|
8
|
+
|
9
|
+
options = Hash[
|
10
|
+
'static_folder' => 'STATIC_FOLDER',
|
11
|
+
'server_ports' => 'SERVER_PORTS',
|
12
|
+
'server_names' => 'SERVER_NAMES',
|
13
|
+
'instance_ports' => 'INSTANCE_PORTS',
|
14
|
+
'relative_root' => 'RAILS_RELATIVE_URL_ROOT',
|
15
|
+
'generator' => 'GENERATOR',
|
16
|
+
'generator_options' => 'GENERATOR_OPTIONS',
|
17
|
+
]
|
18
|
+
|
19
|
+
options.each_pair do |name, var|
|
20
|
+
describe "#{name} option" do
|
21
|
+
it "is set by the #{var} variable" do
|
22
|
+
expect {
|
23
|
+
subject.handle_env(var => 'value')
|
24
|
+
}.to change(config, name).to('value')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'vhost_generator/application'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe VhostGenerator::Application do
|
5
|
+
describe "Options" do
|
6
|
+
let(:config) { OpenStruct.new }
|
7
|
+
before { subject.config = config }
|
8
|
+
|
9
|
+
options = Hash[
|
10
|
+
'static_folder' => %w(-f --static-folder),
|
11
|
+
'server_ports' => %w(-l --listen),
|
12
|
+
'server_names' => %w(-s --server-name),
|
13
|
+
'instance_ports' => %w(-p --instance-port),
|
14
|
+
'relative_root' => %w(-r --relative-root),
|
15
|
+
'generator' => %w(-g --generator),
|
16
|
+
'generator_options' => %w(-o --generator-options)
|
17
|
+
]
|
18
|
+
|
19
|
+
options.each_pair do |name, flags|
|
20
|
+
describe "#{name} option" do
|
21
|
+
flags.each do |flag|
|
22
|
+
it "is set by the #{flag} flag" do
|
23
|
+
expect {
|
24
|
+
subject.handle_options([flag, 'value'])
|
25
|
+
}.to change(config, name).to('value')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'vhost_generator/nginx_generator'
|
2
|
+
|
3
|
+
describe VhostGenerator::NginxGenerator do
|
4
|
+
let(:config) { double('vhost config').as_null_object }
|
5
|
+
subject do
|
6
|
+
described_class.new(config, 'upstream' => 'myupstream')
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#render" do
|
10
|
+
let(:output) { subject.render }
|
11
|
+
|
12
|
+
it "includes the cmdline in a comment" do
|
13
|
+
config.stub(:cmdline).and_return('CMDLINE')
|
14
|
+
expect(output).to match(/^#### FILE GENERATED BY .*CMDLINE/)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "declares the named upstream" do
|
18
|
+
expect(output).to include('upstream myupstream {')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "references the named upstream" do
|
22
|
+
expect(output).to include('http://myupstream;')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "declares all the requested upstream servers" do
|
26
|
+
config.stub(:instance_ports).and_return([1337, 1338])
|
27
|
+
expect(output).to include('server localhost:1337 fail_timeout=0;')
|
28
|
+
expect(output).to include('server localhost:1338 fail_timeout=0;')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "listens to the requested server ports" do
|
32
|
+
config.stub(:server_ports).and_return([12345, 12346])
|
33
|
+
expect(output).to include('listen 12345;')
|
34
|
+
expect(output).to include('listen 12346;')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "declares the server names it responds to" do
|
38
|
+
config.stub(:server_names).and_return(%w(host1 host2))
|
39
|
+
expect(output).to include('server_name host1, host2;')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "declares the requested document root" do
|
43
|
+
config.stub(:static_folder).and_return('STATIC-FOLDER')
|
44
|
+
expect(output).to include('root STATIC-FOLDER;')
|
45
|
+
end
|
46
|
+
|
47
|
+
it "forwards X-Forwarded-For header" do
|
48
|
+
expect(output).to \
|
49
|
+
include('proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;')
|
50
|
+
end
|
51
|
+
|
52
|
+
it "forwards X-Forwarded-Proto header" do
|
53
|
+
expect(output).to include('proxy_set_header X-Forwarded-Proto $scheme;')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "respects custom relative_roots" do
|
57
|
+
config.stub(:relative_root).and_return('RELATIVE_ROOT')
|
58
|
+
expect(output).to include('location RELATIVE_ROOTassets {')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'vhost_generator/vhost_configuration'
|
2
|
+
|
3
|
+
describe VhostGenerator::VhostConfiguration do
|
4
|
+
describe "#static_folder" do
|
5
|
+
it "is 'public/' by default" do
|
6
|
+
expect(subject.static_folder).to eql(File.expand_path('public'))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "expanded" do
|
10
|
+
expect {
|
11
|
+
subject.static_folder = 'html'
|
12
|
+
}.to change(subject, :static_folder).to File.expand_path('html')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#server_ports" do
|
17
|
+
it "is 80 by default" do
|
18
|
+
expect(subject.server_ports).to eql([80])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "parses to Array of Integer" do
|
22
|
+
expect {
|
23
|
+
subject.server_ports = '80,81'
|
24
|
+
}.to change(subject, :server_ports).to [80, 81]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "complains when trying to set invalid values" do
|
28
|
+
expect {
|
29
|
+
subject.server_ports = '80a'
|
30
|
+
}.to raise_error(ArgumentError, /invalid value for Integer/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#server_names" do
|
35
|
+
it "is 'localhost' by default" do
|
36
|
+
expect(subject.server_names).to eql(%w(localhost))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "parses to Array of String" do
|
40
|
+
expect {
|
41
|
+
subject.server_names = 'localhost , test.host'
|
42
|
+
}.to change(subject, :server_names).to %w(localhost test.host)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#instance_ports" do
|
47
|
+
it "is empty by default" do
|
48
|
+
expect(subject.instance_ports).to be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it "parses to Array of Integer" do
|
52
|
+
expect {
|
53
|
+
subject.instance_ports = '5000,5001'
|
54
|
+
}.to change(subject, :instance_ports).to [5000, 5001]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "complains when trying to set invalid values" do
|
58
|
+
expect {
|
59
|
+
subject.instance_ports = '5000a'
|
60
|
+
}.to raise_error(ArgumentError, /invalid value for Integer/)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#relative_root" do
|
65
|
+
it "is '/' by default" do
|
66
|
+
expect(subject.relative_root).to eql('/')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "appends '/' at end" do
|
70
|
+
expect {
|
71
|
+
subject.relative_root = '/myapp'
|
72
|
+
}.to change(subject, :relative_root).to '/myapp/'
|
73
|
+
end
|
74
|
+
|
75
|
+
it "strips redundant slashes" do
|
76
|
+
expect {
|
77
|
+
subject.relative_root = '/path//to///myapp////'
|
78
|
+
}.to change(subject, :relative_root).to '/path/to/myapp/'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#cmdline" do
|
83
|
+
it "is empty by default" do
|
84
|
+
subject.cmdline.should be_empty
|
85
|
+
end
|
86
|
+
|
87
|
+
it "can be append to using the shovel operator" do
|
88
|
+
subject.cmdline.should respond_to(:<<)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "can be coerced into string" do
|
92
|
+
subject.cmdline.should respond_to(:to_str)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#generator" do
|
97
|
+
it "is present by default" do
|
98
|
+
expect(subject.generator).to be
|
99
|
+
end
|
100
|
+
|
101
|
+
it "is resolved into a generator plugin" do
|
102
|
+
generator = double('generator')
|
103
|
+
subject.send(:registry).merge!('test' => generator)
|
104
|
+
expect {
|
105
|
+
subject.generator = 'test'
|
106
|
+
}.to change(subject, :generator).to generator
|
107
|
+
end
|
108
|
+
|
109
|
+
it "complains when trying to set invalid values" do
|
110
|
+
expect {
|
111
|
+
subject.generator = 'xyzzy'
|
112
|
+
}.to raise_error(ArgumentError, /unsupported generator/)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#generator_options" do
|
117
|
+
it "is empty by default" do
|
118
|
+
expect(subject.generator_options).to be_empty
|
119
|
+
end
|
120
|
+
|
121
|
+
it "parses to Hash[key=value]" do
|
122
|
+
expect {
|
123
|
+
subject.generator_options = 'k=a=b , l=j'
|
124
|
+
}.to change(subject, :generator_options).to Hash['k' => 'a=b', 'l' => 'j']
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'vhost_generator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "vhost_generator"
|
8
|
+
gem.version = VhostGenerator::VERSION
|
9
|
+
gem.authors = ["Julien Pervillé"]
|
10
|
+
gem.email = ["julien.perville@mingalar.fr"]
|
11
|
+
gem.description = ['vhost_generator outputs a general-purpose VirtualHost',
|
12
|
+
'configuration file to run your web application behind',
|
13
|
+
'an nginx or apache frontend'].join(' ')
|
14
|
+
gem.summary = ['vhost_generator outputs nginx or apache VirtualHost',
|
15
|
+
'configurations to run your web application'].join(' ')
|
16
|
+
gem.homepage = "https://github.com/mingalar/vhost_generator"
|
17
|
+
|
18
|
+
gem.files = `git ls-files`.split($/)
|
19
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
|
23
|
+
gem.add_runtime_dependency('dotenv', '~> 0.2.0')
|
24
|
+
gem.add_development_dependency('rake', '~> 0.9.2.2')
|
25
|
+
gem.add_development_dependency('cucumber', '~> 1.2.1')
|
26
|
+
gem.add_development_dependency('aruba', '~> 0.4.11')
|
27
|
+
gem.add_development_dependency('rspec', '~> 2.11.0')
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vhost_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Julien Pervillé
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: dotenv
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.2.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.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.9.2.2
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.9.2.2
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: cucumber
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.1
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.2.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: aruba
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.4.11
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.4.11
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 2.11.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 2.11.0
|
94
|
+
description: vhost_generator outputs a general-purpose VirtualHost configuration file
|
95
|
+
to run your web application behind an nginx or apache frontend
|
96
|
+
email:
|
97
|
+
- julien.perville@mingalar.fr
|
98
|
+
executables:
|
99
|
+
- vhost-generator
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- bin/vhost-generator
|
109
|
+
- features/help.feature
|
110
|
+
- features/output-nginx.feature
|
111
|
+
- features/step_definitions/dev_steps.rb
|
112
|
+
- features/support/env.rb
|
113
|
+
- features/version.feature
|
114
|
+
- lib/vhost_generator.rb
|
115
|
+
- lib/vhost_generator/application.rb
|
116
|
+
- lib/vhost_generator/nginx_generator.rb
|
117
|
+
- lib/vhost_generator/version.rb
|
118
|
+
- lib/vhost_generator/vhost_configuration.rb
|
119
|
+
- lib/vhost_generator/vhost_generator_module.rb
|
120
|
+
- spec/application_env_spec.rb
|
121
|
+
- spec/application_options_spec.rb
|
122
|
+
- spec/nginx_generator_spec.rb
|
123
|
+
- spec/vhost_configuration_spec.rb
|
124
|
+
- vhost_generator.gemspec
|
125
|
+
homepage: https://github.com/mingalar/vhost_generator
|
126
|
+
licenses: []
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
hash: -198369393
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
segments:
|
147
|
+
- 0
|
148
|
+
hash: -198369393
|
149
|
+
requirements: []
|
150
|
+
rubyforge_project:
|
151
|
+
rubygems_version: 1.8.23
|
152
|
+
signing_key:
|
153
|
+
specification_version: 3
|
154
|
+
summary: vhost_generator outputs nginx or apache VirtualHost configurations to run
|
155
|
+
your web application
|
156
|
+
test_files:
|
157
|
+
- features/help.feature
|
158
|
+
- features/output-nginx.feature
|
159
|
+
- features/step_definitions/dev_steps.rb
|
160
|
+
- features/support/env.rb
|
161
|
+
- features/version.feature
|
162
|
+
- spec/application_env_spec.rb
|
163
|
+
- spec/application_options_spec.rb
|
164
|
+
- spec/nginx_generator_spec.rb
|
165
|
+
- spec/vhost_configuration_spec.rb
|