parity 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZWQ5MDcxMzdkOTY3ZDE1OGQzZmJiYzlmMjJlN2U4NTQ4NzBiNWM1Ng==
5
- data.tar.gz: !binary |-
6
- NWI3ZjUyZmNlOTY3Yzc1NjQzNDMwMTc4NzcxMzE4ZGYzMDg1NmIyNA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- YmZhM2U4ZDc0ZDQwM2MzOTlkNTFjZWRjZmJlN2FlOWQ4YmE5NzIyODFjYjBh
10
- MTJhYzEwNTJmMWI2YmJiMWNkYmZhOGY1OGFkYzNmYTQ5NGY1ZTZkODIwMjVh
11
- YjAyMTdhODgyMmRkM2E4ODU0MDMyYjAwMjEyOTRlNmNkODhkOWQ=
12
- data.tar.gz: !binary |-
13
- MTlmMjYyNDg3NzEwY2FjODE1ZTA3MTE3OTdlZTIxZDU5OThmODUxZjUyMDhh
14
- OWIwZjVkM2M4NmRjMmVlNDMwNGIyODljMzE0MTI4MmRhYTM0YTA5MjBiOGM1
15
- Y2JlMDg0NmNhZjEzODAxM2NkNTlmNmI4Y2Q4NTM3ZjA1ZDRjMDQ=
2
+ SHA1:
3
+ metadata.gz: 0698fa82d8c213ab44c52cb3fce810562de1f473
4
+ data.tar.gz: 46a3715c5db2394ae33ad4b6f2de32db42c36206
5
+ SHA512:
6
+ metadata.gz: 3f8d844f83bd34cc98c3d04cb85815fab30b8d0490d7c345b7f92c3a981a66d231ce5d845a9420f965a89d95d5a9ec0eb232191f19ce7f81b6976afee11b86c9
7
+ data.tar.gz: b9d1f976654e6bb6716a07ea03be643f680c9d0b5ff39df916d7a9aeaaf6e4137e332dc8aa1f2f705ac261247492ccbc2b20940baefb8b9e216293b04e24df2d
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ Parity
2
+ ======
3
+
4
+ Shell commands for development, staging, and production parity for Heroku apps.
5
+
6
+ Install
7
+ -------
8
+
9
+ gem install parity
10
+
11
+ This installs three shell commands:
12
+
13
+ development
14
+ staging
15
+ production
16
+
17
+ Your development machine will also need these command-line programs:
18
+
19
+ curl
20
+ heroku
21
+ pg_restore
22
+
23
+ On a Mac, `curl` is installed by default and the other programs can be installed
24
+ with Homebrew:
25
+
26
+ brew install heroku-toolbelt
27
+ brew install postgres --no-python
28
+
29
+ Usage
30
+ -----
31
+
32
+ Backup a database:
33
+
34
+ production backup
35
+ staging backup
36
+
37
+ Restore a production or staging database backup into development:
38
+
39
+ development restore production
40
+ development restore staging
41
+
42
+ Restore a production database backup into staging:
43
+
44
+ staging restore production
45
+
46
+ Open a console:
47
+
48
+ production console
49
+ staging console
50
+
51
+ Open [log2viz][1]:
52
+
53
+ production log2viz
54
+ staging log2viz
55
+
56
+ Migrate a database and restart the dynos:
57
+
58
+ production migrate
59
+ staging migrate
60
+
61
+ Tail a log:
62
+
63
+ production tail
64
+ staging tail
65
+
66
+ The scripts also pass through, so you can do anything with them that you can do
67
+ with `heroku ______ --remote staging` or `heroku ______ --remote production`:
68
+
69
+ watch production ps
70
+ staging open
71
+
72
+ Convention
73
+ ----------
74
+
75
+ Parity expects:
76
+
77
+ * A `staging` remote pointing to the staging Heroku app.
78
+ * A `production` remote pointing to the production Heroku app.
79
+ * There is a `config/database.yml` file that can be parsed as Yaml for
80
+ `['development']['database']`.
81
+ * The Heroku apps are named like `app-staging` and `app-production`
82
+ where `app` is equal to `basename $PWD`.
83
+
84
+ Configuration
85
+ -------------
86
+
87
+ Override some of the conventions:
88
+
89
+ ```ruby
90
+ Parity.configure do |config|
91
+ config.database_config_path = 'different/path.yml'
92
+ config.heroku_app_basename = 'different-base-name'
93
+ end
94
+ ```
95
+
96
+ Credits
97
+ -------
98
+
99
+ Parity is maintained by Dan Croak. It is free software and may be redistributed
100
+ under the terms specified in the LICENSE file.
101
+
102
+ [1]: https://blog.heroku.com/archives/2013/3/19/log2viz
data/bin/development CHANGED
@@ -2,4 +2,8 @@
2
2
 
3
3
  require File.join(File.dirname(__FILE__), '..', 'lib', 'parity')
4
4
 
