branchy 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.rdoc +65 -0
- data/bin/branchy +37 -0
- data/lib/branchy/branch.rb +73 -0
- data/lib/branchy/cli.rb +28 -0
- data/lib/branchy/drivers/git.rb +34 -0
- data/lib/branchy/version.rb +4 -0
- data/lib/branchy.rb +4 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ff46d1f1add7c02a6bebbc34de50a0267f38ec2
|
4
|
+
data.tar.gz: f4eecfe2d89b233ef3ae4b0c24be87a537a8481d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68175dc477d0d59430451b16ace6c6e4a7fc903b205e98c41e464ebf2bd6137dc1ad471008ef7cbc6356da6d38279d9d284e688f56a4762434933cf83f417a73
|
7
|
+
data.tar.gz: 76f027339cd2e7119d2e7b13a2636953ab20cd6f4012f294cb22cbf986afdfb6cdb56ce5ebb46ef0c304692e02be4c340687bdb4c2b05c980c5b2ca6193a2e94
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Consolo Services
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
== Branchy
|
2
|
+
|
3
|
+
Branchy is a library for getting the name of the branch you're on. Lame, right? But its real purpose is to make it very easy to use
|
4
|
+
the branched database pattern in Ruby, where each branch in your project has its own database. Rails was the original use-case, but
|
5
|
+
there's nothing Rails-specific in it - you should be able to use it with just about any Ruby ORM. That said, all examples assume
|
6
|
+
Rails and ActiveRecord. Salt to taste.
|
7
|
+
|
8
|
+
Supported SCMs:
|
9
|
+
* git
|
10
|
+
|
11
|
+
== The Branched Database Pattern
|
12
|
+
|
13
|
+
Do you use feature branches for development? Are you in migration hell, fighting merge conflicts in schema.rb and running into exceptions
|
14
|
+
caused by database changes from other branches? The branched database pattern might be what you're looking for. Each branch has its
|
15
|
+
own database, isolating it from any other branch's changes.
|
16
|
+
|
17
|
+
NOTE Branched databases work best when everyone on your team uses them and practices good database migration habits. A more complete
|
18
|
+
write-up on that subject can be found at http://jordanhollinger.com/2014/07/30/rails-migration-etiquette/. These are the highlights:
|
19
|
+
* Use schema.rb to create your database (rake db:schema:load or rake db:setup).
|
20
|
+
* After running migrations locally, commit the resulting changes in schema.rb.
|
21
|
+
* Use branched databases to keep each branch's schema changes isolated.
|
22
|
+
* Remember to restart your local Rails server after switching branches.
|
23
|
+
|
24
|
+
== Installation
|
25
|
+
In your Gemfile:
|
26
|
+
|
27
|
+
group :development, :test do
|
28
|
+
gem 'branchy', git: 'git://github.com/consolo/branchy.git'
|
29
|
+
end
|
30
|
+
|
31
|
+
== Use in database.yml
|
32
|
+
You probably only want to use it in your development and test environments.
|
33
|
+
For a branch called "widgets" the database would be "foobar_development_widgets".
|
34
|
+
|
35
|
+
development:
|
36
|
+
database: <%= Branchy.git.db 'foobar_development' %>
|
37
|
+
...
|
38
|
+
|
39
|
+
== A database for EVERY branch? Overkill much?
|
40
|
+
Maybe. If you have lots branches without schema changes, you might want to enable branchy on a per-branch basis. There's a command-line
|
41
|
+
utility for this:
|
42
|
+
|
43
|
+
$ git checkout my_branch
|
44
|
+
$ branchy --enable
|
45
|
+
|
46
|
+
Then in your database.yml file use the "db_if_enabled" method. It the current branch isn't branchy-enabled it will simply return
|
47
|
+
whatever string your passed.
|
48
|
+
|
49
|
+
development:
|
50
|
+
database: <%= Branchy.git.db_if_enabled 'foobar_development' %>
|
51
|
+
...
|
52
|
+
|
53
|
+
== You don't even NEED this library
|
54
|
+
It's really just a convenient way to share the idea. You can get 90% of the functionality in database.yml with:
|
55
|
+
|
56
|
+
<% branch = `git rev-parse --abbrev-ref HEAD`.chomp %>
|
57
|
+
|
58
|
+
development:
|
59
|
+
database: my_project_development_<%= branch %>
|
60
|
+
...
|
61
|
+
|
62
|
+
== License
|
63
|
+
Copyright 2014 Consolo Services Group
|
64
|
+
|
65
|
+
Licensed under the MIT License
|
data/bin/branchy
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'branchy'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
o = OptionParser.new do |opts|
|
8
|
+
opts.banner = 'Usage: branchy [options]'
|
9
|
+
opts.on('--enable', 'Enable a branched database for the current branch') { options[:command] = 'enable' }
|
10
|
+
opts.on('--disable', 'Disable a branched database for the current branch') { options[:command] = 'disable' }
|
11
|
+
opts.on('--scm SCM', 'Set the SCM (defaults to git). Supported SCMs: git') { |scm| options[:scm] = scm.downcase.strip }
|
12
|
+
end
|
13
|
+
o.parse!
|
14
|
+
|
15
|
+
options[:scm] ||= 'git'
|
16
|
+
branch = Branchy.respond_to?(options[:scm]) ? Branchy.send(options[:scm]) : nil
|
17
|
+
unless branch.is_a? Branchy::Branch
|
18
|
+
$stderr.puts "Unknown scm '#{options[:scm]}'"
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
case options[:command]
|
24
|
+
when 'enable'
|
25
|
+
puts "Enabling branched database"
|
26
|
+
branch.enable!
|
27
|
+
when 'disable'
|
28
|
+
puts "Disabling branched database"
|
29
|
+
branch.disable!
|
30
|
+
else
|
31
|
+
puts o.help
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
rescue Branchy::CommandFailed => e
|
35
|
+
$stderr.puts e.message
|
36
|
+
exit 1
|
37
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
##
|
2
|
+
# A library for interacting with branched database. I.E. each of your feature branches may
|
3
|
+
# have its own database to keep schema changes seperated until each is merged into the
|
4
|
+
# mainline.
|
5
|
+
#
|
6
|
+
# Supported SCMs:
|
7
|
+
# - git
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# -> Branchy.git.db('my_project_development')
|
11
|
+
# -> "my_project_development_branch_name"
|
12
|
+
#
|
13
|
+
# Example with optional branching enabled:
|
14
|
+
# -> Branchy.git.db_if_enabled('my_project_development')
|
15
|
+
# -> "my_project_development_branch_name"
|
16
|
+
#
|
17
|
+
# Example with optional branching disabled:
|
18
|
+
# -> Branchy.git.db_if_enabled('my_project_development')
|
19
|
+
# -> "my_project_development"
|
20
|
+
#
|
21
|
+
# To enable or disable branched databases in a branch, check out your branch and run:
|
22
|
+
# $ branchy --enable|--disable
|
23
|
+
#
|
24
|
+
module Branchy
|
25
|
+
# Returns a new Branchy object initialized for use with git
|
26
|
+
def self.git
|
27
|
+
Branch.new(Drivers::Git)
|
28
|
+
end
|
29
|
+
|
30
|
+
# A class for getting a branch's database name
|
31
|
+
class Branch
|
32
|
+
# The SCM driver
|
33
|
+
attr_reader :scm
|
34
|
+
|
35
|
+
# Initializes a new Branchy with the specified SCM driver
|
36
|
+
def initialize(driver)
|
37
|
+
@scm = driver
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the name of the current branch
|
41
|
+
def name
|
42
|
+
scm.branch
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns prefix + branch name (e.g. "my_project_development_my_branch"), replacing any db name
|
46
|
+
# unfriendly characthers with _.
|
47
|
+
# If it's the master/trunk/mainline branch only the prefix is returned.
|
48
|
+
def database(prefix)
|
49
|
+
db_name = scm.trunk? ? prefix : "#{prefix}_#{name}"
|
50
|
+
db_name.gsub(/[^A-Za-z0-9_]+/, '_')
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method :db, :database
|
54
|
+
|
55
|
+
# Returns the prefix + branch name, but *only* if branched db has been enabled for this branch.
|
56
|
+
# Otherwise it just returns the prefix.
|
57
|
+
def database_if_enabled(prefix)
|
58
|
+
scm.enabled? ? database(prefix) : prefix
|
59
|
+
end
|
60
|
+
|
61
|
+
alias_method :db_if_enabled, :database_if_enabled
|
62
|
+
|
63
|
+
# Enable a branched database for this branch
|
64
|
+
def enable!
|
65
|
+
scm.enable!
|
66
|
+
end
|
67
|
+
|
68
|
+
# Disable a branched database for this branch
|
69
|
+
def disable!
|
70
|
+
scm.disable!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/branchy/cli.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Branchy
|
4
|
+
# Exception for failed CLI commands
|
5
|
+
CommandFailed = Class.new(RuntimeError)
|
6
|
+
|
7
|
+
# Shared command line functionality
|
8
|
+
module CLI
|
9
|
+
protected
|
10
|
+
|
11
|
+
# If command is successful, returns stdout. Otherwise raises a CommandFailed exception.
|
12
|
+
def exec_or_raise(command, success_codes = [0])
|
13
|
+
stdout, stderr, process_status = self.exec(command)
|
14
|
+
if success_codes.include? process_status.exitstatus
|
15
|
+
return stdout.gets.to_s.chomp
|
16
|
+
else
|
17
|
+
raise CommandFailed, "Command `#{command}` failed with status #{process_status.exitstatus}\n#{stderr.gets.to_s.chomp}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Execute the command and return stdout, stderr, and process_status
|
22
|
+
def exec(command)
|
23
|
+
stdin, stdout, stderr, wait_thread = Open3.popen3(command)
|
24
|
+
process_status = wait_thread.value
|
25
|
+
return stdout, stderr, process_status
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Branchy
|
2
|
+
# Drivers for SCMs
|
3
|
+
module Drivers
|
4
|
+
# A Branchy driver for git
|
5
|
+
class Git
|
6
|
+
extend ::Branchy::CLI
|
7
|
+
|
8
|
+
# Returns the git branch name
|
9
|
+
def self.branch
|
10
|
+
exec_or_raise('git symbolic-ref HEAD').sub('refs/heads/', '')
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns true if it's the master/trunk/mainline branch.
|
14
|
+
def self.trunk?
|
15
|
+
branch == 'master'
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns true if this git branch has been configured with a branched database
|
19
|
+
def self.enabled?
|
20
|
+
exec_or_raise("git config --bool branch.#{branch}.database", [0,1]) == 'true'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Enables a database for this git branch
|
24
|
+
def self.enable!
|
25
|
+
exec_or_raise("git config --bool branch.#{branch}.database true")
|
26
|
+
end
|
27
|
+
|
28
|
+
# Disables a database for this git branch
|
29
|
+
def self.disable!
|
30
|
+
exec_or_raise("git config --bool branch.#{branch}.database false")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/branchy.rb
ADDED
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: branchy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jordan Hollinger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-07 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Use a different database for each of your branches!
|
14
|
+
email: jordan@jordanhollinger.com
|
15
|
+
executables:
|
16
|
+
- branchy
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- README.rdoc
|
22
|
+
- bin/branchy
|
23
|
+
- lib/branchy.rb
|
24
|
+
- lib/branchy/branch.rb
|
25
|
+
- lib/branchy/cli.rb
|
26
|
+
- lib/branchy/drivers/git.rb
|
27
|
+
- lib/branchy/version.rb
|
28
|
+
homepage: http://github.com/consolo/branchy
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.2.2
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: Branched database helpers
|
52
|
+
test_files: []
|