git_duplicator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +23 -0
 - data/.rspec +2 -0
 - data/.test.env.example +13 -0
 - data/.travis.yml +21 -0
 - data/.yardopts +5 -0
 - data/Gemfile +21 -0
 - data/Guardfile +5 -0
 - data/LICENSE.md +16 -0
 - data/README.md +70 -0
 - data/Rakefile +10 -0
 - data/git_duplicator.gemspec +23 -0
 - data/lib/git_duplicator/duplicator.rb +66 -0
 - data/lib/git_duplicator/errors.rb +11 -0
 - data/lib/git_duplicator/helpers/authorization_header.rb +71 -0
 - data/lib/git_duplicator/null_logger.rb +14 -0
 - data/lib/git_duplicator/repositories.rb +3 -0
 - data/lib/git_duplicator/repository/repository.rb +41 -0
 - data/lib/git_duplicator/repository/service_repository.rb +29 -0
 - data/lib/git_duplicator/services/bitbucket.rb +67 -0
 - data/lib/git_duplicator/services/github.rb +63 -0
 - data/lib/git_duplicator/services.rb +15 -0
 - data/lib/git_duplicator/version.rb +15 -0
 - data/lib/git_duplicator.rb +15 -0
 - data/spec/git_duplicator/duplicator_spec.rb +82 -0
 - data/spec/git_duplicator/git_duplicator_spec.rb +102 -0
 - data/spec/git_duplicator/repository/repository_spec.rb +47 -0
 - data/spec/git_duplicator/repository/service_repository_spec.rb +25 -0
 - data/spec/git_duplicator/services/bitbucket_spec.rb +51 -0
 - data/spec/git_duplicator/services/github_spec.rb +52 -0
 - data/spec/git_duplicator/version_spec.rb +9 -0
 - data/spec/helper.rb +33 -0
 - metadata +118 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: c56bf9a2478b996375f297102452f577a678625f
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: c9dcca68935f1f25245686697d9e1ee191811b33
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 43b7d1d5308dcfbe6b812166463282c7ad47f6d0dbcd87b550ff38dab6eefaf36c17b481210c09af1d775dde79c4a05f82b1a6168399ac06497815f058f2d41f
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: a21c7b71c3b1269b19be4593c646873f05ade3fd6cf4e1dda211ffc1586e507dec80480d9bdbf0fe637936d1c401d144415dd89651e49d077e7713a364529ea9
         
     | 
    
        data/.gitignore
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            *.gem
         
     | 
| 
      
 2 
     | 
    
         
            +
            *.rbc
         
     | 
| 
      
 3 
     | 
    
         
            +
            .bundle
         
     | 
| 
      
 4 
     | 
    
         
            +
            .config
         
     | 
| 
      
 5 
     | 
    
         
            +
            .yardoc
         
     | 
| 
      
 6 
     | 
    
         
            +
            Gemfile.lock
         
     | 
| 
      
 7 
     | 
    
         
            +
            InstalledFiles
         
     | 
| 
      
 8 
     | 
    
         
            +
            _yardoc
         
     | 
| 
      
 9 
     | 
    
         
            +
            coverage
         
     | 
| 
      
 10 
     | 
    
         
            +
            doc/
         
     | 
| 
      
 11 
     | 
    
         
            +
            lib/bundler/man
         
     | 
| 
      
 12 
     | 
    
         
            +
            pkg
         
     | 
| 
      
 13 
     | 
    
         
            +
            rdoc
         
     | 
| 
      
 14 
     | 
    
         
            +
            spec/reports
         
     | 
| 
      
 15 
     | 
    
         
            +
            test/tmp
         
     | 
| 
      
 16 
     | 
    
         
            +
            test/version_tmp
         
     | 
| 
      
 17 
     | 
    
         
            +
            tmp
         
     | 
| 
      
 18 
     | 
    
         
            +
            *.bundle
         
     | 
| 
      
 19 
     | 
    
         
            +
            *.so
         
     | 
| 
      
 20 
     | 
    
         
            +
            *.o
         
     | 
| 
      
 21 
     | 
    
         
            +
            *.a
         
     | 
| 
      
 22 
     | 
    
         
            +
            mkmf.log
         
     | 
| 
      
 23 
     | 
    
         
            +
            *.env
         
     | 
    
        data/.rspec
    ADDED
    
    
    
        data/.test.env.example
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            bundler_args: "--without development"
         
     | 
| 
      
 2 
     | 
    
         
            +
            language: ruby
         
     | 
| 
      
 3 
     | 
    
         
            +
            rvm:
         
     | 
| 
      
 4 
     | 
    
         
            +
            - 1.9.3
         
     | 
| 
      
 5 
     | 
    
         
            +
            - 2.0.0
         
     | 
| 
      
 6 
     | 
    
         
            +
            - 2.1
         
     | 
| 
      
 7 
     | 
    
         
            +
            - rbx-2
         
     | 
| 
      
 8 
     | 
    
         
            +
            - jruby-19mode
         
     | 
| 
      
 9 
     | 
    
         
            +
            - ruby-head
         
     | 
| 
      
 10 
     | 
    
         
            +
            - jruby-head
         
     | 
| 
      
 11 
     | 
    
         
            +
            matrix:
         
     | 
| 
      
 12 
     | 
    
         
            +
              include:
         
     | 
| 
      
 13 
     | 
    
         
            +
              - rvm: jruby-19mode
         
     | 
| 
      
 14 
     | 
    
         
            +
                env: JRUBY_OPTS="$JRUBY_OPTS --debug"
         
     | 
| 
      
 15 
     | 
    
         
            +
              - rvm: jruby-head
         
     | 
| 
      
 16 
     | 
    
         
            +
                env: JRUBY_OPTS="$JRUBY_OPTS --debug"
         
     | 
| 
      
 17 
     | 
    
         
            +
              allow_failures:
         
     | 
| 
      
 18 
     | 
    
         
            +
              - rvm: jruby-head
         
     | 
| 
      
 19 
     | 
    
         
            +
              - rvm: rbx-2
         
     | 
| 
      
 20 
     | 
    
         
            +
              - rvm: ruby-head
         
     | 
| 
      
 21 
     | 
    
         
            +
              fast_finish: true
         
     | 
    
        data/.yardopts
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            source 'https://rubygems.org'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem 'rake'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            group :development do
         
     | 
| 
      
 6 
     | 
    
         
            +
              gem 'pry'
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            group :test do
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem 'coveralls', '~> 0.7', :require => false
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem 'rspec', '>= 2.14'
         
     | 
| 
      
 12 
     | 
    
         
            +
              gem 'rspec-nc'
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem 'rubocop', '>= 0.2', :platforms => [:ruby_19, :ruby_20, :ruby_21]
         
     | 
| 
      
 14 
     | 
    
         
            +
              gem 'simplecov', '~> 0.7.1', :require => false
         
     | 