5
- Parity::Development.new(ARGV).run
5
+ if ARGV.empty?
6
+ puts Parity::Usage.new
7
+ else
8
+ Parity::Development.new(ARGV).run
9
+ end
data/bin/production CHANGED
@@ -2,4 +2,8 @@
2
2
 
3
3
  require File.join(File.dirname(__FILE__), '..', 'lib', 'parity')
4
4
 
5
- Parity::Production.new(ARGV).run
5
+ if ARGV.empty?
6
+ puts Parity::Usage.new
7
+ else
8
+ Parity::Production.new(ARGV).run
9
+ end
data/bin/staging CHANGED
@@ -2,4 +2,8 @@
2
2
 
3
3
  require File.join(File.dirname(__FILE__), '..', 'lib', 'parity')
4
4
 
5
- Parity::Staging.new(ARGV).run
5
+ if ARGV.empty?
6
+ puts Parity::Usage.new
7
+ else
8
+ Parity::Staging.new(ARGV).run
9
+ end
data/lib/parity.rb CHANGED
@@ -1,3 +1,7 @@
1
+ require 'parity/configuration'
1
2
  require 'parity/development'
2
3
  require 'parity/staging'
3
4
  require 'parity/production'
5
+ require 'parity/usage'
6
+
7
+ Parity.configure
data/lib/parity/backup.rb CHANGED
@@ -2,7 +2,7 @@ require 'yaml'
2
2
 
3
3
  module Parity
4
4
  class Backup
5
- def initialize(from, to)
5
+ def initialize(from: from, to: to)
6
6
  @from = from
7
7
  @to = to
8
8
  end
@@ -20,16 +20,23 @@ module Parity
20
20
  attr_reader :from, :to
21
21
 
22
22
  def restore_to_development
23
- system %{
24
- curl -s `#{db_backup_url}` | \
25
- pg_restore --verbose --clean --no-acl --no-owner -d #{development_db}
26
- }
23
+ Kernel.system "#{curl} | #{pg_restore}"
24
+ end
25
+
26
+ def curl
27
+ "curl -s `#{db_backup_url}`"
28
+ end
29
+
30
+ def pg_restore
31
+ "pg_restore --verbose --clean --no-acl --no-owner -d #{development_db}"
27
32
  end
28
33
 
29
34
  def restore_to_pass_through
30
- system %{
31
- heroku pgbackups:restore DATABASE `#{db_backup_url}` --remote #{to}
32
- }
35
+ Kernel.system "heroku pgbackups:restore #{backup_from} --remote #{to}"
36
+ end
37
+
38
+ def backup_from
39
+ "DATABASE `#{db_backup_url}`"
33
40
  end
34
41
 
35
42
  def db_backup_url
@@ -37,7 +44,8 @@ module Parity
37
44
  end
38
45
 
39
46
  def development_db
40
- YAML.load(IO.read('config/database.yml'))['development']['database']
47
+ yaml_file = IO.read(Parity.config.database_config_path)
48
+ YAML.load(yaml_file)['development']['database']
41
49
  end
42
50
  end
43
51
  end
@@ -0,0 +1,21 @@
1
+ module Parity
2
+ class Configuration
3
+ attr_accessor :database_config_path, :heroku_app_basename
4
+
5
+ def initialize
6
+ @database_config_path = 'config/database.yml'
7
+ end
8
+ end
9
+
10
+ class << self
11
+ attr_accessor :config
12
+ end
13
+
14
+ def self.configure
15
+ self.config ||= Configuration.new
16
+
17
+ if block_given?
18
+ yield config
19
+ end
20
+ end
21
+ end
@@ -4,14 +4,13 @@ require 'parity/environment'
4
4
  module Parity
5
5
  class Development < Environment
6
6
  def initialize(subcommands)
7
- @environment = 'development'
8
- super(subcommands)
7
+ super 'development', subcommands
9
8
  end
10
9
 
11
10
  private
12
11
 
13
12
  def restore
14
- Backup.new(arguments.first, 'development').restore
13
+ Backup.new(from: arguments.first, to: 'development').restore
15
14
  end
16
15
  end
17
16
  end
@@ -1,51 +1,52 @@
1
1
  module Parity
2
2
  class Environment
3
- def initialize(subcommands)
4
- @subcommand = subcommands[0]
5
- @arguments = subcommands[1..-1]
3
+ def initialize(environment, subcommands)
4
+ self.environment = environment
5
+ self.subcommand = subcommands[0]
6
+ self.arguments = subcommands[1..-1]
6
7
  end
7
8
 
8
9
  def run
9
10
  if self.class.private_method_defined?(subcommand)
10
11
  send(subcommand)
11
12
  else
12
- system "heroku #{pass_through} --remote #{environment}"
13
+ Kernel.system "heroku #{pass_through} --remote #{environment}"
13
14
  end
14
15
  end
15
16
 
16
17
  private
17
18
 
