branchbot 0.1.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.
- checksums.yaml +7 -0
 - data/Gemfile +6 -0
 - data/Gemfile.lock +22 -0
 - data/LICENSE +20 -0
 - data/README.md +39 -0
 - data/bin/console +15 -0
 - data/bin/setup +8 -0
 - data/branchbot.gemspec +34 -0
 - data/exe/branchbot +28 -0
 - data/lib/branchbot.rb +16 -0
 - data/lib/branchbot/adapters/abstract.rb +74 -0
 - data/lib/branchbot/adapters/mysql.rb +26 -0
 - data/lib/branchbot/adapters/postgresql.rb +47 -0
 - data/lib/branchbot/adapters/unsupported_database.rb +17 -0
 - data/lib/branchbot/branch_switcher.rb +80 -0
 - data/lib/branchbot/version.rb +5 -0
 - data/post-checkout +6 -0
 - metadata +78 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 0fa6c1ef194f2f10f54ac1a874d0ef1971e585f2ff9b2c8aefe958178fca3d54
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: fbfc9ffc56df62c39152ece3a5ca4ba28334bf857e9b42fdb4c19c65c08a6707
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 2e3b4baf23cd8108b3d096a91d946c9e0b8f175374b83103024514416ce0cb255e3e2b991ce82d6a2fb5112efe972c9891225e6294dcf7ee3f2a61f1308fc5e5
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 263700bdbfa46eba2d124a21df567946bfed5209676ac1c45fa6d2612bb61782e44a76413e92ebce61446da03837e6352870f8716eea3058e8a10a41ee036ed1
         
     | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            PATH
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: .
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                branchbot (0.1.0)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  commander (~> 4.6.0)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 8 
     | 
    
         
            +
              remote: https://rubygems.org/
         
     | 
| 
      
 9 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 10 
     | 
    
         
            +
                commander (4.6.0)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  highline (~> 2.0.0)
         
     | 
| 
      
 12 
     | 
    
         
            +
                highline (2.0.3)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 15 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 16 
     | 
    
         
            +
              x86_64-darwin-18
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 19 
     | 
    
         
            +
              branchbot!
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            BUNDLED WITH
         
     | 
| 
      
 22 
     | 
    
         
            +
               2.2.19
         
     | 
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            The MIT License (MIT)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (c) 2014 Room 118 Solutions Inc.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy of
         
     | 
| 
      
 6 
     | 
    
         
            +
            this software and associated documentation files (the "Software"), to deal in
         
     | 
| 
      
 7 
     | 
    
         
            +
            the Software without restriction, including without limitation the rights to
         
     | 
| 
      
 8 
     | 
    
         
            +
            use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
         
     | 
| 
      
 9 
     | 
    
         
            +
            the Software, and to permit persons to whom the Software is furnished to do so,
         
     | 
| 
      
 10 
     | 
    
         
            +
            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, FITNESS
         
     | 
| 
      
 17 
     | 
    
         
            +
            FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
         
     | 
| 
      
 18 
     | 
    
         
            +
            COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
         
     | 
| 
      
 19 
     | 
    
         
            +
            IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
         
     | 
| 
      
 20 
     | 
    
         
            +
            CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            branchbot
         
     | 
| 
      
 2 
     | 
    
         
            +
            ==============================
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Save and restore the state of your Rails development and test databases as you work on different branches.
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            This allows you to make some changes to the structure of your database on a feature branch, then be able to quickly switch back to your master branch to make a hotfix or start a new feature branch with your original database structure and content.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            # Installation
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            1. Install the gem:
         
     | 
| 
      
 11 
     | 
    
         
            +
               
         
     | 
| 
      
 12 
     | 
    
         
            +
                `gem install branchbot`
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            2. Download the `post-checkout` file into the `.git/hooks` directory of your project.
         
     | 
| 
      
 15 
     | 
    
         
            +
               Modify to configure any flags.
         
     | 
| 
      
 16 
     | 
    
         
            +
               
         
     | 
