noveku 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +41 -6
- data/lib/noveku/cli/base.rb +73 -0
- data/lib/noveku/cli/git.rb +12 -0
- data/lib/noveku/cli/heroku.rb +20 -0
- data/lib/noveku/config.rb +1 -1
- data/lib/noveku/console.rb +1 -1
- data/lib/noveku/core.rb +37 -14
- data/lib/noveku/deploy.rb +12 -0
- data/lib/noveku/exceptions.rb +1 -1
- data/lib/noveku/migrate.rb +1 -1
- data/lib/noveku/options.rb +15 -0
- data/lib/noveku/proxy.rb +2 -2
- data/lib/noveku/push.rb +12 -0
- data/lib/noveku/rake.rb +1 -1
- data/lib/noveku/tail.rb +1 -1
- data/lib/noveku/version.rb +1 -1
- data/spec/core_spec.rb +9 -11
- data/spec/deploy_spec.rb +10 -0
- data/spec/heroku_spec.rb +18 -0
- data/spec/options_spec.rb +28 -0
- data/spec/push_spec.rb +10 -0
- metadata +12 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -14,14 +14,34 @@ you should install it globally, not via bundler and your project's Gemfile.
|
|
14
14
|
|
15
15
|
## Usage
|
16
16
|
|
17
|
-
|
17
|
+
This gem is developed with Rails 3+ in mind. However, it should be suited to any project with a notion of "app environment", with different heroku apps for these environments.
|
18
18
|
|
19
|
-
|
19
|
+
`noveku production COMMAND` translate `COMMAND` in the context of the heroku remote `heroku-production`. When pushing/deploying, the local source branche is `production`. Please read the next two paragraphs for more detailed explications.
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
### Conventions
|
22
|
+
|
23
|
+
This gem makes a few assumptions about how your branches and remotes are named.
|
24
|
+
This is *not* configurable, and that there is no plans to change this.
|
25
|
+
|
26
|
+
* `origin` is the main git remote, pointing towards github, bitbucket, or any other server.
|
27
|
+
* if you have a branch named `novelys`, the heroku git remote corresponding this branch is assumed to be `heroku-novelys`.
|
28
|
+
|
29
|
+
Our git flow at Novelys is pretty straightforward : the branch `master` is the current version of the app; `staging` is the pre-production version; `production` the production one.
|
30
|
+
|
31
|
+
This translates to two heroku apps (the name of the apps does not matter), and the remotes named `heroku-staging` and `heroku-master` :
|
32
|
+
|
33
|
+
[remote "heroku-production"]
|
34
|
+
url = git@heroku.com:sampleapp.git
|
35
|
+
fetch = +refs/heads/*:refs/remotes/production/*
|
36
|
+
[remote "heroky-staging"]
|
37
|
+
url = git@heroku.com:sampleapp-preprod.git
|
38
|
+
fetch = +refs/heads/*:refs/remotes/staging/*
|
39
|
+
|
40
|
+
### Interface
|
41
|
+
|
42
|
+
Considering what is written above :
|
43
|
+
|
44
|
+
`noveku ENV COMMAND`: will execute the given `COMMAND` in the context of the `ENV` local branch and `heroku-ENV` heroku git remote.
|
25
45
|
|
26
46
|
## Heroku commands
|
27
47
|
|
@@ -37,6 +57,20 @@ This makes several other commands available, such as `restart`, `releases`, `ps`
|
|
37
57
|
|
38
58
|
## Advanced commands
|
39
59
|
|
60
|
+
### Git
|
61
|
+
|
62
|
+
Those commands are shortcuts for other git commands.
|
63
|
+
|
64
|
+
* `push`: Push your changes in your local branch to the `origin` remote.
|
65
|
+
* `deploy`: Push your changes in your local branch to the heroku remote.
|
66
|
+
|
67
|
+
They accept the following options:
|
68
|
+
|
69
|
+
* `--dry-run`: only prints the git command that is going to be executed, without executing it;
|
70
|
+
* `--verbose`: prints the git command that is going to be executed, and then execute it.
|
71
|
+
|
72
|
+
### MongoDB
|
73
|
+
|
40
74
|
* `mongodump`: Dumps the mongo database. Shortcut for both `mongolab_dump` and `mongohq_dump`: tries mongolab first, then mongohq.
|
41
75
|
* `mongolab_dump`: Dumps the mongo database. Look in the config keys of `ENV` to find `MONGOLAB_URI`.
|
42
76
|
* `mongohq_dump`: Dumps the mongo database. Look in the config keys of `ENV` to find `MONGOHQ_URL`.
|
@@ -58,6 +92,7 @@ I plan on adding a command allowing you to create a heroku app, setup your addon
|
|
58
92
|
|
59
93
|
## Changelog
|
60
94
|
|
95
|
+
* `0.6`: Adds `deploy` and `push`; assumes heroku remotes are prefixed with `heroku-`; enhanced README; internal refactoring.
|
61
96
|
* `0.5`: Test coverage, check the presence of environment & that it matches a heroku app, that pwd is a heroku app, the presence of mongohq/lab uri.
|
62
97
|
* `0.4`: Require `gomon` for mongodump, changed executable names, internal refactoring.
|
63
98
|
* `0.3`: Added `mongodump`, `mongolab_dump`, `mongohq_dump`.
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Noveku
|
2
|
+
module CLI
|
3
|
+
class Base
|
4
|
+
attr_reader :commands
|
5
|
+
|
6
|
+
# Extract commands & options
|
7
|
+
def initialize(*commands)
|
8
|
+
@options = (commands.last.is_a?(Hash) && commands.pop) || {}
|
9
|
+
@commands = commands
|
10
|
+
end
|
11
|
+
|
12
|
+
# Only print
|
13
|
+
def dry_run?
|
14
|
+
@options[:dry_run]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Print & execute
|
18
|
+
def verbose?
|
19
|
+
@options[:verbose]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Hide stderr ?
|
23
|
+
def hide_stderr?
|
24
|
+
!!(@options[:hide_stderr])
|
25
|
+
end
|
26
|
+
|
27
|
+
# Hide stderr ?
|
28
|
+
def hide_stdout?
|
29
|
+
!!(@options[:hide_stdout])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Hide stderr & stdout ?
|
33
|
+
def hide_both?
|
34
|
+
hide_stderr? && hide_stdout?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Execute the commands
|
38
|
+
def call
|
39
|
+
print if dry_run? || verbose?
|
40
|
+
system(command) unless dry_run?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Only print the command
|
44
|
+
def print
|
45
|
+
puts command
|
46
|
+
end
|
47
|
+
|
48
|
+
# The command template, with stream redirection handled
|
49
|
+
def template_command_with_output_cleaned(*args)
|
50
|
+
base = template_command(*args)
|
51
|
+
|
52
|
+
stream = if hide_both?
|
53
|
+
'&'
|
54
|
+
elsif hide_stderr?
|
55
|
+
'2'
|
56
|
+
elsif hide_stdout?
|
57
|
+
'1'
|
58
|
+
end
|
59
|
+
|
60
|
+
base = "#{base} #{stream}> /dev/null" if stream
|
61
|
+
base
|
62
|
+
end
|
63
|
+
|
64
|
+
# Command string to execute
|
65
|
+
def command
|
66
|
+
return nil unless commands
|
67
|
+
|
68
|
+
# Map commands to template & chain
|
69
|
+
commands.map(&method(:template_command_with_output_cleaned)).join(' && ')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'noveku/cli/base'
|
2
|
+
|
3
|
+
module Noveku
|
4
|
+
module CLI
|
5
|
+
class Heroku < Base
|
6
|
+
attr_reader :environment
|
7
|
+
|
8
|
+
# Extract environment from commands
|
9
|
+
def initialize(*commands)
|
10
|
+
super
|
11
|
+
@environment = @commands.shift
|
12
|
+
end
|
13
|
+
|
14
|
+
# Template for commands
|
15
|
+
def template_command(command)
|
16
|
+
"heroku #{command} --remote '#{environment}'"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/noveku/config.rb
CHANGED
data/lib/noveku/console.rb
CHANGED
data/lib/noveku/core.rb
CHANGED
@@ -1,25 +1,33 @@
|
|
1
|
+
require 'noveku/cli/git'
|
2
|
+
require 'noveku/cli/heroku'
|
1
3
|
require 'noveku/config'
|
2
|
-
require 'noveku/exceptions'
|
3
|
-
require 'noveku/rake'
|
4
4
|
require 'noveku/console'
|
5
|
+
require 'noveku/deploy'
|
6
|
+
require 'noveku/exceptions'
|
5
7
|
require 'noveku/migrate'
|
8
|
+
require 'noveku/mongo'
|
9
|
+
require 'noveku/options'
|
6
10
|
require 'noveku/proxy'
|
11
|
+
require 'noveku/push'
|
12
|
+
require 'noveku/rake'
|
7
13
|
require 'noveku/tail'
|
8
|
-
require 'noveku/mongo'
|
9
14
|
|
10
15
|
module Noveku
|
11
16
|
# Common functionnality
|
12
17
|
class Core
|
13
18
|
include Config
|
14
19
|
include Exceptions
|
20
|
+
include Options
|
15
21
|
# Aliases
|
16
|
-
include Rake
|
17
22
|
include Console
|
18
23
|
include Migrate
|
19
24
|
include Proxy
|
25
|
+
include Rake
|
20
26
|
include Tail
|
21
27
|
# Advanced Features
|
28
|
+
include Deploy
|
22
29
|
include Mongo
|
30
|
+
include Push
|
23
31
|
|
24
32
|
attr_reader :environment, :command, :arguments
|
25
33
|
|
@@ -41,22 +49,37 @@ module Noveku
|
|
41
49
|
send "#{@command}_cmd"
|
42
50
|
end
|
43
51
|
|
52
|
+
# Prefix of heroku git remotes
|
53
|
+
def prefix
|
54
|
+
"heroku"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Environment
|
58
|
+
alias :branch :environment
|
59
|
+
|
60
|
+
# Name of heroku remote
|
61
|
+
def remote
|
62
|
+
"#{prefix}-#{environment}"
|
63
|
+
end
|
64
|
+
|
44
65
|
private
|
45
66
|
|
46
67
|
# Execute the commands
|
47
|
-
def
|
48
|
-
|
49
|
-
|
68
|
+
def execute_heroku(*commands)
|
69
|
+
options = (commands.last.is_a?(Hash) && commands.pop) || {}
|
70
|
+
options = {dry_run: dry_run?, verbose: verbose?}.merge(options)
|
50
71
|
|
51
|
-
|
52
|
-
|
53
|
-
|
72
|
+
h = Noveku::CLI::Heroku.new environment, *commands, options
|
73
|
+
h.()
|
74
|
+
end
|
54
75
|
|
55
|
-
|
56
|
-
|
76
|
+
# Execute the commands
|
77
|
+
def execute_git(*commands)
|
78
|
+
options = (commands.last.is_a?(Hash) && commands.pop) || {}
|
79
|
+
options = {dry_run: dry_run?, verbose: verbose?}.merge(options)
|
57
80
|
|
58
|
-
|
59
|
-
|
81
|
+
g = Noveku::CLI::Git.new *commands, options
|
82
|
+
g.()
|
60
83
|
end
|
61
84
|
end
|
62
85
|
end
|
data/lib/noveku/exceptions.rb
CHANGED
@@ -21,7 +21,7 @@ module Noveku
|
|
21
21
|
# Check if there is a matching heroku app
|
22
22
|
def ensure_heroku_app
|
23
23
|
# This env is used for testing
|
24
|
-
return if environment == 'noveku-safe-env'
|
24
|
+
return if @environment == 'noveku-safe-env'
|
25
25
|
|
26
26
|
system "heroku releases --remote '#{environment}' >& /dev/null"
|
27
27
|
|
data/lib/noveku/migrate.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Noveku
|
2
|
+
module Options
|
3
|
+
def verbose?
|
4
|
+
arguments.include?('--verbose')
|
5
|
+
end
|
6
|
+
|
7
|
+
def dry_run?
|
8
|
+
arguments.include?('--dry-run')
|
9
|
+
end
|
10
|
+
|
11
|
+
def proxied_arguments
|
12
|
+
arguments.reject { |a| %w(--verbose --dry-run).include?(a) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/noveku/proxy.rb
CHANGED
@@ -2,13 +2,13 @@ module Noveku
|
|
2
2
|
module Proxy
|
3
3
|
# String to execute when proxying commands
|
4
4
|
def proxy_cmd_str
|
5
|
-
([@command] +
|
5
|
+
([@command] + proxied_arguments).join(' ')
|
6
6
|
end
|
7
7
|
|
8
8
|
# If this is a command with no specific support, pass the raw arguments to `heroku` directly
|
9
9
|
def method_missing(name, *args, &block)
|
10
10
|
if name.to_s.end_with?('_cmd')
|
11
|
-
|
11
|
+
execute_heroku proxy_cmd_str
|
12
12
|
else
|
13
13
|
super
|
14
14
|
end
|
data/lib/noveku/push.rb
ADDED
data/lib/noveku/rake.rb
CHANGED
data/lib/noveku/tail.rb
CHANGED
data/lib/noveku/version.rb
CHANGED
data/spec/core_spec.rb
CHANGED
@@ -11,8 +11,16 @@ describe 'Core' do
|
|
11
11
|
context 'commands' do
|
12
12
|
subject { Noveku::Core.new 'noveku-safe-env', 'rake', 'stats' }
|
13
13
|
|
14
|
+
it 'prefix should be "heroku"' do
|
15
|
+
expect(subject.prefix).to eq 'heroku'
|
16
|
+
end
|
17
|
+
|
14
18
|
it 'environment should be the first command' do
|
15
|
-
expect(subject.environment).to eq
|
19
|
+
expect(subject.environment).to eq "noveku-safe-env"
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'remote should be the prefixed environment' do
|
23
|
+
expect(subject.remote).to eq "#{subject.prefix}-#{subject.environment}"
|
16
24
|
end
|
17
25
|
|
18
26
|
it 'main command should be the second command' do
|
@@ -22,15 +30,5 @@ describe 'Core' do
|
|
22
30
|
it 'argument should be the remaining' do
|
23
31
|
expect(subject.arguments).to eq ['stats']
|
24
32
|
end
|
25
|
-
|
26
|
-
it 'string to execute should contain given command' do
|
27
|
-
str = "heroku run rake stats --remote 'noveku-safe-env'"
|
28
|
-
expect(subject.send(:executable_command, 'run rake stats')).to eq str
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'string to execute should chain given command' do
|
32
|
-
str = "heroku run rake stats --remote 'noveku-safe-env' && heroku releases --remote 'noveku-safe-env'"
|
33
|
-
expect(subject.send(:executable_command, 'run rake stats', 'releases')).to eq str
|
34
|
-
end
|
35
33
|
end
|
36
34
|
end
|
data/spec/deploy_spec.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'noveku/core'
|
3
|
+
|
4
|
+
describe 'Deploy' do
|
5
|
+
subject { Noveku::Core.new 'noveku-safe-env', 'deploy' }
|
6
|
+
|
7
|
+
it 'must have an executable command string' do
|
8
|
+
expect(subject.deploy_cmd_str).to eq "push #{subject.prefix}-noveku-safe-env noveku-safe-env:master"
|
9
|
+
end
|
10
|
+
end
|
data/spec/heroku_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'noveku/cli/heroku'
|
3
|
+
|
4
|
+
describe 'CLI' do
|
5
|
+
context 'Heroku' do
|
6
|
+
it 'string to execute should contain given command' do
|
7
|
+
heroku = Noveku::CLI::Heroku.new 'noveku-safe-env', 'run rake stats'
|
8
|
+
str = "heroku run rake stats --remote 'noveku-safe-env'"
|
9
|
+
expect(heroku.command).to eq str
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'string to execute should chain given command' do
|
13
|
+
heroku = Noveku::CLI::Heroku.new 'noveku-safe-env', 'run rake stats', 'releases'
|
14
|
+
str = "heroku run rake stats --remote 'noveku-safe-env' && heroku releases --remote 'noveku-safe-env'"
|
15
|
+
expect(heroku.command).to eq str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'noveku/core'
|
3
|
+
|
4
|
+
describe 'Options handler' do
|
5
|
+
context 'Dry run' do
|
6
|
+
subject { Noveku::Core.new 'noveku-safe-env', 'anycommandyoulike', '--dry-run' }
|
7
|
+
|
8
|
+
it 'recognizes the long form option' do
|
9
|
+
expect(subject.dry_run?).to be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'does not proxy the option' do
|
13
|
+
expect(subject.proxied_arguments).not_to include '--dry-run'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'Verbose' do
|
18
|
+
subject { Noveku::Core.new 'noveku-safe-env', 'anycommandyoulike', '--verbose' }
|
19
|
+
|
20
|
+
it 'recognizes the long form option' do
|
21
|
+
expect(subject.verbose?).to be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'does not proxy the option' do
|
25
|
+
expect(subject.proxied_arguments).not_to include '--verbose'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/push_spec.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'noveku/core'
|
3
|
+
|
4
|
+
describe 'Push' do
|
5
|
+
subject { Noveku::Core.new 'noveku-safe-env', 'push' }
|
6
|
+
|
7
|
+
it 'must have an executable command string' do
|
8
|
+
expect(subject.push_cmd_str).to eq "push origin #{subject.environment}"
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: noveku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.6'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: gomon
|
@@ -77,13 +77,19 @@ files:
|
|
77
77
|
- Rakefile
|
78
78
|
- bin/noveku
|
79
79
|
- lib/noveku.rb
|
80
|
+
- lib/noveku/cli/base.rb
|
81
|
+
- lib/noveku/cli/git.rb
|
82
|
+
- lib/noveku/cli/heroku.rb
|
80
83
|
- lib/noveku/config.rb
|
81
84
|
- lib/noveku/console.rb
|
82
85
|
- lib/noveku/core.rb
|
86
|
+
- lib/noveku/deploy.rb
|
83
87
|
- lib/noveku/exceptions.rb
|
84
88
|
- lib/noveku/migrate.rb
|
85
89
|
- lib/noveku/mongo.rb
|
90
|
+
- lib/noveku/options.rb
|
86
91
|
- lib/noveku/proxy.rb
|
92
|
+
- lib/noveku/push.rb
|
87
93
|
- lib/noveku/rake.rb
|
88
94
|
- lib/noveku/tail.rb
|
89
95
|
- lib/noveku/version.rb
|
@@ -91,9 +97,13 @@ files:
|
|
91
97
|
- spec/config_spec.rb
|
92
98
|
- spec/console_spec.rb
|
93
99
|
- spec/core_spec.rb
|
100
|
+
- spec/deploy_spec.rb
|
101
|
+
- spec/heroku_spec.rb
|
94
102
|
- spec/migrate_spec.rb
|
95
103
|
- spec/mongo_spec.rb
|
104
|
+
- spec/options_spec.rb
|
96
105
|
- spec/proxy_spec.rb
|
106
|
+
- spec/push_spec.rb
|
97
107
|
- spec/rake_spec.rb
|
98
108
|
- spec/spec_helper.rb
|
99
109
|
- spec/tail_spec.rb
|