18
- attr_reader :environment, :subcommand, :arguments
19
+ attr_accessor :environment, :subcommand, :arguments
19
20
 
20
21
  def backup
21
- system "heroku pgbackups:capture --expire --remote #{environment}"
22
+ Kernel.system "heroku pgbackups:capture --expire --remote #{environment}"
22
23
  end
23
24
 
24
25
  def console
25
- system "heroku run console --remote #{environment}"
26
+ Kernel.system "heroku run console --remote #{environment}"
26
27
  end
27
28
 
28
29
  def log2viz
29
- system "open https://log2viz.herokuapp.com/app/#{heroku_app_name}"
30
+ Kernel.system "open https://log2viz.herokuapp.com/app/#{heroku_app_name}"
30
31
  end
31
32
 
32
33
  def migrate
33
- system %{
34
+ Kernel.system %{
34
35
  heroku run rake db:migrate --remote #{environment} &&
35
36
  heroku restart --remote #{environment}
36
37
  }
37
38
  end
38
39
 
39
40
  def tail
40
- system "heroku logs --tail --remote #{environment}"
41
+ Kernel.system "heroku logs --tail --remote #{environment}"
41
42
  end
42
43
 
43
44
  def heroku_app_name
44
- [app_name, environment].join('-')
45
+ [basename, environment].join('-')
45
46
  end
46
47
 
47
- def app_name
48
- Dir.pwd.split('/').last
48
+ def basename
49
+ Parity.config.heroku_app_basename || Dir.pwd.split('/').last
49
50
  end
50
51
 
51
52
  def pass_through
@@ -3,8 +3,7 @@ require 'parity/environment'
3
3
  module Parity
4
4
  class Production < Environment
5
5
  def initialize(subcommands)
6
- @environment = 'production'
7
- super(subcommands)
6
+ super 'production', subcommands
8
7
  end
9
8
  end
10
9
  end
@@ -4,14 +4,13 @@ require 'parity/environment'
4
4
  module Parity
5
5
  class Staging < Environment
6
6
  def initialize(subcommands)
7
- @environment = 'staging'
8
- super(subcommands)
7
+ super 'staging', subcommands
9
8
  end
10
9
 
11
10
  private
12
11
 
13
12
  def restore
14
- Backup.new(arguments.last, 'staging').restore
13
+ Backup.new(from: arguments.last, to: 'staging').restore
15
14
  end
16
15
  end
17
16
  end
@@ -0,0 +1,13 @@
1
+ module Parity
2
+ class Usage
3
+ def to_s
4
+ File.read(readme).match(/Usage\n-----\n([^\/.]*)Convention/)[1]
5
+ end
6
+
7
+ private
8
+
9
+ def readme
10
+ File.join(File.dirname(__FILE__), '..', '..', 'README.md')
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,19 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Croak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-13 00:00:00.000000000 Z
11
+ date: 2013-08-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: ! " Devevelopment/staging/production parity is intended to decrease
14
- the time\n between a developer writing code and having it deployed, make it possible\n
15
- \ for the same people who wrote the code to deploy it and watch its behavior\n
16
- \ in production, and reduce the number of tools necessary to manage.\n"
13
+ description: |2
14
+ Devevelopment/staging/production parity is intended to decrease the time
15
+ between a developer writing code and having it deployed, make it possible
16
+ for the same people who wrote the code to deploy it and watch its behavior
17
+ in production, and reduce the number of tools necessary to manage.
17
18
  email:
18
19
  - dan@thoughtbot.com
19
20
  executables:
@@ -23,12 +24,15 @@ executables:
23
24
  extensions: []
24
25
  extra_rdoc_files: []
25
26
  files:
27
+ - README.md
26
28
  - lib/parity.rb
27
29
  - lib/parity/backup.rb
30
+ - lib/parity/configuration.rb
28
31
  - lib/parity/development.rb
29
32
  - lib/parity/environment.rb
30
33
  - lib/parity/production.rb
31
34
  - lib/parity/staging.rb
35
+ - lib/parity/usage.rb
32
36
  - bin/development
33
37
  - bin/staging
34
38
  - bin/production
@@ -42,19 +46,18 @@ require_paths:
42
46
  - lib
43
47
  required_ruby_version: !ruby/object:Gem::Requirement
44
48
  requirements:
45
- - - ! '>='
49
+ - - '>='
46
50
  - !ruby/object:Gem::Version
47
51
  version: '0'
48
52
  required_rubygems_version: !ruby/object:Gem::Requirement
49
53
  requirements:
50
- - - ! '>='
54
+ - - '>='
51
55
  - !ruby/object:Gem::Version
52
56
  version: '0'
53
57
  requirements: []
54
58
  rubyforge_project:
55
- rubygems_version: 2.0.0
59
+ rubygems_version: 2.0.5
56
60
  signing_key:
57
61
  specification_version: 4
58
62
  summary: Shell commands for development, staging, and production parity.
59
63
  test_files: []
60
- has_rdoc: