between_meals 0.0.5 → 0.0.6
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.
- data/README.md +2 -2
- data/lib/between_meals/changes/change.rb +3 -3
- data/lib/between_meals/changes/cookbook.rb +8 -8
- data/lib/between_meals/changes/databag.rb +3 -3
- data/lib/between_meals/changes/role.rb +4 -4
- data/lib/between_meals/changeset.rb +3 -3
- data/lib/between_meals/cmd.rb +44 -0
- data/lib/between_meals/knife.rb +52 -13
- data/lib/between_meals/repo.rb +74 -30
- data/lib/between_meals/repo/git.rb +49 -49
- data/lib/between_meals/repo/git/cmd.rb +49 -0
- data/lib/between_meals/repo/hg.rb +214 -0
- data/lib/between_meals/repo/hg/cmd.rb +72 -0
- data/lib/between_meals/repo/svn.rb +51 -68
- data/lib/between_meals/repo/svn/cmd.rb +56 -0
- data/lib/between_meals/util.rb +3 -3
- metadata +41 -8
    
        data/README.md
    CHANGED
    
    | @@ -9,8 +9,8 @@ Between Meals is the library for calculating what Chef objects where modified | |
| 9 9 | 
             
            between two revisions in a version control system. It is also the library
         | 
| 10 10 | 
             
            that that backs Taste Tester and Grocery Delivery.
         | 
| 11 11 |  | 
| 12 | 
            -
            It currently supports SVN and  | 
| 13 | 
            -
            other systems.
         | 
| 12 | 
            +
            It currently supports SVN, GIT and HG, but plugins can easily be written for
         | 
| 13 | 
            +
            other source control systems.
         | 
| 14 14 |  | 
| 15 15 | 
             
            It also includes some wrappers around knife execution and a few other utility
         | 
| 16 16 | 
             
            functions.
         | 
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -54,10 +54,10 @@ module BetweenMeals | |
| 54 54 | 
             
                    # otherwise it was modified
         | 
| 55 55 | 
             
                    #   and will be re-uploaded
         | 
| 56 56 | 
             
                    if files.
         | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 57 | 
            +
                       select { |x| x[:status] == :deleted }.
         | 
| 58 | 
            +
                       map { |x| x[:path].match(%{.*metadata\.rb$}) }.
         | 
| 59 | 
            +
                       compact.
         | 
| 60 | 
            +
                       any?
         | 
| 61 61 | 
             
                      @status = :deleted
         | 
| 62 62 | 
             
                    else
         | 
| 63 63 | 
             
                      @status = :modified
         | 
| @@ -78,7 +78,7 @@ module BetweenMeals | |
| 78 78 | 
             
                      g = self.explode_path(x[:path], cookbook_dirs)
         | 
| 79 79 | 
             
                      g[:cookbook_dir] + '/' + g[:name] if g
         | 
| 80 80 | 
             
                    end.
         | 
| 81 | 
            -
             | 
| 81 | 
            +
                      map do |_, change|
         | 
| 82 82 | 
             
                      # Confirm we're dealing with a cookbook
         | 
| 83 83 | 
             
                      # Changes to OWNERS or other stuff that might end up
         | 
| 84 84 | 
             
                      # in [core, other, secure] dirs are ignored
         | 
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -20,7 +20,7 @@ module BetweenMeals | |
| 20 20 | 
             
                # Changeset aware role
         | 
| 21 21 | 
             
                class Role < Change
         | 
| 22 22 | 
             
                  def self.name_from_path(path, role_dir)
         | 
| 23 | 
            -
                    re =  | 