| 
      
 15 
     | 
    
         
            +
              gem 'guard', '~> 2.6'
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem 'guard-rspec', '~> 4.2'
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem 'webmock', '~> 1.1'
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem 'dotenv'
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            gemspec
         
     | 
    
        data/Guardfile
    ADDED
    
    
    
        data/LICENSE.md
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2014 Khaled alHabache
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            LGPL-3.0 License
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            This library is free software; you can redistribute it and/or
         
     | 
| 
      
 6 
     | 
    
         
            +
            modify it under the terms of the GNU Lesser General Public
         
     | 
| 
      
 7 
     | 
    
         
            +
            License as published by the Free Software Foundation; either
         
     | 
| 
      
 8 
     | 
    
         
            +
            version 3.0 of the License, or (at your option) any later version.
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            This library is distributed in the hope that it will be useful,
         
     | 
| 
      
 11 
     | 
    
         
            +
            but WITHOUT ANY WARRANTY; without even the implied warranty of
         
     | 
| 
      
 12 
     | 
    
         
            +
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
         
     | 
| 
      
 13 
     | 
    
         
            +
            Lesser General Public License for more details.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            You should have received a copy of the GNU Lesser General Public
         
     | 
| 
      
 16 
     | 
    
         
            +
            License along with this library.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,70 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Git Duplicator
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Duplicating git repositories without forking.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            - [x] Duplicate any repository
         
     | 
| 
      
 6 
     | 
    
         
            +
            - [x] Additional Github support
         
     | 
| 
      
 7 
     | 
    
         
            +
            - [x] Additional Bibucket support
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Add this line to your application's Gemfile:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                gem 'git_duplicator'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            And then execute:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                $ bundle
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Or install it yourself as:
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                $ gem install git_duplicator
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            ### Basic usage
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            Duplicate a repository. It assumes that you have the destination repository initiated. 
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 30 
     | 
    
         
            +
            require 'git_duplicator'
         
     | 
| 
      
 31 
     | 
    
         
            +
            from = GitDuplicator::Repository
         
     | 
| 
      
 32 
     | 
    
         
            +
            .new('source repo name', 'source repo url')
         
     | 
| 
      
 33 
     | 
    
         
            +
            to = GitDuplicator::Repository
         
     | 
| 
      
 34 
     | 
    
         
            +
            .new('destination repo name', 'destination repo url')
         
     | 
| 
      
 35 
     | 
    
         
            +
            GitDuplicator.perform(from, to)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            ```
         
     | 
| 
      
 38 
     | 
    
         
            +
            ### Advanced usage
         
     | 
| 
      
 39 
     | 
    
         
            +
            - You can create the destination repository automatically. This needs you to provide the needed authentication credentials for the script.
         
     | 
| 
      
 40 
     | 
    
         
            +
            - You can set the clone working path locally for the script to work. It's a temporary workplace that will get swiped after finishing.
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 43 
     | 
    
         
            +
            require 'git_duplicator'
         
     | 
| 
      
 44 
     | 
    
         
            +
            from = GitDuplicator::Repository
         
     | 
| 
      
 45 
     | 
    
         
            +
            .new('source repo name', 'source repo url')
         
     | 
| 
      
 46 
     | 
    
         
            +
            to = GitDuplicator::Services::GithubRepository
         
     | 
| 
      
 47 
     | 
    
         
            +
            .new('destination repo name', 'destination owner', {auth2_token: 'some token'})
         
     | 
| 
      
 48 
     | 
    
         
            +
            GitDuplicator.perform(from, to, force_create_destination: true, clone_path: 'path/to/tmp')
         
     | 
| 
      
 49 
     | 
    
         
            +
            ```
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            ### Available Services
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            The script works with any repository that you have access to. However, right now, there are 2 services that are implemented to help you initiate an empty destination repository. That way, you don't need to create them manaullay before doing the duplicaton. The services are Github and Bitbucket.
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            ### Adding new Services
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            Adding new service, if needed, should be straight forward. You can look at the source of the Bitbucket or Github services implementations, where they inherit a base abstract class that you need to inherit as well.
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            ### Running tests
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            To be able to run the tests, specially the acceptance ones, you need to rename the `.test.env.example` to `.test.env` and add the needed credentials for your accounts.
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            ## Contributing
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            1. Fork it ( https://github.com/Startappz/git_duplicator/fork )
         
     | 
| 
      
 67 
     | 
    
         
            +
            2. Create your feature branch (`git checkout -b my-new-feature`)
         
     | 
| 
      
 68 
     | 
    
         
            +
            3. Commit your changes (`git commit -am 'Add some feature'`)
         
     | 
| 
      
 69 
     | 
    
         
            +
            4. Push to the branch (`git push origin my-new-feature`)
         
     | 
| 
      
 70 
     | 
    
         
            +
            5. Create a new Pull Request
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'bundler/gem_tasks'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'dotenv/tasks'
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Default directory to look in is `/specs`
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Run with `rake spec`
         
     | 
| 
      
 6 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec) do |task|
         
     | 
| 
      
 7 
     | 
    
         
            +
              task.rspec_opts = ['--color', '--format', 'doc']
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            task :default => :spec
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'git_duplicator/version'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |gem|
         
     | 
| 
      
 7 
     | 
    
         
            +
              gem.name          = "git_duplicator"
         
     | 
| 
      
 8 
     | 
    
         
            +
              gem.version       = GitDuplicator::Version
         
     | 