| 
      
 17 
     | 
    
         
            +
               Note: Be sure to keep the `post-checkout` name to match Git's expectations.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            # Support
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Only PostgreSQL and MySQL databases are currently supported.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            # Non-Rails Usage
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            While this hook is geared towards Rails and depends on Ruby, it is very easy to use it in non-Ruby/Rails projects, so long as you have Ruby installed on your system.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            This script will look for a `database.yml` config file (default: `config/database.yml` in your project's root directory), and expects it to look like this:
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 30 
     | 
    
         
            +
            development:
         
     | 
| 
      
 31 
     | 
    
         
            +
              adapter: <adapter>
         
     | 
| 
      
 32 
     | 
    
         
            +
              username: <database username>
         
     | 
| 
      
 33 
     | 
    
         
            +
              password: <database password>
         
     | 
| 
      
 34 
     | 
    
         
            +
              database: <database name>
         
     | 
| 
      
 35 
     | 
    
         
            +
            ```
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            The path to this file is configurable via the `--db-config-path` option.
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            We currently support two adapters: `mysql2` and `postgresql`. We don't actually rely on these gems, but instead use them to determine which database's command line tools we should use (mysqldump/mysql or pg_dump/psql). Use `mysql2` if you are using a MySQL database, or `postgresql` if you are using a PostgreSQL database.
         
     | 
    
        data/bin/console
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require "bundler/setup"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "branchbot"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            # You can add fixtures and/or initialization code here to make experimenting
         
     | 
| 
      
 8 
     | 
    
         
            +
            # with your gem easier. You can also use a different console, if you like.
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # (If you use this, don't forget to add pry to your Gemfile!)
         
     | 
| 
      
 11 
     | 
    
         
            +
            # require "pry"
         
     | 
| 
      
 12 
     | 
    
         
            +
            # Pry.start
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            require "irb"
         
     | 
| 
      
 15 
     | 
    
         
            +
            IRB.start(__FILE__)
         
     | 
    
        data/bin/setup
    ADDED
    
    
    
        data/branchbot.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "lib/branchbot/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Gem::Specification.new do |spec|
         
     | 
| 
      
 6 
     | 
    
         
            +
              spec.name          = "branchbot"
         
     | 
| 
      
 7 
     | 
    
         
            +
              spec.version       = Branchbot::VERSION
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.authors       = ["Jim Ryan"]
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.email         = ["jim@room118solutions.com"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.license       = 'MIT'
         
     | 
| 
      
 11 
     | 
    
         
            +
              spec.summary       = "Saves and restores the state of your local database as you work on different git branches."
         
     | 
| 
      
 12 
     | 
    
         
            +
              spec.description   = spec.summary
         
     | 
| 
      
 13 
     | 
    
         
            +
              spec.homepage      = "https://github.com/room118solutions/branchbot"
         
     | 
| 
      
 14 
     | 
    
         
            +
              spec.required_ruby_version = ">= 2.4.0"
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              spec.metadata["homepage_uri"] = spec.homepage
         
     | 
| 
      
 17 
     | 
    
         
            +
              spec.metadata["source_code_uri"] = "https://github.com/room118solutions/git-rails-database-branch-hook"
         
     | 
| 
      
 18 
     | 
    
         
            +
              # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              # Specify which files should be added to the gem when it is released.
         
     | 
| 
      
 21 
     | 
    
         
            +
              # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
         
     | 
| 
      
 22 
     | 
    
         
            +
              spec.files = Dir.chdir(File.expand_path(__dir__)) do
         
     | 
| 
      
 23 
     | 
    
         
            +
                `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              spec.bindir        = "exe"
         
     | 
| 
      
 26 
     | 
    
         
            +
              spec.executables   = ['branchbot']
         
     | 
| 
      
 27 
     | 
    
         
            +
              spec.require_paths = ["lib"]
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              # Uncomment to register a new dependency of your gem
         
     | 
| 
      
 30 
     | 
    
         
            +
              spec.add_runtime_dependency "commander", '~> 4.6.0'
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              # For more information and examples about making a new gem, checkout our
         
     | 
| 
      
 33 
     | 
    
         
            +
              # guide at: https://bundler.io/guides/creating_gem.html
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
    
        data/exe/branchbot
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require "commander/import"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "branchbot"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            program :name, 'branchbot'
         
     | 
| 
      
 8 
     | 
    
         
            +
            program :version, Branchbot::VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
            program :description, "Saves and restores the state of your local database as you work on different git branches."
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            command :switch do |cmd|
         
     | 
| 
      
 12 
     | 
    
         
            +
              cmd.syntax = "branchbot switch [options]"
         
     | 
| 
      
 13 
     | 
    
         
            +
              cmd.option '--from FROM_REF', String, 'ref switching from'
         
     | 
| 
      
 14 
     | 
    
         
            +
              cmd.option '--db-config-path path/to/database.yml', String, 'path to database.yml relative to project root (default: config/database.yml)'
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              cmd.action do |args, options|
         
     | 
| 
      
 17 
     | 
    
         
            +
                unless options.from
         
     | 
| 
      
 18 
     | 
    
         
            +
                  say "--from required"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  next
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                options.default db_config_path: 'config/database.yml'
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                Branchbot::BranchSwitcher.new(
         
     | 
| 
      
 25 
     | 
    
         
            +
                  database_yml_path: options.db_config_path
         
     | 
| 
      
 26 
     | 
    
         
            +
                ).switch_from(options.from)
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/branchbot.rb
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "branchbot/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "branchbot/adapters/abstract"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "branchbot/adapters/unsupported_database"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "branchbot/adapters/mysql"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative "branchbot/adapters/postgresql"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative "branchbot/branch_switcher"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'erb'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            module Branchbot
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Branchbot
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Adapters
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Abstract
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.build(config, dump_folder)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    klass = case config['adapter']
         
     | 
| 
      
 7 
     | 
    
         
            +
                    when 'postgresql'
         
     | 
| 
      
 8 
     | 
    
         
            +
                      PostgreSQL
         
     | 
| 
      
 9 
     | 
    
         
            +
                    when 'mysql2'
         
     | 
| 
      
 10 
     | 
    
         
            +
                      MySQL
         
     | 
| 
      
 11 
     | 
    
         
            +
                    else
         
     | 
| 
      
 12 
     | 
    
         
            +
                      raise UnsupportedDatabase.new(config['adapter'])
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    klass.new(config, dump_folder)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def initialize(config, dump_folder)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @config = config
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @database_name = config['database']
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    @dump_folder = dump_folder
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def dump(branch_name)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    print "Saving state of database on '#{branch_name}' branch..."
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    if system(dump_cmd(branch_name))
         
     | 
| 
      
 29 
     | 
    
         
            +
                      print "done!\n"
         
     | 
| 
      
 30 
     | 
    
         
            +
                      true
         
     | 
| 
      
 31 
     | 
    
         
            +
                    else
         
     | 
| 
      
 32 
     | 
    
         
            +
                      print "failed!\n"
         
     | 
| 
      
 33 
     | 
    
         
            +
                      false
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  def dump_exists?(branch_name)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    File.exists?(dump_file(branch_name))
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def restore(branch_name)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    print "Restoring #{database_name} to its previous state on this branch..."
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    if system(restore_cmd(branch_name))
         
     | 
| 
      
 45 
     | 
    
         
            +
                      print "done!\n"
         
     | 
| 
      
 46 
     | 
    
         
            +
                      true
         
     | 
| 
      
 47 
     | 
    
         
            +
                    else
         
     | 
| 
      
 48 
     | 
    
         
            +
                      print "failed!\n"
         
     | 
| 
      
 49 
     | 
    
         
            +
                      false
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  private
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    attr_reader :dump_folder, :database_name
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    def dump_cmd(branch_name)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      raise NotImplementedError
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                    def restore_cmd(branch_name)
         
     | 
| 
      
 62 
     | 
    
         
            +
                      raise NotImplementedError
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    def dump_file(branch_name)
         
     | 
| 
      
 66 
     | 
    
         
            +
                      # Replace any special characters that may cause file system issues
         
     | 
| 
      
 67 
     | 
    
         
            +
                      branch_name = branch_name.gsub(/[^0-9a-z.\-_]/i, '_')
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                      "#{dump_folder}/#{database_name}-#{branch_name}"
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Branchbot
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Adapters
         
     | 
| 
      
 3 
     | 
    
         
            +
                class MySQL < Abstract
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def initialize(*)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    super
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    @username = @config['username']
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @password = @config['password']
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  private
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    attr_reader :username, :password
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    def dump_cmd(branch_name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      %[mysqldump --add-drop-database --user=#{username} --password="#{password}" --databases #{database_name} > "#{dump_file(branch_name)}"]
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    def restore_cmd(branch_name)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      %[mysql -u #{username} --password="#{password}" #{database_name} < "#{dump_file(branch_name)}"]
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Branchbot
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Adapters
         
     | 
| 
      
 3 
     | 
    
         
            +
                class PostgreSQL < Abstract
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  private
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                    def dump_cmd(branch_name)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      # Delete legacy SQL dump, or previous directory-format archive since folder cannot already exist
         
     | 
| 
      
 9 
     | 
    
         
            +
                      if File.exist?(dump_file(branch_name))
         
     | 
| 
      
 10 
     | 
    
         
            +
                        FileUtils.rm_r dump_file(branch_name)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                      %[pg_dump --file="#{dump_file(branch_name)}" --format=directory --jobs=#{number_of_jobs} #{database_name}]
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    def restore_cmd(branch_name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      # Drop existing connections
         
     | 
| 
      
 18 
     | 
    
         
            +
                      system(%[psql --command="SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '#{database_name}' AND pid <> pg_backend_pid();" postgres > /dev/null])
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      # Drop database
         
     | 
| 
      
 21 
     | 
    
         
            +
                      system(%[dropdb #{database_name}])
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      # Create database
         
     | 
| 
      
 24 
     | 
    
         
            +
                      system(%[createdb #{database_name}])
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                      if File.directory?(dump_file(branch_name))
         
     | 
| 
      
 27 
     | 
    
         
            +
                        # Restore directory-format archive
         
     | 
| 
      
 28 
     | 
    
         
            +
                        %[pg_restore --dbname=#{database_name} --jobs=#{number_of_jobs} "#{dump_file(branch_name)}"]
         
     | 
| 
      
 29 
     | 
    
         
            +
                      else
         
     | 
| 
      
 30 
     | 
    
         
            +
                        # Restore legacy SQL dump
         
     | 
| 
      
 31 
     | 
    
         
            +
                        %[psql --file="#{dump_file(branch_name)}" #{database_name} > /dev/null]
         
     | 
| 
      
 32 
     | 
    
         
            +
                      end
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    def number_of_jobs
         
     | 
| 
      
 36 
     | 
    
         
            +
                      require 'etc'
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      if Etc.respond_to?(:nprocessors) # Available in 2.2.3+
         
     | 
| 
      
 39 
     | 
    
         
            +
                        Etc.nprocessors
         
     | 
| 
      
 40 
     | 
    
         
            +
                      else
         
     | 
| 
      
 41 
     | 
    
         
            +
                        1
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Branchbot
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Adapters
         
     | 
| 
      
 3 
     | 
    
         
            +
                class UnsupportedDatabase < RuntimeError
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_reader :adapter
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(adapter)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @adapter = adapter
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def message
         
     | 
| 
      
 12 
     | 
    
         
            +
                    "Adapter `#{adapter}` is not supported."
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Branchbot
         
     | 
| 
      
 2 
     | 
    
         
            +
              class BranchSwitcher
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize(database_yml_path: 'config/database.yml')
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @database_yml_path = database_yml_path
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def switch_from(prev_ref)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Get the current (destination) branch
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @destination_branch = `git rev-parse --abbrev-ref HEAD`.strip
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  # Since we're just given a commit ID referencing the branch head we're coming from,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # it could be at the head of multiple branches. We can assume the source isn't the same as the
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # destination branch, so we can remove that immediately.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @source_branches = branches_from_refhead(prev_ref).reject{ |b| b == @destination_branch }
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  @project_root = %x[git rev-parse --show-toplevel].strip
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @dump_folder = "#{@project_root}/.db_branch_dumps"
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  # Load Rails DB config and grab database name
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @rails_db_config = YAML.load(ERB.new(File.read(File.join @project_root, @database_yml_path)).result)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  dev_database_name = @rails_db_config['development']['database']
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @adapter = Adapters::Abstract.build(@rails_db_config['development'], @dump_folder)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  rescue Adapters::UnsupportedDatabase => e
         
     | 
| 
      
 26 
     | 
    
         
            +
                    puts "\nERROR: #{e.message}"
         
     | 
| 
      
 27 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  # Ensure dump directory exists
         
     | 
| 
      
 31 
     | 
    
         
            +
                  unless Dir.exists?(@dump_folder)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    Dir.mkdir @dump_folder
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Don't do anything if the source and destination branches are the same or nonexistent
         
     | 
| 
      
 36 
     | 
    
         
            +
                  unless @source_branches.include?(@destination_branch) || @source_branches.empty? || (@source_branches | [@destination_branch]).any?{ |b| b == '' }
         
     | 
| 
      
 37 
     | 
    
         
            +
                    # Dump database for source branches
         
     | 
| 
      
 38 
     | 
    
         
            +
                    if @source_branches.all? { |branch| @adapter.dump(branch) }
         
     | 
| 
      
 39 
     | 
    
         
            +
                      # Restore dump from this branch, if it exists
         
     | 
| 
      
 40 
     | 
    
         
            +
                      if @adapter.dump_exists?(@destination_branch)
         
     | 
| 
      
 41 
     | 
    
         
            +
                        if @adapter.restore(@destination_branch)
         
     | 
| 
      
 42 
     | 
    
         
            +
                          prepare_test_database
         
     | 
| 
      
 43 
     | 
    
         
            +
                        end
         
     | 
| 
      
 44 
     | 
    
         
            +
                      else
         
     | 
| 
      
 45 
     | 
    
         
            +
                        print "No DB dump for #{dev_database_name} on the '#{@destination_branch}' branch was found!\n"
         
     | 
| 
      
 46 
     | 
    
         
            +
                        print "The state of your database has been saved for when you return to the '#{@source_branches.join('\' or \'')}' branch, but its current state has been left unchanged.  You are now free to make changes to it that are specific to this branch, and they will be saved when you checkout a different branch, then restored when you checkout this one again.\n"
         
     | 
| 
      
 47 
     | 
    
         
            +
                      end
         
     | 
| 
      
 48 
     | 
    
         
            +
                    else
         
     | 
| 
      
 49 
     | 
    
         
            +
                      print "Failed to dump database. Halting.\n"
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                private
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def branches_from_refhead(ref)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    `git show-ref --heads | grep #{ref} | awk '{print $2}'`.split("\n").map{ |b| b.sub(/^refs\/heads\//, '') }
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  def prepare_test_database
         
     | 
| 
      
 61 
     | 
    
         
            +
                    if File.exists?("#{@project_root}/Rakefile")
         
     | 
| 
      
 62 
     | 
    
         
            +
                      print "Preparing test database..."
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      rake_cmd = "rake db:test:prepare"
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                      if File.exists?("#{@project_root}/bin/rake")
         
     | 
| 
      
 67 
     | 
    
         
            +
                        rake_cmd = "./bin/#{rake_cmd}"
         
     | 
| 
      
 68 
     | 
    
         
            +
                      elsif File.exists?("#{@project_root}/Gemfile")
         
     | 
| 
      
 69 
     | 
    
         
            +
                        rake_cmd = "bundle exec #{rake_cmd}"
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                      system rake_cmd
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                      print "done!\n"
         
     | 
| 
      
 75 
     | 
    
         
            +
                    else
         
     | 
| 
      
 76 
     | 
    
         
            +
                      print "No Rakefile detected, skipping test database restoration\n"
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
            end
         
     | 
    
        data/post-checkout
    ADDED
    
    
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: branchbot
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Jim Ryan
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: exe
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-06-04 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: commander
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: 4.6.0
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: 4.6.0
         
     | 
| 
      
 27 
     | 
    
         
            +
            description: Saves and restores the state of your local database as you work on different
         
     | 
| 
      
 28 
     | 
    
         
            +
              git branches.
         
     | 
| 
      
 29 
     | 
    
         
            +
            email:
         
     | 
| 
      
 30 
     | 
    
         
            +
            - jim@room118solutions.com
         
     | 
| 
      
 31 
     | 
    
         
            +
            executables:
         
     | 
| 
      
 32 
     | 
    
         
            +
            - branchbot
         
     | 
| 
      
 33 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 34 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 35 
     | 
    
         
            +
            files:
         
     | 
| 
      
 36 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 37 
     | 
    
         
            +
            - Gemfile.lock
         
     | 
| 
      
 38 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 39 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 40 
     | 
    
         
            +
            - bin/console
         
     | 
| 
      
 41 
     | 
    
         
            +
            - bin/setup
         
     | 
| 
      
 42 
     | 
    
         
            +
            - branchbot.gemspec
         
     | 
| 
      
 43 
     | 
    
         
            +
            - exe/branchbot
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/branchbot.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/branchbot/adapters/abstract.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/branchbot/adapters/mysql.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - lib/branchbot/adapters/postgresql.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - lib/branchbot/adapters/unsupported_database.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - lib/branchbot/branch_switcher.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            - lib/branchbot/version.rb
         
     | 
| 
      
 51 
     | 
    
         
            +
            - post-checkout
         
     | 
| 
      
 52 
     | 
    
         
            +
            homepage: https://github.com/room118solutions/branchbot
         
     | 
| 
      
 53 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 54 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 55 
     | 
    
         
            +
            metadata:
         
     | 
| 
      
 56 
     | 
    
         
            +
              homepage_uri: https://github.com/room118solutions/branchbot
         
     | 
| 
      
 57 
     | 
    
         
            +
              source_code_uri: https://github.com/room118solutions/git-rails-database-branch-hook
         
     | 
| 
      
 58 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
      
 59 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 60 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 61 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 62 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 63 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 64 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 65 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 66 
     | 
    
         
            +
                  version: 2.4.0
         
     | 
| 
      
 67 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 68 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 69 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 70 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 71 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 72 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 73 
     | 
    
         
            +
            rubygems_version: 3.1.2
         
     | 
| 
      
 74 
     | 
    
         
            +
            signing_key:
         
     | 
| 
      
 75 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 76 
     | 
    
         
            +
            summary: Saves and restores the state of your local database as you work on different
         
     | 
| 
      
 77 
     | 
    
         
            +
              git branches.
         
     | 
| 
      
 78 
     | 
    
         
            +
            test_files: []
         
     |