| 23 | 
            +
                    re = %r{^#{role_dir}/(.+)\.rb}
         | 
| 24 24 | 
             
                    debug("[role] Matching #{path} against #{re}")
         | 
| 25 25 | 
             
                    m = path.match(re)
         | 
| 26 26 | 
             
                    if m
         | 
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Copyright 2013-present Facebook
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 | 
            +
            # you may not use this file except in compliance with the License.
         | 
| 7 | 
            +
            # You may obtain a copy of the License at
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 | 
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 | 
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 14 | 
            +
            # See the License for the specific language governing permissions and
         | 
| 15 | 
            +
            # limitations under the License.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            require 'logger'
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            module BetweenMeals
         | 
| 20 | 
            +
              class Cmd
         | 
| 21 | 
            +
                attr_accessor :bin
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def initialize(params)
         | 
| 24 | 
            +
                  @bin = params[:bin] || fail
         | 
| 25 | 
            +
                  @cwd = params[:cwd] || Dir.pwd
         | 
| 26 | 
            +
                  @logger = params[:logger] || Logger.new(STDOUT)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def cmd(params, cwd = nil)
         | 
| 30 | 
            +
                  unless cwd
         | 
| 31 | 
            +
                    cwd = File.expand_path(@cwd)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                  cmd = "#{@bin} #{params}"
         | 
| 34 | 
            +
                  @logger.info("Running \"#{cmd}\"")
         | 
| 35 | 
            +
                  c = Mixlib::ShellOut.new(
         | 
| 36 | 
            +
                    cmd,
         | 
| 37 | 
            +
                    :cwd => cwd
         | 
| 38 | 
            +
                  )
         | 
| 39 | 
            +
                  c.run_command
         | 
| 40 | 
            +
                  c.error!
         | 
| 41 | 
            +
                  c
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
            end
         | 
    
        data/lib/between_meals/knife.rb
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -31,14 +31,16 @@ module BetweenMeals | |
| 31 31 | 
             
                  @user = opts[:user] || ENV['USER']
         | 
| 32 32 | 
             
                  @home = opts[:home] || ENV['HOME']
         | 
| 33 33 | 
             
                  # make sure people can pass in false :)
         | 
| 34 | 
            -
                  @ssl = opts[:ssl].nil? ? true : opts[:ssl] | 
| 34 | 
            +
                  @ssl = opts[:ssl].nil? ? true : opts[:ssl]
         | 
| 35 35 | 
             
                  @host = opts[:host] || 'localhost'
         | 
| 36 36 | 
             
                  @port = opts[:port] || 4000
         | 
| 37 37 | 
             
                  @config = opts[:config] ||
         | 
| 38 | 
            -
             | 
| 38 | 
            +
                            "#{@home}/.chef/knife-#{@user}-taste-tester.rb"
         | 
| 39 39 | 
             
                  @knife = opts[:bin] || 'knife'
         | 
| 40 | 
            +
                  @berks = opts[:berks_bin] || 'berks'
         | 
| 41 | 
            +
                  @berks_config = opts[:berks_config]
         | 
| 40 42 | 
             
                  @pem = opts[:pem] ||
         | 
| 41 | 
            -
             | 
| 43 | 
            +
                         "#{@home}/.chef/#{@user}-taste-tester.pem"
         | 
| 42 44 | 
             
                  @role_dir = opts[:role_dir]
         | 
| 43 45 | 
             
                  @cookbook_dirs = opts[:cookbook_dirs]
         | 
| 44 46 | 
             
                  @databag_dir = opts[:databag_dir]
         | 
| @@ -48,8 +50,10 @@ module BetweenMeals | |
| 48 50 | 
             
                end
         | 
| 49 51 |  | 
| 50 52 | 
             
                def role_upload_all
         | 
| 51 | 
            -
                   | 
| 52 | 
            -
             | 
| 53 | 
            +
                  if File.exists?(@role_dir)
         | 
| 54 | 
            +
                    roles = File.join(@role_dir, '*.rb')
         | 
| 55 | 
            +
                    exec!("#{@knife} role from file #{roles} -c #{@config}", @logger)
         | 
| 56 | 
            +
                  end
         | 
| 53 57 | 
             
                end
         | 
| 54 58 |  | 
| 55 59 | 
             
                def role_upload(roles)
         | 
| @@ -73,13 +77,45 @@ module BetweenMeals | |
| 73 77 | 
             
                  exec!("#{@knife} cookbook upload -a -c #{@config}", @logger)
         | 
| 74 78 | 
             
                end
         | 
| 75 79 |  | 
| 80 | 
            +
                def berks_cookbook_upload_all
         | 
| 81 | 
            +
                  if @berks_config
         | 
| 82 | 
            +
                    berks_config = '--config=' + @berks_config
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
                  @cookbook_dirs.each do |path|
         | 
| 85 | 
            +
                    cookbooks = Dir["#{path}/*"].select { |o| File.directory?(o) }
         | 
| 86 | 
            +
                    cookbooks.each do |cb|
         | 
| 87 | 
            +
                      @logger.warn("Running berkshelf on cookbook: #{cb}")
         | 
| 88 | 
            +
                      exec!("cd #{cb} && #{@berks} install #{berks_config} && " +
         | 
| 89 | 
            +
                        "#{@berks} upload #{berks_config}", @logger)
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 76 94 | 
             
                def cookbook_upload(cookbooks)
         | 
| 77 95 | 
             
                  if cookbooks.any?
         | 
| 78 | 
            -
                    cookbooks = cookbooks.map | 
| 96 | 
            +
                    cookbooks = cookbooks.map(&:name).join(' ')
         | 
| 79 97 | 
             
                    exec!("#{@knife} cookbook upload #{cookbooks} -c #{@config}", @logger)
         | 
| 80 98 | 
             
                  end
         | 
| 81 99 | 
             
                end
         | 
| 82 100 |  | 
| 101 | 
            +
                def berks_cookbook_upload(cookbooks)
         | 
| 102 | 
            +
                  # cookbooks: array
         | 
| 103 | 
            +
                  # cookbook_paths: array
         | 
| 104 | 
            +
                  if @berks_config
         | 
| 105 | 
            +
                    berks_config = '--config=' + @berks_config
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
                  if cookbooks.any?
         | 
| 108 | 
            +
                    @cookbook_dirs.each do |path|
         | 
| 109 | 
            +
                      cookbooks.each do |cb|
         | 
| 110 | 
            +
                        next unless File.exists?("#{path}/#{cb}")
         | 
| 111 | 
            +
                        @logger.warn("Running berkshelf on cookbook: #{cb}")
         | 
| 112 | 
            +
                        exec!("cd #{path}/#{cb} && #{@berks} install #{berks_config} && " +
         | 
| 113 | 
            +
                          "#{@berks} upload #{berks_config}", @logger)
         | 
| 114 | 
            +
                      end
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 83 119 | 
             
                def cookbook_delete(cookbooks)
         | 
| 84 120 | 
             
                  if cookbooks.any?
         | 
| 85 121 | 
             
                    cookbooks.each do |cookbook|
         | 
| @@ -101,19 +137,22 @@ module BetweenMeals | |
| 101 137 |  | 
| 102 138 | 
             
                def databag_upload(databags)
         | 
| 103 139 | 
             
                  if databags.any?
         | 
| 104 | 
            -
                    databags.group_by | 
| 140 | 
            +
                    databags.group_by(&:name).each do |dbname, dbs|
         | 
| 105 141 | 
             
                      create_databag_if_missing(dbname)
         | 
| 106 142 | 
             
                      dbitems = dbs.map do |x|
         | 
| 107 143 | 
             
                        File.join(@databag_dir, dbname, "#{x.item}.json")
         | 
| 108 144 | 
             
                      end.join(' ')
         | 
| 109 | 
            -
                      exec!( | 
| 145 | 
            +
                      exec!(
         | 
| 146 | 
            +
                        "#{@knife} data bag from file #{dbname} #{dbitems} -c #{@config}",
         | 
| 147 | 
            +
                        @logger
         | 
| 148 | 
            +
                      )
         | 
| 110 149 | 
             
                    end
         | 
| 111 150 | 
             
                  end
         | 
| 112 151 | 
             
                end
         | 
| 113 152 |  | 
| 114 153 | 
             
                def databag_delete(databags)
         | 
| 115 154 | 
             
                  if databags.any?
         | 
| 116 | 
            -
                    databags.group_by | 
| 155 | 
            +
                    databags.group_by(&:name).each do |dbname, dbs|
         | 
| 117 156 | 
             
                      dbs.each do |db|
         | 
| 118 157 | 
             
                        exec!("#{@knife} data bag delete #{dbname} #{db.item}" +
         | 
| 119 158 | 
             
                                " --yes -c #{@config}", @logger)
         | 
| @@ -146,7 +185,7 @@ BLOCK | |
| 146 185 | 
             
                  end
         | 
| 147 186 | 
             
                  if !File.exists?(@config) ||
         | 
| 148 187 | 
             
                     ::Digest::MD5.hexdigest(cfg) !=
         | 
| 149 | 
            -
             | 
| 188 | 
            +
                     ::Digest::MD5.hexdigest(File.read(@config))
         | 
| 150 189 | 
             
                    @logger.info("Generating #{@config}")
         | 
| 151 190 | 
             
                    File.write(@config, cfg)
         | 
| 152 191 | 
             
                  end
         | 
    
        data/lib/between_meals/repo.rb
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Copyright 2013-present Facebook
         | 
| 4 | 
            -
            # | 
| 4 | 
            +
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 6 6 | 
             
            # you may not use this file except in compliance with the License.
         | 
| 7 7 | 
             
            # You may obtain a copy of the License at
         | 
| 8 | 
            -
            # | 
| 8 | 
            +
            #
         | 
| 9 9 | 
             
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # Unless required by applicable law or agreed to in writing, software
         | 
| 12 12 | 
             
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 13 13 | 
             
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| @@ -19,8 +19,7 @@ require 'mixlib/shellout' | |
| 19 19 | 
             
            module BetweenMeals
         | 
| 20 20 | 
             
              # Local checkout wrapper
         | 
| 21 21 | 
             
              class Repo
         | 
| 22 | 
            -
                attr_reader :repo_path
         | 
| 23 | 
            -
                attr_writer :bin
         | 
| 22 | 
            +
                attr_reader :repo_path, :bin
         | 
| 24 23 |  | 
| 25 24 | 
             
                def initialize(repo_path, logger)
         | 
| 26 25 | 
             
                  @repo_path = repo_path
         | 
| @@ -35,93 +34,138 @@ module BetweenMeals | |
| 35 34 |  | 
| 36 35 | 
             
                def self.get(type, repo_path, logger)
         | 
| 37 36 | 
             
                  case type
         | 
| 37 | 
            +
                  when 'auto'
         | 
| 38 | 
            +
                    unless File.directory?(repo_path)
         | 
| 39 | 
            +
                      logger.warn("#{repo_path} does not point to a repo")
         | 
| 40 | 
            +
                      exit(1)
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                    logger.info('Trying to detect repo type')
         | 
| 43 | 
            +
                    require 'between_meals/repo/git'
         | 
| 44 | 
            +
                    require 'between_meals/repo/hg'
         | 
| 45 | 
            +
                    require 'between_meals/repo/svn'
         | 
| 46 | 
            +
                    [
         | 
| 47 | 
            +
                      BetweenMeals::Repo::Git,
         | 
| 48 | 
            +
                      BetweenMeals::Repo::Hg,
         | 
| 49 | 
            +
                      BetweenMeals::Repo::Svn,
         | 
| 50 | 
            +
                    ].each do |klass|
         | 
| 51 | 
            +
                      begin
         | 
| 52 | 
            +
                        r = klass.new(repo_path, logger)
         | 
| 53 | 
            +
                        if r.exists?
         | 
| 54 | 
            +
                          logger.info("Repo found to be #{klass.to_s.split('::').last}")
         | 
| 55 | 
            +
                          return r
         | 
| 56 | 
            +
                        end
         | 
| 57 | 
            +
                      rescue
         | 
| 58 | 
            +
                        logger.debug("Skipping #{klass}")
         | 
| 59 | 
            +
                      end
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                    logger.warn("Failed detecting repo type at #{repo_path}")
         | 
| 62 | 
            +
                    exit(1)
         | 
| 38 63 | 
             
                  when 'svn'
         | 
| 39 64 | 
             
                    require 'between_meals/repo/svn'
         | 
| 40 65 | 
             
                    BetweenMeals::Repo::Svn.new(repo_path, logger)
         | 
| 41 66 | 
             
                  when 'git'
         | 
| 42 67 | 
             
                    require 'between_meals/repo/git'
         | 
| 43 68 | 
             
                    BetweenMeals::Repo::Git.new(repo_path, logger)
         | 
| 69 | 
            +
                  when 'hg'
         | 
| 70 | 
            +
                    require 'between_meals/repo/hg'
         | 
| 71 | 
            +
                    BetweenMeals::Repo::Hg.new(repo_path, logger)
         | 
| 44 72 | 
             
                  else
         | 
| 45 73 | 
             
                    fail "Do not know repo type #{type}"
         | 
| 46 74 | 
             
                  end
         | 
| 47 75 | 
             
                end
         | 
| 48 76 |  | 
| 77 | 
            +
                def bin=(bin)
         | 
| 78 | 
            +
                  @bin = bin
         | 
| 79 | 
            +
                  @cmd.bin = bin
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 49 82 | 
             
                def exists?
         | 
| 50 | 
            -
                  fail  | 
| 83 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 51 84 | 
             
                end
         | 
| 52 85 |  | 
| 53 86 | 
             
                def status
         | 
| 54 | 
            -
                  fail  | 
| 87 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 55 88 | 
             
                end
         | 
| 56 89 |  | 
| 90 | 
            +
                # This method *must* succeed in the case of no repo directory so that
         | 
| 91 | 
            +
                # users can call `checkout`. Users may call `exists?` to find out if
         | 
| 92 | 
            +
                # we have an underlying repo yet.
         | 
| 57 93 | 
             
                def setup
         | 
| 58 | 
            -
                  fail  | 
| 94 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 59 95 | 
             
                end
         | 
| 60 96 |  | 
| 61 97 | 
             
                def head_rev
         | 
| 62 | 
            -
                  fail  | 
| 98 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 63 99 | 
             
                end
         | 
| 64 100 |  | 
| 65 101 | 
             
                def head_msg
         | 
| 66 | 
            -
                  fail  | 
| 102 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 67 103 | 
             
                end
         | 
| 68 104 |  | 
| 69 105 | 
             
                def head_msg=
         | 
| 70 | 
            -
                  fail  | 
| 106 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 71 107 | 
             
                end
         | 
| 72 108 |  | 
| 73 109 | 
             
                def head_parents
         | 
| 74 | 
            -
                  fail  | 
| 110 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 75 111 | 
             
                end
         | 
| 76 112 |  | 
| 77 113 | 
             
                def latest_revision
         | 
| 78 | 
            -
                  fail  | 
| 114 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 79 115 | 
             
                end
         | 
| 80 116 |  | 
| 81 117 | 
             
                def create(_url)
         | 
| 82 | 
            -
                  fail  | 
| 118 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 83 119 | 
             
                end
         | 
| 84 120 |  | 
| 85 121 | 
             
                # Return files changed between two revisions
         | 
| 86 122 | 
             
                def changes(_start_ref, _end_ref)
         | 
| 87 | 
            -
                  fail  | 
| 123 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 88 124 | 
             
                end
         | 
| 89 125 |  | 
| 90 126 | 
             
                def update
         | 
| 91 | 
            -
                  fail  | 
| 127 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 92 128 | 
             
                end
         | 
| 93 129 |  | 
| 94 130 | 
             
                # Return all files
         | 
| 95 131 | 
             
                def files
         | 
| 96 | 
            -
                  fail  | 
| 97 | 
            -
                end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
                def latest_revision
         | 
| 100 | 
            -
                  fail 'Not implemented'
         | 
| 132 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 101 133 | 
             
                end
         | 
| 102 134 |  | 
| 103 135 | 
             
                def head
         | 
| 104 | 
            -
                  fail  | 
| 136 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 105 137 | 
             
                end
         | 
| 106 138 |  | 
| 107 139 | 
             
                def checkout
         | 
| 108 | 
            -
                  fail  | 
| 109 | 
            -
                end
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                def update
         | 
| 112 | 
            -
                  fail 'Not implemented'
         | 
| 140 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 113 141 | 
             
                end
         | 
| 114 142 |  | 
| 115 143 | 
             
                def last_author
         | 
| 116 | 
            -
                  fail  | 
| 144 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 117 145 | 
             
                end
         | 
| 118 146 |  | 
| 119 147 | 
             
                def last_msg
         | 
| 120 | 
            -
                  fail  | 
| 148 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 121 149 | 
             
                end
         | 
| 122 150 |  | 
| 123 151 | 
             
                def last_msg=
         | 
| 124 | 
            -
                  fail  | 
| 152 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                def name
         | 
| 156 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                def email
         | 
| 160 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 161 | 
            +
                end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                def upstream?(_rev)
         | 
| 164 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 165 | 
            +
                end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                def valid_ref?(_rev)
         | 
| 168 | 
            +
                  fail "#{__method__} not implemented"
         | 
| 125 169 | 
             
                end
         | 
| 126 170 | 
             
              end
         | 
| 127 171 | 
             
            end
         |