| 
      
 9 
     | 
    
         
            +
              gem.authors       = ["Khaled alHabache"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem.email         = ["khellls@gmail.com"]
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem.summary       = %q{Duplicating git repositories without forking.}
         
     | 
| 
      
 12 
     | 
    
         
            +
              gem.description   = %q{Duplicating git repositories without forking.}
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem.homepage      = "https://github.com/Startappz/git_duplicator"
         
     | 
| 
      
 14 
     | 
    
         
            +
              gem.license       = 'LGPL-3'
         
     | 
| 
      
 15 
     | 
    
         
            +
              gem.required_ruby_version = '>= 1.9.3'
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem.files         = `git ls-files`.split($/)
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem.executables   = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem.test_files = Dir.glob('gem/**/*')
         
     | 
| 
      
 19 
     | 
    
         
            +
              gem.require_paths = ['lib']
         
     | 
| 
      
 20 
     | 
    
         
            +
              gem.add_dependency 'http', '~> 0.6'
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem.add_dependency 'git', '~> 1.2'
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem.add_dependency 'simple_oauth', '~> 0.2'
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'null_logger'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Duplicator
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :from, :to, :logger, :clone_path, :force_create_destination
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                # @param [GitDuplicator::Repository, GitDuplicator::ServiceRepository]
         
     | 
| 
      
 9 
     | 
    
         
            +
                #  from repository to mirror
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @param [GitDuplicator::Repository, GitDuplicator::ServiceRepository]
         
     | 
| 
      
 11 
     | 
    
         
            +
                #  to repository to mirror to
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @param [Hash] options
         
     | 
| 
      
 13 
     | 
    
         
            +
                # @option options [String] :clone_path
         
     | 
| 
      
 14 
     | 
    
         
            +
                #   path to clone the repository to
         
     | 
| 
      
 15 
     | 
    
         
            +
                # @option options [Boolean] :force_create_destination
         
     | 
| 
      
 16 
     | 
    
         
            +
                #  delete the exisiting service repo then create it
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @option options [#info] :logger log what's going on
         
     | 
| 
      
 18 
     | 
    
         
            +
                def initialize(from, to, options = {})
         
     | 
| 
      
 19 
     | 
    
         
            +
                  self.from = from
         
     | 
| 
      
 20 
     | 
    
         
            +
                  self.to = to
         
     | 
| 
      
 21 
     | 
    
         
            +
                  self.clone_path = options.fetch(:clone_path) { '/tmp' }
         
     | 
| 
      
 22 
     | 
    
         
            +
                  self.force_create_destination =
         
     | 
| 
      
 23 
     | 
    
         
            +
                    options.fetch(:force_create_destination) { false }
         
     | 
| 
      
 24 
     | 
    
         
            +
                  self.logger = options.fetch(:logger) { NullLogger.new }
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                # Perform the duplication
         
     | 
| 
      
 28 
     | 
    
         
            +
                def perform
         
     | 
| 
      
 29 
     | 
    
         
            +
                  recreate_destination
         
     | 
| 
      
 30 
     | 
    
         
            +
                  clone_source
         
     | 
| 
      
 31 
     | 
    
         
            +
                  mirror
         
     | 
| 
      
 32 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 33 
     | 
    
         
            +
                  clean_up
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                private
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                attr_accessor :source_cloned
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def recreate_destination
         
     | 
| 
      
 41 
     | 
    
         
            +
                  return unless force_create_destination
         
     | 
| 
      
 42 
     | 
    
         
            +
                  logger.info("Deleting existing destination repo: #{to.url}")
         
     | 
| 
      
 43 
     | 
    
         
            +
                  to.delete
         
     | 
| 
      
 44 
     | 
    
         
            +
                  logger.info("Creating destination repo: #{to.url}")
         
     | 
| 
      
 45 
     | 
    
         
            +
                  to.create
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def clone_source
         
     | 
| 
      
 49 
     | 
    
         
            +
                  logger.info("Cloning bare Gitorious repo: #{from.url}")
         
     | 
| 
      
 50 
     | 
    
         
            +
                  from.bare_clone(clone_path)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  self.source_cloned = true
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                def mirror
         
     | 
| 
      
 55 
     | 
    
         
            +
                  logger.info("Mirroring Gitorious to Bitbucket: #{from.url}")
         
     | 
| 
      
 56 
     | 
    
         
            +
                  from.mirror(to.url)
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                def clean_up
         
     | 
| 
      
 60 
     | 
    
         
            +
                  return unless source_cloned
         
     | 
| 
      
 61 
     | 
    
         
            +
                  logger.info 'Clean local source repo'
         
     | 
| 
      
 62 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{from.name}")
         
     | 
| 
      
 63 
     | 
    
         
            +
                  @cloned = nil
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 2 
     | 
    
         
            +
              class MigrationError < StandardError; end
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              class RepositoryDeletionError < MigrationError; end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              class RepositoryCreationError < MigrationError; end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              class RepositoryCloningError < MigrationError; end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              class RepositoryMirorringError < MigrationError; end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,71 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'base64'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'simple_oauth'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Generates authentication header
         
     | 
| 
      
 7 
     | 
    
         
            +
                class AuthorizationHeader
         
     | 
| 
      
 8 
     | 
    
         
            +
                  OAUTH2_KEYS = [:oauth2_token]
         
     | 
| 
      
 9 
     | 
    
         
            +
                  OAUTH_KEYS = [:consumer_key, :consumer_secret, :token, :token_secret]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  BASIC_KEYS = [:username, :password]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # @param [Hash] credentials
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @option credentials [Symbol] :oauth2_token used in oAuth2 authentication
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @option credentials [Symbol] :consumer_key used in oAuth authentication
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @option credentials [Symbol] :consumer_secret used in oAuth authentication
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # @option credentials [Symbol] :token used in oAuth authentication
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # @option credentials [Symbol] :token_secret used in oAuth authentication
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # @option credentials [Symbol] :username used in basic authentication
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # @option credentials [Symbol] :password used in basic authentication
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # @param [Hash] request used in generating oauth headers
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # @option request [Symbol] :method
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # @option request [String] :url
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # @option request [Array] :params
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def initialize(credentials, request)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    self.credentials = credentials
         
     | 
| 
      
 26 
     | 
    
         
            +
                    self.request_method = request.fetch(:method)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    self.request_url = request.fetch(:url)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    self.request_params = request.fetch(:params) { [] }
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  # Generate the header
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def generate
         
     | 
| 
      
 33 
     | 
    
         
            +
                    if exists?(self.class::OAUTH2_KEYS)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      oauth2_header
         
     | 
| 
      
 35 
     | 
    
         
            +
                    elsif exists?(self.class::OAUTH_KEYS)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      oauth_header
         
     | 
| 
      
 37 
     | 
    
         
            +
                    elsif exists?(self.class::BASIC_KEYS)
         
     | 
| 
      
 38 
     | 
    
         
            +
                      basic_authenticaion_header
         
     | 
| 
      
 39 
     | 
    
         
            +
                    else
         
     | 
| 
      
 40 
     | 
    
         
            +
                      fail ArgumentError, 'Proper authentication keys are missing'
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  private
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  attr_accessor :credentials, :request_method, :request_url, :request_params
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def exists?(list)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    list.all? { |value| credentials.keys.include?(value) }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def oauth2_header
         
     | 
| 
      
 53 
     | 
    
         
            +
                    "token #{credentials[:oauth2_token]}"
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def basic_authenticaion_header
         
     | 
| 
      
 57 
     | 
    
         
            +
                    "Basic #{base64_username_password}"
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  def oauth_header
         
     | 
| 
      
 61 
     | 
    
         
            +
                    SimpleOAuth::Header.new(request_method, request_url,
         
     | 
| 
      
 62 
     | 
    
         
            +
                                            request_params, credentials).to_s
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def base64_username_password
         
     | 
| 
      
 66 
     | 
    
         
            +
                    Base64.encode64("#{credentials[:username]}" \
         
     | 
| 
      
 67 
     | 
    
         
            +
                                    ":#{credentials[:password]}")
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'git'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Basic Repostiroy
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Repository
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :name, :url
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :repo
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # Initializer
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @param [String] name name of the repository
         
     | 
| 
      
 11 
     | 
    
         
            +
                # @param [String] url URL of the repository
         
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(name, url)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.name = name
         
     | 
| 
      
 14 
     | 
    
         
            +
                  self.url = url
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                # Repository attribute setter
         
     | 
| 
      
 18 
     | 
    
         
            +
                # @param [Git::Base] repository
         
     | 
| 
      
 19 
     | 
    
         
            +
                def repo=(repository)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  fail(TypeError) unless repository.is_a?(Git::Base)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @repo = repository
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # Bare clone the repository
         
     | 
| 
      
 25 
     | 
    
         
            +
                # @param [String] path_to_repo path to clone the repository to
         
     | 
| 
      
 26 
     | 
    
         
            +
                def bare_clone(path_to_repo)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  self.repo = Git.clone(url, name, bare: true, path: path_to_repo)
         
     | 
| 
      
 28 
     | 
    
         
            +
                rescue => exception
         
     | 
| 
      
 29 
     | 
    
         
            +
                  raise RepositoryCloningError, exception.message
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                # Mirror the repository
         
     | 
| 
      
 33 
     | 
    
         
            +
                # @param [String] destination_url URL of destination repository 
         
     | 
| 
      
 34 
     | 
    
         
            +
                def mirror(destination_url)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  fail('No local repo defined. Set the "repo" attribute') unless repo
         
     | 
| 
      
 36 
     | 
    
         
            +
                  repo.push(destination_url, '--mirror')
         
     | 
| 
      
 37 
     | 
    
         
            +
                rescue => exception
         
     | 
| 
      
 38 
     | 
    
         
            +
                  raise RepositoryMirorringError, exception.message
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Abstract class to use when defining new Git service provider
         
     | 
| 
      
 3 
     | 
    
         
            +
              class ServiceRepository < Repository
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr_accessor :owner
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                # Initializer
         
     | 
| 
      
 7 
     | 
    
         
            +
                # @param [String] name name of the repository
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @param [String] owner owner of the repository
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(name, owner)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  self.owner = owner
         
     | 
| 
      
 11 
     | 
    
         
            +
                  super(name, url)
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # URL of the repositroy
         
     | 
| 
      
 15 
     | 
    
         
            +
                def url
         
     | 
| 
      
 16 
     | 
    
         
            +
                  fail NotImplementedError
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # Create the repositroy
         
     | 
| 
      
 20 
     | 
    
         
            +
                def create
         
     | 
| 
      
 21 
     | 
    
         
            +
                  fail NotImplementedError
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # Delete the repositroy
         
     | 
| 
      
 25 
     | 
    
         
            +
                def delete
         
     | 
| 
      
 26 
     | 
    
         
            +
                  fail NotImplementedError
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'http'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../helpers/authorization_header'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Services
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Bitbucket based repository
         
     | 
| 
      
 7 
     | 
    
         
            +
                class BitbucketRepository < ServiceRepository
         
     | 
| 
      
 8 
     | 
    
         
            +
                  BASE_URI = 'https://api.bitbucket.org/2.0'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_accessor :credentials, :options
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # Initializer
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @param [String] name name of the repository
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @param [String] owner owner of the repository
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @param [Hash] credentials
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # @option credentials [Symbol] :consumer_key used in oAuth authentication
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # @option credentials [Symbol] :consumer_secret used in oAuth authentication
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # @option credentials [Symbol] :token used in oAuth authentication
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # @option credentials [Symbol] :token_secret used in oAuth authentication
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # @option credentials [Symbol] :username used in basic authentication
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # @option credentials [Symbol] :password used in basic authentication
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # @param [Hash] options options for creation
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # @see https://confluence.atlassian.com/display/BITBUCKET/repository+Resource#repositoryResource-POSTanewrepository
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def initialize(name, owner, credentials = {}, options = {})
         
     | 
| 
      
 25 
     | 
    
         
            +
                    super(name, owner)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    self.credentials = credentials
         
     | 
| 
      
 27 
     | 
    
         
            +
                    self.options = options
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  # URL of the repositroy
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def url
         
     | 
| 
      
 32 
     | 
    
         
            +
                    "git@bitbucket.org:#{owner}/#{name}.git"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Create the repositroy
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @see https://confluence.atlassian.com/display/BITBUCKET/repository+Resource#repositoryResource-POSTanewrepository
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def create
         
     | 
| 
      
 38 
     | 
    
         
            +
                    request_url = BASE_URI + "/repositories/#{owner}/#{name}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                    response = HTTP.with(headers(:post, request_url))
         
     | 
| 
      
 40 
     | 
    
         
            +
                    .post(request_url, json: options)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    code, body = response.code.to_i, response.body
         
     | 
| 
      
 42 
     | 
    
         
            +
                    fail(RepositoryCreationError, body) unless 200 == code
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  # Delete the repositroy
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # @see https://confluence.atlassian.com/display/BITBUCKET/repository+Resource#repositoryResource-DELETEarepository
         
     | 
| 
      
 47 
     | 
    
         
            +
                  def delete
         
     | 
| 
      
 48 
     | 
    
         
            +
                    request_url = BASE_URI + "/repositories/#{owner}/#{name}"
         
     | 
| 
      
 49 
     | 
    
         
            +
                    response = HTTP.with(headers(:delete, request_url)).delete(request_url)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    code, body = response.code.to_i, response.body
         
     | 
| 
      
 51 
     | 
    
         
            +
                    fail(RepositoryDeletionError, body) unless [204, 404].include?(code)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  private
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def headers(method, url)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    {
         
     | 
| 
      
 58 
     | 
    
         
            +
                      'Content-Type' => 'application/json',
         
     | 
| 
      
 59 
     | 
    
         
            +
                      'Authorization' =>
         
     | 
| 
      
 60 
     | 
    
         
            +
                      Helpers::AuthorizationHeader.new(
         
     | 
| 
      
 61 
     | 
    
         
            +
                        credentials, method: method, url: url
         
     | 
| 
      
 62 
     | 
    
         
            +
                      ).generate
         
     | 
| 
      
 63 
     | 
    
         
            +
                    }
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'http'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../helpers/authorization_header'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Services
         
     | 
| 
      
 6 
     | 
    
         
            +
                class GithubRepository < ServiceRepository
         
     | 
| 
      
 7 
     | 
    
         
            +
                  BASE_URI = 'https://api.github.com'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  attr_accessor :credentials, :options
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  # Initializer
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # @param [String] name name of the repository
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @param [String] owner owner of the repository
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @param [Hash] credentials
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @option credentials [Symbol] :oauth2_token used in oAuth2 authentication
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # @option credentials [Symbol] :username used in basic authentication
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # @option credentials [Symbol] :password used in basic authentication
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # @param [Hash] options options for creation
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # @see https://developer.github.com/v3/repos/#create
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def initialize(name, owner, credentials = {}, options = {})
         
     | 
| 
      
 21 
     | 
    
         
            +
                    super(name, owner)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    self.credentials = credentials
         
     | 
| 
      
 23 
     | 
    
         
            +
                    self.options = options
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  # URL of the repositroy
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def url
         
     | 
| 
      
 28 
     | 
    
         
            +
                    "git@github.com:#{owner}/#{name}.git"
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  # Create the repository
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @see https://developer.github.com/v3/repos/#create
         
     | 
| 
      
 33 
     | 
    
         
            +
                  def create
         
     | 
| 
      
 34 
     | 
    
         
            +
                    request_url = BASE_URI + '/user/repos'
         
     | 
| 
      
 35 
     | 
    
         
            +
                    response = HTTP.with(headers(:post, request_url))
         
     | 
| 
      
 36 
     | 
    
         
            +
                    .post(request_url, json: options.merge(name: name))
         
     | 
| 
      
 37 
     | 
    
         
            +
                    code, body = response.code.to_i, response.body
         
     | 
| 
      
 38 
     | 
    
         
            +
                    fail(RepositoryCreationError, body) unless 201 == code
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  # Delete the repositroy
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # @see https://developer.github.com/v3/repos/#delete-a-repository
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def delete
         
     | 
| 
      
 44 
     | 
    
         
            +
                    request_url = BASE_URI + "/repos/#{owner}/#{name}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                    response = HTTP.with(headers(:delete, request_url)).delete(request_url)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    code, body = response.code.to_i, response.body
         
     | 
| 
      
 47 
     | 
    
         
            +
                    fail(RepositoryDeletionError, body) unless [204, 404].include?(code)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  private
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def headers(method, url)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    {
         
     | 
| 
      
 54 
     | 
    
         
            +
                      'Accept' => 'application/vnd.github.v3+json',
         
     | 
| 
      
 55 
     | 
    
         
            +
                      'Authorization' =>
         
     | 
| 
      
 56 
     | 
    
         
            +
                      Helpers::AuthorizationHeader.new(
         
     | 
| 
      
 57 
     | 
    
         
            +
                        credentials, method: method, url: url
         
     | 
| 
      
 58 
     | 
    
         
            +
                      ).generate
         
     | 
| 
      
 59 
     | 
    
         
            +
                    }
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Load all implemented services
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Services
         
     | 
| 
      
 4 
     | 
    
         
            +
                Dir[File.dirname(__FILE__) + '/services/**/*.rb'].each do |file|
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # Get camelized class name
         
     | 
| 
      
 6 
     | 
    
         
            +
                  filename = File.basename(file, '.rb')
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # Add _gateway suffix
         
     | 
| 
      
 8 
     | 
    
         
            +
                  gateway_name = filename + '_repository'
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # Camelize the string to get the class name
         
     | 
| 
      
 10 
     | 
    
         
            +
                  gateway_class = gateway_name.split('_').map(&:capitalize).join
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Register for autoloading
         
     | 
| 
      
 12 
     | 
    
         
            +
                  autoload gateway_class, file
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'git_duplicator/version'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'git_duplicator/duplicator'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'git_duplicator/repositories'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'git_duplicator/services'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # Main module
         
     | 
| 
      
 7 
     | 
    
         
            +
            module GitDuplicator
         
     | 
| 
      
 8 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Perform the duplication
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @see GitDuplicator::Duplicator
         
     | 
| 
      
 11 
     | 
    
         
            +
                def perform(from, to, options)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  Duplicator.new(from, to, options).perform
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,82 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe GitDuplicator::Duplicator do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:path) { '/somepath' }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:from) do
         
     | 
