vhost_generator 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -8,10 +8,8 @@ also every time the virtualhost parameters (such as the number of instances to
8
8
  run and the ports where the instances are listening).
9
9
 
10
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`.
11
+ * reading configuration parameters from `ENV` (or from the `.env` file if invoked via `foreman run`)
12
+
15
13
 
16
14
  ## Installation
17
15
 
@@ -37,27 +35,23 @@ Advanced usage: all command-line switches have their equivalent environment vari
37
35
 
38
36
  $ SERVER_PORTS=80 SERVER_NAMES=myapp.com INSTANCE_PORTS=5000,5001,5002 bundle exec vhost-generator
39
37
 
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
38
  More advanced usages: see `features/` directory or run:
47
39
 
48
40
  $ bundle exec vhost-generator --help
49
41
 
50
42
  ## Tips
51
43
 
52
- Protip: pipe with `sudo tee` to save the configuration in your nginx sites-enabled directory.
44
+ Pipe with `sudo tee` to save the configuration in your nginx sites-enabled directory.
53
45
 
54
46
  $ bundle exec vhost-generator -l 80 -s myapp.com -p 5000,5001,5002 | sudo tee /etc/nginx/sites-enabled/myapp
55
47
 
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)
48
+ Run through `foreman run` to leverage your application's `.env` (DRY and handy when having a configured `RAILS_RELATIVE_URL_ROOT` for example).
57
49
 
58
50
  $ echo RAILS_RELATIVE_URL_ROOT='/myapp' >> .env
59
51
  $ bundle exec foreman run vhost-generator -l 80 -s myapp.com -p 5000,5001,5002
60
52
 
53
+ Check the comment at top of each virtualhost configuration file for a command-line that can regenerate the file.
54
+
61
55
  ## Contributing
62
56
 
63
57
  1. Fork it
@@ -53,67 +53,6 @@ Feature: Output nginx configuration file
53
53
  }
54
54
  """
55
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
56
  Scenario: using environment variables
118
57
  When I set env variable "GENERATOR" to "nginx"
119
58
  And I set env variable "GENERATOR_OPTIONS" to "upstream=myupstream"
@@ -8,5 +8,5 @@ Feature: Output program version
8
8
  When I run `bundle exec vhost-generator --version`
9
9
  Then it should pass with:
10
10
  """
11
- vhost-generator, version 0.1.0
11
+ vhost-generator, version 0.2.0
12
12
  """
@@ -1,8 +1,7 @@
1
1
  require 'vhost_generator/version'
2
+ require 'vhost_generator/cmdline_builder'
2
3
  require 'vhost_generator/vhost_configuration'
3
4
  require 'optparse'
4
- require 'ostruct'
5
- require 'dotenv'
6
5
 
7
6
  module VhostGenerator
8
7
 
@@ -22,13 +21,9 @@ module VhostGenerator
22
21
  # Run the VhostGenerator application.
23
22
  def run
24
23
  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
24
  handle_env(ENV)
29
25
  handle_options(ARGV)
30
- config.cmdline << ['cd', Dir.pwd]
31
- config.cmdline << [$0] + ARGV
26
+ config.cmdline = CmdlineBuilder.new(config, Dir.pwd, $0, ENV)
32
27
  @output_stream.puts config.output
33
28
  end
34
29
  end
@@ -0,0 +1,60 @@
1
+ require 'shellwords'
2
+
3
+ module VhostGenerator
4
+
5
+ # Represents a Shell command line (to display in vhost comments)
6
+ class CmdlineBuilder
7
+ attr_writer :config, :cwd, :progname, :env
8
+
9
+ def initialize(config, cwd, progname, env)
10
+ self.config = config
11
+ self.cwd = cwd
12
+ self.progname = progname
13
+ self.env = env
14
+ end
15
+
16
+ def cwd
17
+ @cwd ? ['cd', @cwd] : nil
18
+ end
19
+
20
+ def progname
21
+ if @progname
22
+ if @env.keys.grep(/^BUNDLE_/).empty?
23
+ [@progname]
24
+ else
25
+ ['bundle', 'exec', File.basename(@progname)]
26
+ end
27
+ end
28
+ end
29
+
30
+ def progargs
31
+ args = []
32
+ args << '-f' << @config.static_folder
33
+ args << '-l' << @config.server_ports.join(',')
34
+ args << '-s' << @config.server_names.join(',')
35
+ args << '-p' << @config.instance_ports.join(',')
36
+ args << '-r' << @config.relative_root
37
+ args << '-g' << 'nginx' # FIXME use @config.generator when real registry
38
+ options = @config.generator_options.collect {|k,v| "#{k}=#{v}" }
39
+ args << '-o' << options.join(',')
40
+ args
41
+ end
42
+
43
+ def commands
44
+ if prog_name = progname
45
+ [cwd, prog_name + progargs].compact
46
+ else
47
+ []
48
+ end
49
+ end
50
+
51
+ def to_str
52
+ parts = commands.collect { |cmd| Shellwords.shelljoin(cmd) }
53
+ if parts.length > 1
54
+ "(#{ parts.join(' && ') })"
55
+ else
56
+ parts.first
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,3 +1,3 @@
1
1
  module VhostGenerator
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -3,37 +3,25 @@ require 'shellwords'
3
3
 
4
4
  module VhostGenerator
5
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
6
  ###########################################################################
20
7
  # VhostConfiguration stores all the configuration values (to read from)
21
8
  # +env+ or +cmdline+ needed to render the configuration template.
22
9
  #
23
10
  class VhostConfiguration
24
11
  attr_reader :static_folder, :server_ports, :server_names,
25
- :instance_ports, :relative_root, :cmdline,
12
+ :instance_ports, :relative_root,
26
13
  :generator, :generator_options
14
+ attr_accessor :cmdline
27
15
 
28
16
  def initialize(static_folder='public', server_ports='80',
29
17
  server_names='localhost', instance_ports='', relative_root='/',
30
- cmdlinebuilder=ShellCmdLine, generator='nginx', generator_options='')
18
+ generator='nginx', generator_options='', cmdline=nil)
31
19
  self.static_folder = static_folder
32
20
  self.server_ports = server_ports
33
21
  self.server_names = server_names
34
22
  self.instance_ports = instance_ports
35
23
  self.relative_root = relative_root
36
- self.cmdline = cmdlinebuilder.new
24
+ self.cmdline = cmdline # usually set later using attr_writer
37
25
  self.generator = generator
38
26
  self.generator_options = generator_options
39
27
  end
@@ -76,8 +64,6 @@ module VhostGenerator
76
64
 
77
65
  protected
78
66
 
79
- attr_writer :cmdline
80
-
81
67
  def generator_for(name)
82
68
  raise ArgumentError, "unsupported generator: %s, try any of %s." % [
83
69
  name.inspect, registry.keys.inspect
data/script/cibuild ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ bundle install --path .bundle
6
+
7
+ bundle exec rake features
8
+
9
+ bundle exec rake spec
@@ -0,0 +1,106 @@
1
+ require 'vhost_generator/cmdline_builder'
2
+
3
+ describe VhostGenerator::CmdlineBuilder do
4
+ let(:config) { double('vhost config').as_null_object }
5
+ subject do
6
+ described_class.new(config, nil, nil, [])
7
+ end
8
+
9
+ describe "#cwd" do
10
+ context "when a current directory is provided" do
11
+ it "returns 'cd' followed by the current directory" do
12
+ subject.cwd = 'CWD'
13
+ expect(subject.cwd).to eql(['cd', 'CWD'])
14
+ end
15
+ end
16
+
17
+ context "when no current directory is provided" do
18
+ it "is nil" do
19
+ subject.cwd = nil
20
+ expect(subject.cwd).to be_nil
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#progname" do
26
+ before { subject.progname = '/path/to/progname' }
27
+
28
+ context "when no progname is provided" do
29
+ it "is nil" do
30
+ subject.progname = nil
31
+ expect(subject.progname).to be_nil
32
+ end
33
+ end
34
+
35
+ context "when bundler is in environment" do
36
+ it "returns 'bundle exec' followed by the basename" do
37
+ subject.env = Hash['BUNDLE_GEMFILE' => true, 'BUNDLE_BIN' => 'true']
38
+ expect(subject.progname).to eql(['bundle', 'exec', 'progname'])
39
+ end
40
+ end
41
+
42
+ context "when bundler is not in environment" do
43
+ it "returns the full program name" do
44
+ subject.env = Hash[]
45
+ expect(subject.progname).to eql(['/path/to/progname'])
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#progargs" do
51
+ it "describes config as commandline switches" do
52
+ subject.config = mock(:static_folder => 'SF', :server_ports => [80,81],
53
+ :server_names => %w(A B),
54
+ :instance_ports => [5000,5001],
55
+ :relative_root => 'RR', :generator => 'nginx',
56
+ :generator_options => {'k' => 'a=b', 'l' => 'c'})
57
+ expect(subject.progargs).to eql(['-f', 'SF', '-l', '80,81', '-s', 'A,B',
58
+ '-p', '5000,5001', '-r', 'RR',
59
+ '-g', 'nginx', '-o', 'k=a=b,l=c'])
60
+ end
61
+ end
62
+
63
+ describe "#commands" do
64
+ context "when a pwd is present" do
65
+ it "is same as [#pwd, #progname + #progargs]" do
66
+ subject.should_receive(:cwd).and_return('CWD')
67
+ subject.should_receive(:progname).and_return('PROGNAME')
68
+ subject.should_receive(:progargs).and_return('ARGS')
69
+ expect(subject.commands).to eql(['CWD', 'PROGNAMEARGS'])
70
+ end
71
+ end
72
+
73
+ context "when no pwd is present" do
74
+ it "is same as [#progname + #progargs]" do
75
+ subject.should_receive(:cwd).and_return(nil)
76
+ subject.should_receive(:progname).and_return('PROGNAME')
77
+ subject.should_receive(:progargs).and_return('ARGS')
78
+ expect(subject.commands).to eql(['PROGNAMEARGS'])
79
+ end
80
+ end
81
+
82
+ context "when no progname is present" do
83
+ it "is empty" do
84
+ subject.should_receive(:progname).and_return(nil)
85
+ expect(subject.commands).to be_empty
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "#to_str" do
91
+ let(:cmd1) { %w(cd /path/to/directory) }
92
+ let(:cmd2) { %w(bundle exec progname -x arg -y arg2) }
93
+
94
+ it "is escaped #commands" do
95
+ subject.should_receive(:commands).and_return([cmd2])
96
+ cmdline = "bundle exec progname -x arg -y arg2"
97
+ expect(subject.to_str).to eql(cmdline)
98
+ end
99
+
100
+ it "is escaped #commands joined by && & parenthesis" do
101
+ subject.should_receive(:commands).and_return([cmd1, cmd2])
102
+ cmdline = "(cd /path/to/directory && bundle exec progname -x arg -y arg2)"
103
+ expect(subject.to_str).to eql(cmdline)
104
+ end
105
+ end
106
+ end
@@ -79,20 +79,6 @@ describe VhostGenerator::VhostConfiguration do
79
79
  end
80
80
  end
81
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
82
  describe "#generator" do
97
83
  it "is present by default" do
98
84
  expect(subject.generator).to be
@@ -17,10 +17,9 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.files = `git ls-files`.split($/)
19
19
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features|script)/})
21
21
  gem.require_paths = ["lib"]
22
22
 
23
- gem.add_runtime_dependency('dotenv', '~> 0.2.0')
24
23
  gem.add_development_dependency('rake', '~> 0.9.2.2')
25
24
  gem.add_development_dependency('cucumber', '~> 1.2.1')
26
25
  gem.add_development_dependency('aruba', '~> 0.4.11')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vhost_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-30 00:00:00.000000000 Z
12
+ date: 2012-10-01 00:00:00.000000000 Z
13
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
14
  - !ruby/object:Gem::Dependency
31
15
  name: rake
32
16
  requirement: !ruby/object:Gem::Requirement
@@ -113,12 +97,15 @@ files:
113
97
  - features/version.feature
114
98
  - lib/vhost_generator.rb
115
99
  - lib/vhost_generator/application.rb
100
+ - lib/vhost_generator/cmdline_builder.rb
116
101
  - lib/vhost_generator/nginx_generator.rb
117
102
  - lib/vhost_generator/version.rb
118
103
  - lib/vhost_generator/vhost_configuration.rb
119
104
  - lib/vhost_generator/vhost_generator_module.rb
105
+ - script/cibuild
120
106
  - spec/application_env_spec.rb
121
107
  - spec/application_options_spec.rb
108
+ - spec/cmdline_builder_spec.rb
122
109
  - spec/nginx_generator_spec.rb
123
110
  - spec/vhost_configuration_spec.rb
124
111
  - vhost_generator.gemspec
@@ -136,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
123
  version: '0'
137
124
  segments:
138
125
  - 0
139
- hash: -198369393
126
+ hash: -418120369
140
127
  required_rubygems_version: !ruby/object:Gem::Requirement
141
128
  none: false
142
129
  requirements:
@@ -145,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
132
  version: '0'
146
133
  segments:
147
134
  - 0
148
- hash: -198369393
135
+ hash: -418120369
149
136
  requirements: []
150
137
  rubyforge_project:
151
138
  rubygems_version: 1.8.23
@@ -159,7 +146,9 @@ test_files:
159
146
  - features/step_definitions/dev_steps.rb
160
147
  - features/support/env.rb
161
148
  - features/version.feature
149
+ - script/cibuild
162
150
  - spec/application_env_spec.rb
163
151
  - spec/application_options_spec.rb
152
+ - spec/cmdline_builder_spec.rb
164
153
  - spec/nginx_generator_spec.rb
165
154
  - spec/vhost_configuration_spec.rb