vhost_generator 0.1.0 → 0.2.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/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