| 
      
 6 
     | 
    
         
            +
                double(name: 'somename', bare_clone: nil, mirror: nil, url: 'somewhere1')
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
              let(:to) { double(delete: nil, create: nil, url: 'somewhere2') }
         
     | 
| 
      
 9 
     | 
    
         
            +
              let(:duplicator) { GitDuplicator::Duplicator.new(from, to, options) }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              describe '#perform' do
         
     | 
| 
      
 12 
     | 
    
         
            +
                context 'force_create_destination is set' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                  let(:options) { { clone_path: path, force_create_destination: true } }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  it 'deletes existing destination repo' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                    expect(to).to receive(:delete)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  it 'creates the destination repo' do
         
     | 
| 
      
 21 
     | 
    
         
            +
                    expect(to).to receive(:create)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  it 'bare clones the source repo' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                    expect(from).to receive(:bare_clone).with(path)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  it 'mirrors from bare clone to destination' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                    expect(from).to receive(:mirror).with(to.url)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  it 'cleans up' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                    expect(FileUtils).to receive(:rm_rf)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    .with("#{duplicator.clone_path}/#{from.name}")
         
     | 
| 
      
 38 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  it 'logs 5 times' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    expect(duplicator.logger).to receive(:info).exactly(5).times
         
     | 
| 
      
 43 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                context 'force_create_destination is false' do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  let(:options) { { clone_path: path } }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  it 'deletes existing destination repo' do
         
     | 
