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 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
@@ -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
@@ -0,0 +1,4 @@
1
+ module Branchy
2
+ # The gem version
3
+ VERSION = '0.0.1'.freeze
4
+ end
data/lib/branchy.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'branchy/cli'
2
+ require 'branchy/branch'
3
+ require 'branchy/drivers/git'
4
+ require 'branchy/version'
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: []