| 
      
 51 
     | 
    
         
            +
                    expect(to).not_to receive(:delete)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  it 'creates the destination repo' do
         
     | 
| 
      
 56 
     | 
    
         
            +
                    expect(to).not_to receive(:create)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  it 'bare clones the source repo' do
         
     | 
| 
      
 61 
     | 
    
         
            +
                    expect(from).to receive(:bare_clone).with(path)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  it 'mirrors from bare clone to destination' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                    expect(from).to receive(:mirror).with(to.url)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  it 'cleans up' do
         
     | 
| 
      
 71 
     | 
    
         
            +
                    expect(FileUtils).to receive(:rm_rf)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    .with("#{duplicator.clone_path}/#{from.name}")
         
     | 
| 
      
 73 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  it 'logs 3 times' do
         
     | 
| 
      
 77 
     | 
    
         
            +
                    expect(duplicator.logger).to receive(:info).exactly(3).times
         
     | 
| 
      
 78 
     | 
    
         
            +
                    duplicator.perform
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            def random_name
         
     | 
| 
      
 4 
     | 
    
         
            +
              rand(36**5).to_s(36)
         
     | 
| 
      
 5 
     | 
    
         
            +
            end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            describe GitDuplicator do
         
     | 
| 
      
 8 
     | 
    
         
            +
              before(:each) { WebMock.allow_net_connect! }
         
     | 
| 
      
 9 
     | 
    
         
            +
              let(:clone_path) { '/tmp' }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              describe '#perform' do
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                let(:credentials) do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  { consumer_key: ENV['BITBUCKET_CONSUMER_KEY'],
         
     | 
| 
      
 15 
     | 
    
         
            +
                    consumer_secret: ENV['BITBUCKET_CONSUMER_SECRET'],
         
     | 
| 
      
 16 
     | 
    
         
            +
                    token: ENV['BITBUCKET_TOKEN'],
         
     | 
| 
      
 17 
     | 
    
         
            +
                    token_secret: ENV['BITBUCKET_TOKEN_SECRET'] }
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                it 'mirrors from service to service without ' \
         
     | 
| 
      
 21 
     | 
    
         
            +
                'force_create_destination option' do
         
     | 
| 
      
 22 
     | 
    
         
            +
                  skip
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # Setup
         
     | 
| 
      
 24 
     | 
    
         
            +
                  from = GitDuplicator::Services::GithubRepository
         
     | 
| 
      
 25 
     | 
    
         
            +
                  .new('naught', 'avdi')
         
     | 
| 
      
 26 
     | 
    
         
            +
                  to = GitDuplicator::Services::BitbucketRepository
         
     | 
| 
      
 27 
     | 
    
         
            +
                  .new(ENV['TESTING_REPO'], ENV['BITBUCKET_USER'], credentials)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  to.create
         
     | 
| 
      
 29 
     | 
    
         
            +
                  GitDuplicator.perform(from, to, clone_path: clone_path)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  mirrored_name = random_name
         
     | 
| 
      
 31 
     | 
    
         
            +
                  result_name = random_name
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  # Exercise
         
     | 
| 
      
 34 
     | 
    
         
            +
                  mirrored = Git.clone(from.url, mirrored_name, path: clone_path)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  result = Git.clone(from.url, result_name, path: clone_path)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  # Verify
         
     | 
| 
      
 38 
     | 
    
         
            +
                  expect(result.object('HEAD^').to_s).to eq(mirrored.object('HEAD^').to_s)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Teardown
         
     | 
| 
      
 41 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{mirrored_name}")
         
     | 
| 
      
 42 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{result_name}")
         
     | 
| 
      
 43 
     | 
    
         
            +
                  to.delete
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                it 'mirrors from service to service with ' \
         
     | 
| 
      
 47 
     | 
    
         
            +
                'force_create_destination option' do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  skip
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # Setup
         
     | 
| 
      
 50 
     | 
    
         
            +
                  from = GitDuplicator::Services::GithubRepository
         
     | 
| 
      
 51 
     | 
    
         
            +
                  .new('naught', 'avdi')
         
     | 
| 
      
 52 
     | 
    
         
            +
                  to = GitDuplicator::Services::BitbucketRepository
         
     | 
| 
      
 53 
     | 
    
         
            +
                  .new(ENV['TESTING_REPO'], ENV['BITBUCKET_USER'], credentials)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  GitDuplicator.perform(from, to,
         
     | 
| 
      
 55 
     | 
    
         
            +
                                        clone_path: clone_path,
         
     | 
| 
      
 56 
     | 
    
         
            +
                                        force_create_destination: true)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  mirrored_name = random_name
         
     | 
| 
      
 58 
     | 
    
         
            +
                  result_name = random_name
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  # Exercise
         
     | 
| 
      
 61 
     | 
    
         
            +
                  mirrored = Git.clone(from.url, mirrored_name, path: clone_path)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  result = Git.clone(from.url, result_name, path: clone_path)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  # Verify
         
     | 
| 
      
 65 
     | 
    
         
            +
                  expect(result.object('HEAD^').to_s).to eq(mirrored.object('HEAD^').to_s)
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  # Teardown
         
     | 
| 
      
 68 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{mirrored_name}")
         
     | 
| 
      
 69 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{result_name}")
         
     | 
| 
      
 70 
     | 
    
         
            +
                  to.delete
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                it 'mirrors from basic to service with ' \
         
     | 
| 
      
 74 
     | 
    
         
            +
                'force_create_destination option' do
         
     | 
| 
      
 75 
     | 
    
         
            +
                  skip
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # Setup
         
     | 
| 
      
 77 
     | 
    
         
            +
                  from = GitDuplicator::Repository
         
     | 
| 
      
 78 
     | 
    
         
            +
                  .new('naught', 'https://github.com/avdi/naught.git')
         
     | 
| 
      
 79 
     | 
    
         
            +
                  to = GitDuplicator::Services::BitbucketRepository
         
     | 
| 
      
 80 
     | 
    
         
            +
                  .new(ENV['TESTING_REPO'], ENV['BITBUCKET_USER'], credentials)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  GitDuplicator.perform(from, to,
         
     | 
| 
      
 82 
     | 
    
         
            +
                                        clone_path: clone_path,
         
     | 
| 
      
 83 
     | 
    
         
            +
                                        force_create_destination: true)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  mirrored_name = random_name
         
     | 
| 
      
 85 
     | 
    
         
            +
                  result_name = random_name
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  # Exercise
         
     | 
| 
      
 88 
     | 
    
         
            +
                  mirrored = Git.clone(from.url, mirrored_name, path: clone_path)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  result = Git.clone(from.url, result_name, path: clone_path)
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  # Verify
         
     | 
| 
      
 92 
     | 
    
         
            +
                  expect(result.object('HEAD^').to_s).to eq(mirrored.object('HEAD^').to_s)
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  # Teardown
         
     | 
| 
      
 95 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{mirrored_name}")
         
     | 
| 
      
 96 
     | 
    
         
            +
                  FileUtils.rm_rf("#{clone_path}/#{result_name}")
         
     | 
| 
      
 97 
     | 
    
         
            +
                  to.delete
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../../helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe GitDuplicator::Repository do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:path) { 'somepath' }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:name) { 'something' }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:url) { 'someurl' }
         
     | 
| 
      
 7 
     | 
    
         
            +
              let(:to_url) { 'someurl' }
         
     | 
| 
      
 8 
     | 
    
         
            +
              let(:repo) { described_class.new(name, url) }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              describe '#repo=' do
         
     | 
| 
      
 11 
     | 
    
         
            +
                it 'assignes the attribute in case of Git::Base type' do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  val = Git::Base.new
         
     | 
| 
      
 13 
     | 
    
         
            +
                  repo.repo = val
         
     | 
| 
      
 14 
     | 
    
         
            +
                  expect(repo.repo).to eq(val)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                it 'raise ArgumentError in case the attribute type is not Git::Base' do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  expect { repo.repo = 1 }.to raise_error(TypeError)
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              describe '#bare_clone' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                before(:each) { allow(repo).to receive(:repo=) }
         
     | 
| 
      
 24 
     | 
    
         
            +
                it 'clones a repo' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  expect(Git).to receive(:clone).with(url, name, path: path, bare: true)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  repo.bare_clone(path)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                it 'raises an exception in case of failure' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  expect { repo.bare_clone('') }
         
     | 
| 
      
 31 
     | 
    
         
            +
                  .to raise_error(GitDuplicator::RepositoryCloningError)
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              describe '#mirror' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                it 'mirrors a repo' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  repo.repo = Git::Base.new
         
     | 
| 
      
 38 
     | 
    
         
            +
                  expect(repo.repo).to receive(:push).with(to_url, '--mirror')
         
     | 
| 
      
 39 
     | 
    
         
            +
                  repo.mirror(to_url)
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                it 'raises an exception in case of failure' do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  expect { repo.mirror('') }
         
     | 
| 
      
 44 
     | 
    
         
            +
                  .to raise_error(GitDuplicator::RepositoryMirorringError)
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../../helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe GitDuplicator::ServiceRepository do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:name) { 'something' }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:owner) { 'someone' }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:repo) { described_class.new(name, owner) }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              describe '#delete' do
         
     | 
| 
      
 9 
     | 
    
         
            +
                it 'raises an exception in case of not defined' do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  expect { repo.delete }.to raise_error(NotImplementedError)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              describe '#create' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                it 'raises an exception in case of not defined' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  expect { repo.create }.to raise_error(NotImplementedError)
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              describe '#url' do
         
     | 
| 
      
 21 
     | 
    
         
            +
                it 'raises an exception in case of not defined' do
         
     | 
| 
      
 22 
     | 
    
         
            +
                  expect { repo.url }.to raise_error(NotImplementedError)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../../helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe GitDuplicator::Services::BitbucketRepository do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:credentials) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                { consumer_key: ENV['BITBUCKET_CONSUMER_KEY'],
         
     | 
| 
      
 6 
     | 
    
         
            +
                  consumer_secret: ENV['BITBUCKET_CONSUMER_SECRET'],
         
     | 
| 
      
 7 
     | 
    
         
            +
                  token: ENV['BITBUCKET_TOKEN'],
         
     | 
| 
      
 8 
     | 
    
         
            +
                  token_secret: ENV['BITBUCKET_TOKEN_SECRET'] }
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              let(:name) { ENV['TESTING_REPO'] }
         
     | 
| 
      
 11 
     | 
    
         
            +
              let(:owner) { ENV['BITBUCKET_USER'] }
         
     | 
| 
      
 12 
     | 
    
         
            +
              let(:options) do
         
     | 
| 
      
 13 
     | 
    
         
            +
                { scm: 'git', is_private: true, fork_policy: 'no_public_forks' }
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              let(:repo) { described_class.new(name, owner, credentials, options) }
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              describe '#delete' do
         
     | 
| 
      
 18 
     | 
    
         
            +
                it 'deletes the repo in case it exists' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  stub_request(:delete, described_class::BASE_URI +
         
     | 
| 
      
 20 
     | 
    
         
            +
                               "/repositories/#{owner}/#{name}")
         
     | 
| 
      
 21 
     | 
    
         
            +
                  .to_return(body: '', status: 204)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  expect { repo.delete }.not_to raise_error
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                it 'raises an exception in case of unknow problem' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  stub_request(:delete, described_class::BASE_URI +
         
     | 
| 
      
 26 
     | 
    
         
            +
                               "/repositories/#{owner}/#{name}")
         
     | 
| 
      
 27 
     | 
    
         
            +
                  .to_return(body: 'something wrong', status: 401)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  expect { repo.delete }
         
     | 
| 
      
 29 
     | 
    
         
            +
                  .to raise_error(GitDuplicator::RepositoryDeletionError, /something wrong/)
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              describe '#create' do
         
     | 
| 
      
 34 
     | 
    
         
            +
                it 'creates the repository in case of not defined' do
         
     | 
| 
      
 35 
     | 
    
         
            +
                  stub_request(:post, described_class::BASE_URI +
         
     | 
| 
      
 36 
     | 
    
         
            +
                               "/repositories/#{owner}/#{name}")
         
     | 
| 
      
 37 
     | 
    
         
            +
                  .with(body: options.to_json)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  .to_return(body: '', status: 200)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  expect { repo.create }.not_to raise_error
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                it 'raises an exception in case of errors' do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  stub_request(:post, described_class::BASE_URI +
         
     | 
| 
      
 44 
     | 
    
         
            +
                               "/repositories/#{owner}/#{name}")
         
     | 
| 
      
 45 
     | 
    
         
            +
                  .with(body: options.to_json)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  .to_return(body: 'something wrong', status: 401)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  expect { repo.create }
         
     | 
| 
      
 48 
     | 
    
         
            +
                  .to raise_error(GitDuplicator::RepositoryCreationError, /something wrong/)
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../../helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe GitDuplicator::Services::GithubRepository do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:credentials) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                { oauth2_token: ENV['GITHUB_ACCESS_TOKEN'] }
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              let(:name) { ENV['TESTING_REPO'] }
         
     | 
| 
      
 8 
     | 
    
         
            +
              let(:owner) { ENV['GITHUB_USER'] }
         
     | 
| 
      
 9 
     | 
    
         
            +
              let(:options) do
         
     | 
| 
      
 10 
     | 
    
         
            +
                { has_issues: false, has_wiki: false }
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              let(:repo) { described_class.new(name, owner, credentials, options) }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              describe '#delete' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                it 'deletes the repo in case it exists' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  stub_request(:delete, described_class::BASE_URI +
         
     | 
| 
      
 17 
     | 
    
         
            +
                               "/repos/#{owner}/#{name}")
         
     | 
| 
      
 18 
     | 
    
         
            +
                  .with(
         
     | 
| 
      
 19 
     | 
    
         
            +
                    headers: { 'Authorization' => "token #{credentials[:oauth2_token]}" }
         
     | 
| 
      
 20 
     | 
    
         
            +
                  )
         
     | 
| 
      
 21 
     | 
    
         
            +
                  .to_return(body: '', status: 204)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  expect { repo.delete }.not_to raise_error
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                it 'raises an exception in case of unknow problem' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  stub_request(:delete, described_class::BASE_URI +
         
     | 
| 
      
 26 
     | 
    
         
            +
                               "/repos/#{owner}/#{name}")
         
     | 
| 
      
 27 
     | 
    
         
            +
                  .to_return(body: 'something wrong', status: 401)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  expect { repo.delete }
         
     | 
| 
      
 29 
     | 
    
         
            +
                  .to raise_error(GitDuplicator::RepositoryDeletionError)
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              describe '#create' do
         
     | 
| 
      
 34 
     | 
    
         
            +
                it 'creates the repository in case of not defined' do
         
     | 
| 
      
 35 
     | 
    
         
            +
                  stub_request(:post, described_class::BASE_URI + '/user/repos')
         
     | 
| 
      
 36 
     | 
    
         
            +
                  .with(
         
     | 
| 
      
 37 
     | 
    
         
            +
                    body: options.merge(name: name).to_json,
         
     | 
| 
      
 38 
     | 
    
         
            +
                    headers: { 'Authorization' => "token #{credentials[:oauth2_token]}" }
         
     | 
| 
      
 39 
     | 
    
         
            +
                  )
         
     | 
| 
      
 40 
     | 
    
         
            +
                  .to_return(body: '', status: 201)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  expect { repo.create }.not_to raise_error
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                it 'raises an exception in case of errors' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  stub_request(:post, described_class::BASE_URI + '/user/repos')
         
     | 
| 
      
 46 
     | 
    
         
            +
                  .with(body: options.merge(name: name).to_json)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  .to_return(body: 'something wrong', status: 401)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  expect { repo.create }
         
     | 
| 
      
 49 
     | 
    
         
            +
                  .to raise_error(GitDuplicator::RepositoryCreationError)
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'webmock/rspec'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'simplecov'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'coveralls'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'dotenv'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Dotenv.load File.expand_path(
         
     | 
| 
      
 8 
     | 
    
         
            +
              File.join(File.dirname(__FILE__), '../', '.test.env')
         
     | 
| 
      
 9 
     | 
    
         
            +
            )
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
         
     | 
| 
      
 12 
     | 
    
         
            +
              SimpleCov::Formatter::HTMLFormatter,
         
     | 
| 
      
 13 
     | 
    
         
            +
              Coveralls::SimpleCov::Formatter
         
     | 
| 
      
 14 
     | 
    
         
            +
            ]
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            SimpleCov.start do
         
     | 
| 
      
 17 
     | 
    
         
            +
              add_filter '/spec/'
         
     | 
| 
      
 18 
     | 
    
         
            +
              minimum_coverage(95.0)
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            require_relative '../lib/git_duplicator.rb'
         
     | 
| 
      
 22 
     | 
    
         
            +
            # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
         
     | 
| 
      
 23 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 24 
     | 
    
         
            +
              config.run_all_when_everything_filtered = true
         
     | 
| 
      
 25 
     | 
    
         
            +
              # Run specs in random order to surface order dependencies. If you find an
         
     | 
| 
      
 26 
     | 
    
         
            +
              # order dependency and want to debug it, you can fix the order by providing
         
     | 
| 
      
 27 
     | 
    
         
            +
              # the seed, which is printed after each run.
         
     | 
| 
      
 28 
     | 
    
         
            +
              # --seed 1234
         
     | 
| 
      
 29 
     | 
    
         
            +
              config.order = 'random'
         
     | 
| 
      
 30 
     | 
    
         
            +
              config.expect_with :rspec do |c|
         
     | 
| 
      
 31 
     | 
    
         
            +
                c.syntax = :expect
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,118 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: git_duplicator
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Khaled alHabache
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2014-08-29 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: http
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '0.6'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '0.6'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: git
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '1.2'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '1.2'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: simple_oauth
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '0.2'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '0.2'
         
     | 
| 
      
 55 
     | 
    
         
            +
            description: Duplicating git repositories without forking.
         
     | 
| 
      
 56 
     | 
    
         
            +
            email:
         
     | 
| 
      
 57 
     | 
    
         
            +
            - khellls@gmail.com
         
     | 
| 
      
 58 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 59 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 60 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 61 
     | 
    
         
            +
            files:
         
     | 
| 
      
 62 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 63 
     | 
    
         
            +
            - ".rspec"
         
     | 
| 
      
 64 
     | 
    
         
            +
            - ".test.env.example"
         
     | 
| 
      
 65 
     | 
    
         
            +
            - ".travis.yml"
         
     | 
| 
      
 66 
     | 
    
         
            +
            - ".yardopts"
         
     | 
| 
      
 67 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 68 
     | 
    
         
            +
            - Guardfile
         
     | 
| 
      
 69 
     | 
    
         
            +
            - LICENSE.md
         
     | 
| 
      
 70 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 71 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 72 
     | 
    
         
            +
            - git_duplicator.gemspec
         
     | 
| 
      
 73 
     | 
    
         
            +
            - lib/git_duplicator.rb
         
     | 
| 
      
 74 
     | 
    
         
            +
            - lib/git_duplicator/duplicator.rb
         
     | 
| 
      
 75 
     | 
    
         
            +
            - lib/git_duplicator/errors.rb
         
     | 
| 
      
 76 
     | 
    
         
            +
            - lib/git_duplicator/helpers/authorization_header.rb
         
     | 
| 
      
 77 
     | 
    
         
            +
            - lib/git_duplicator/null_logger.rb
         
     | 
| 
      
 78 
     | 
    
         
            +
            - lib/git_duplicator/repositories.rb
         
     | 
| 
      
 79 
     | 
    
         
            +
            - lib/git_duplicator/repository/repository.rb
         
     | 
| 
      
 80 
     | 
    
         
            +
            - lib/git_duplicator/repository/service_repository.rb
         
     | 
| 
      
 81 
     | 
    
         
            +
            - lib/git_duplicator/services.rb
         
     | 
| 
      
 82 
     | 
    
         
            +
            - lib/git_duplicator/services/bitbucket.rb
         
     | 
| 
      
 83 
     | 
    
         
            +
            - lib/git_duplicator/services/github.rb
         
     | 
| 
      
 84 
     | 
    
         
            +
            - lib/git_duplicator/version.rb
         
     | 
| 
      
 85 
     | 
    
         
            +
            - spec/git_duplicator/duplicator_spec.rb
         
     | 
| 
      
 86 
     | 
    
         
            +
            - spec/git_duplicator/git_duplicator_spec.rb
         
     | 
| 
      
 87 
     | 
    
         
            +
            - spec/git_duplicator/repository/repository_spec.rb
         
     | 
| 
      
 88 
     | 
    
         
            +
            - spec/git_duplicator/repository/service_repository_spec.rb
         
     | 
| 
      
 89 
     | 
    
         
            +
            - spec/git_duplicator/services/bitbucket_spec.rb
         
     | 
| 
      
 90 
     | 
    
         
            +
            - spec/git_duplicator/services/github_spec.rb
         
     | 
| 
      
 91 
     | 
    
         
            +
            - spec/git_duplicator/version_spec.rb
         
     | 
| 
      
 92 
     | 
    
         
            +
            - spec/helper.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            homepage: https://github.com/Startappz/git_duplicator
         
     | 
| 
      
 94 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 95 
     | 
    
         
            +
            - LGPL-3
         
     | 
| 
      
 96 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 97 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 98 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 99 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 100 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 101 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 102 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 103 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 104 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 105 
     | 
    
         
            +
                  version: 1.9.3
         
     | 
| 
      
 106 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 107 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 108 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 109 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 110 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 111 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 112 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 113 
     | 
    
         
            +
            rubygems_version: 2.4.1
         
     | 
| 
      
 114 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 115 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 116 
     | 
    
         
            +
            summary: Duplicating git repositories without forking.
         
     | 
| 
      
 117 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 118 
     | 
    
         
            +
            has_rdoc: 
         
     |