github_backup 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +55 -0
- data/README.md +23 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/github-backup +60 -0
- data/github_backup.gemspec +31 -0
- data/lib/github_backup.rb +8 -0
- data/lib/github_backup/api.rb +40 -0
- data/lib/github_backup/config.rb +88 -0
- data/lib/github_backup/git.rb +59 -0
- data/lib/github_backup/helpers.rb +17 -0
- data/lib/github_backup/json_store.rb +50 -0
- data/lib/github_backup/version.rb +4 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9acdffdd4f2ecf5f4f0aba30a1f71dcf84c7304e6d6c28d4a1968975c97655f8
|
4
|
+
data.tar.gz: db0e9a35201bc78717193ad5983a2ad91b72cc55a360c40fffd75ad679dd4a21
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1f49b1f08d8a9e43d58426bbe5ff5e0966f49c4be61cbaec58295cdc10b317a44d9663134a54b59783aceefafbf8b2f02522b6f1293a0a46f44c8b21209cff14
|
7
|
+
data.tar.gz: fedbb55ac7c2f06944c570087777a9d3b646038b954d1036febb45f568075459663b610adc65ee630fd2633a588edc4482a4c9f1503e3d64a898648a815f7d79
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github_backup
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.6.2
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
github_backup (0.1.0)
|
5
|
+
http
|
6
|
+
link_header
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
addressable (2.6.0)
|
12
|
+
public_suffix (>= 2.0.2, < 4.0)
|
13
|
+
diff-lcs (1.3)
|
14
|
+
domain_name (0.5.20180417)
|
15
|
+
unf (>= 0.0.5, < 1.0.0)
|
16
|
+
http (4.1.1)
|
17
|
+
addressable (~> 2.3)
|
18
|
+
http-cookie (~> 1.0)
|
19
|
+
http-form_data (~> 2.0)
|
20
|
+
http_parser.rb (~> 0.6.0)
|
21
|
+
http-cookie (1.0.3)
|
22
|
+
domain_name (~> 0.5)
|
23
|
+
http-form_data (2.1.1)
|
24
|
+
http_parser.rb (0.6.0)
|
25
|
+
link_header (0.0.8)
|
26
|
+
public_suffix (3.0.3)
|
27
|
+
rake (10.5.0)
|
28
|
+
rspec (3.8.0)
|
29
|
+
rspec-core (~> 3.8.0)
|
30
|
+
rspec-expectations (~> 3.8.0)
|
31
|
+
rspec-mocks (~> 3.8.0)
|
32
|
+
rspec-core (3.8.0)
|
33
|
+
rspec-support (~> 3.8.0)
|
34
|
+
rspec-expectations (3.8.2)
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
+
rspec-support (~> 3.8.0)
|
37
|
+
rspec-mocks (3.8.0)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.8.0)
|
40
|
+
rspec-support (3.8.0)
|
41
|
+
unf (0.1.4)
|
42
|
+
unf_ext
|
43
|
+
unf_ext (0.0.7.5)
|
44
|
+
|
45
|
+
PLATFORMS
|
46
|
+
ruby
|
47
|
+
|
48
|
+
DEPENDENCIES
|
49
|
+
bundler (~> 1.17)
|
50
|
+
github_backup!
|
51
|
+
rake (~> 10.0)
|
52
|
+
rspec (~> 3.0)
|
53
|
+
|
54
|
+
BUNDLED WITH
|
55
|
+
1.17.2
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# GithubBackup
|
2
|
+
|
3
|
+
Backup all of your github repos by using the Github API to clone and update them.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install github_backup
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
Edit: `~/.config/github-backup.json`
|
12
|
+
|
13
|
+
Example config
|
14
|
+
|
15
|
+
```json
|
16
|
+
{
|
17
|
+
"repos_path": "~/Repos",
|
18
|
+
"backup_path": "~/Documents/RepoBundles",
|
19
|
+
"token": "...github_token..."
|
20
|
+
}
|
21
|
+
```
|
22
|
+
|
23
|
+
$ github-backup
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "github_backup"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/github-backup
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.join(__dir__, '..', 'lib')
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'shellwords'
|
7
|
+
require 'thread'
|
8
|
+
require 'github_backup'
|
9
|
+
require 'github_backup/git'
|
10
|
+
include GithubBackup::Helpers
|
11
|
+
|
12
|
+
config = GithubBackup::Config.new(File.join(__dir__, '..', 'default_config.json'))
|
13
|
+
|
14
|
+
config['repos_path'] ||= File.join(Dir.home, 'Repos')
|
15
|
+
config['backup_path'] ||= File.join(Dir.home, 'Documents', 'RepoBundles')
|
16
|
+
|
17
|
+
config.save
|
18
|
+
github = GithubBackup::Api.new(config['token'])
|
19
|
+
|
20
|
+
puts "Fetching repos..."
|
21
|
+
page_no = 0
|
22
|
+
puts "page #{page_no += 1}"
|
23
|
+
repos = github.get('/user/repos')
|
24
|
+
while page = github.next
|
25
|
+
puts "page #{page_no += 1}"
|
26
|
+
repos.concat page
|
27
|
+
end
|
28
|
+
puts "Done!"
|
29
|
+
|
30
|
+
clone_urls = repos.map { |repo| repo['ssh_url'] }
|
31
|
+
|
32
|
+
@threads = []
|
33
|
+
|
34
|
+
clone_urls.each do |url|
|
35
|
+
user = /github\.com.([^\/]+)/.match(url)[1]
|
36
|
+
project_name = File.basename(url.split('/').last, '.git')
|
37
|
+
path = File.expand_path(File.join(config['repos_path'], user, project_name))
|
38
|
+
FileUtils.mkdir_p(File.dirname(path))
|
39
|
+
|
40
|
+
@threads << Thread.new do |thread|
|
41
|
+
unless File.exist?(path)
|
42
|
+
cmd = "git clone #{url} #{Shellwords.shellescape(path)}"
|
43
|
+
puts cmd
|
44
|
+
puts `#{cmd}`
|
45
|
+
else
|
46
|
+
puts "Updating existing repo: #{path}"
|
47
|
+
git_updater = GithubBackup::Git.new
|
48
|
+
Dir.chdir(path)
|
49
|
+
git_updater.update
|
50
|
+
backup_path = File.expand_path(File.join(config['backup_path'], user))
|
51
|
+
FileUtils.mkdir_p(backup_path)
|
52
|
+
bundle = "#{project_name}.gitbundle"
|
53
|
+
bundle_path = File.join(backup_path, bundle)
|
54
|
+
puts `git bundle create #{Shellwords.shellescape(bundle_path)} --all --remotes`
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
@threads.each(&:join)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "github_backup/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "github_backup"
|
8
|
+
spec.version = GithubBackup::VERSION
|
9
|
+
spec.authors = ["Alex Clink"]
|
10
|
+
spec.email = ["code@alexclink.com"]
|
11
|
+
|
12
|
+
spec.summary = "Create backups of your github repos"
|
13
|
+
spec.description = "Automatically clones your github repos and makes git bundles"
|
14
|
+
spec.homepage = "http://alexclink.com/gems/github-backup"
|
15
|
+
|
16
|
+
# Specify which files should be added to the gem when it is released.
|
17
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
19
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
|
29
|
+
spec.add_dependency "link_header"
|
30
|
+
spec.add_dependency "http"
|
31
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'link_header'
|
2
|
+
require 'json'
|
3
|
+
require 'uri'
|
4
|
+
require 'http'
|
5
|
+
|
6
|
+
module GithubBackup
|
7
|
+
class Api
|
8
|
+
URL = 'https://api.github.com'
|
9
|
+
|
10
|
+
def initialize(token, version = 'v3')
|
11
|
+
@token = token
|
12
|
+
@version = version
|
13
|
+
end
|
14
|
+
|
15
|
+
def accept
|
16
|
+
"application/vnd.github.#{@version}+json"
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(url)
|
20
|
+
@response = HTTP[
|
21
|
+
'User-Agent' => 'sleepinginsomniac - cloner',
|
22
|
+
'Authorization' => "token #{@token}",
|
23
|
+
'Accept' => accept
|
24
|
+
].get(URI.join(URL, url))
|
25
|
+
JSON.parse(@response)
|
26
|
+
end
|
27
|
+
|
28
|
+
def next
|
29
|
+
links = LinkHeader.parse(@response.headers['Link']).links
|
30
|
+
next_link = links.find do |link|
|
31
|
+
Hash[link.attr_pairs]['rel'] == 'next'
|
32
|
+
end
|
33
|
+
if next_link
|
34
|
+
get(next_link.href)
|
35
|
+
else
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'github_backup/json_store'
|
4
|
+
|
5
|
+
module GithubBackup
|
6
|
+
class Config
|
7
|
+
attr_accessor :override
|
8
|
+
|
9
|
+
def initialize(default_path)
|
10
|
+
@override = {}
|
11
|
+
@default_path = default_path
|
12
|
+
puts "Config: #{path}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def defaults
|
16
|
+
if @default_path
|
17
|
+
@defaults ||= JSONStore.new(@default_path)
|
18
|
+
else
|
19
|
+
{}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def values
|
24
|
+
@values ||= JSONStore.new(path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def data
|
28
|
+
@data ||= JSONStore.new(data_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Check if the config exists
|
32
|
+
def exists?
|
33
|
+
values.exists?
|
34
|
+
end
|
35
|
+
|
36
|
+
# The user's home directory
|
37
|
+
def home
|
38
|
+
ENV['HOME'] || File.expand_path('~')
|
39
|
+
end
|
40
|
+
|
41
|
+
# The user's preferred config dir
|
42
|
+
def dir
|
43
|
+
ENV['XDG_CONFIG_HOME'] || File.join(home, '.config')
|
44
|
+
end
|
45
|
+
|
46
|
+
def data_dir
|
47
|
+
ENV['XDG_DATA_HOME'] || File.join(home, '.local', 'share')
|
48
|
+
end
|
49
|
+
|
50
|
+
def data_path
|
51
|
+
File.join(data_dir, "#{APP}.json")
|
52
|
+
end
|
53
|
+
|
54
|
+
# the path to the config file
|
55
|
+
def path
|
56
|
+
File.join(dir, "#{APP}.json")
|
57
|
+
end
|
58
|
+
|
59
|
+
# Read a value from the config ex:
|
60
|
+
# config[key] # => value
|
61
|
+
def [](key)
|
62
|
+
@override[key] || values[key] || defaults[key]
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set a value in the config ex:
|
66
|
+
# config[key] = value
|
67
|
+
def []=(key, value)
|
68
|
+
values[key] = value
|
69
|
+
values.save
|
70
|
+
end
|
71
|
+
|
72
|
+
# Write config to disk at the user's config dir.
|
73
|
+
# Doesn't save overrides
|
74
|
+
def save
|
75
|
+
values.save
|
76
|
+
end
|
77
|
+
|
78
|
+
# Removes the saved config
|
79
|
+
def delete!
|
80
|
+
values.delete!
|
81
|
+
end
|
82
|
+
|
83
|
+
# writes the config json to stdout
|
84
|
+
def to_s
|
85
|
+
values.to_s
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module GithubBackup
|
2
|
+
class Git
|
3
|
+
def remotes(_remotes = nil)
|
4
|
+
unless _remotes
|
5
|
+
_remotes = `git remote`.split(/\s+/)
|
6
|
+
end
|
7
|
+
_remotes
|
8
|
+
end
|
9
|
+
|
10
|
+
def current_branch
|
11
|
+
`git rev-parse --abbrev-ref HEAD`.chomp
|
12
|
+
end
|
13
|
+
|
14
|
+
def tracked_branches(remote)
|
15
|
+
info = `git remote show #{remote}`
|
16
|
+
.lines
|
17
|
+
.select { |l| l =~ /merges with remote/i }
|
18
|
+
.map{ |l| l.strip.split(/\s+merges with remote\s+/i) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def commits_behind(remote, lbranch, rbranch)
|
22
|
+
`git rev-list --count refs/heads/#{lbranch}..refs/remotes/#{remote}/#{rbranch}`.chomp.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def commits_ahead(remote, lbranch, rbranch)
|
26
|
+
`git rev-list --count refs/remotes/#{remote}/#{rbranch}..refs/heads/#{lbranch}`.chomp.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
# ===========
|
30
|
+
# = updater =
|
31
|
+
# ===========
|
32
|
+
def update
|
33
|
+
remotes.each do |remote|
|
34
|
+
puts `git remote update #{remote}`
|
35
|
+
tracked_branches(remote).each do |branches|
|
36
|
+
lbranch, rbranch = branches
|
37
|
+
behind = commits_behind(remote, lbranch, rbranch)
|
38
|
+
ahead = commits_ahead(remote, lbranch, rbranch)
|
39
|
+
if behind > 0
|
40
|
+
if ahead > 0
|
41
|
+
puts "branch #{lbranch} is #{behind} commit(s) behind and " \
|
42
|
+
"#{ahead} commit(s) ahead of #{remote}/#{rbranch}. " \
|
43
|
+
"could not be fast-forwarded"
|
44
|
+
elsif lbranch == current_branch
|
45
|
+
puts "branch #{lbranch} was #{behind} commit(s) behind of " \
|
46
|
+
"#{remote}/#{rbranch}. fast-forward merge"
|
47
|
+
puts "git merge -q refs/remotes/#{remote}/#{rbranch}"
|
48
|
+
else
|
49
|
+
puts "branch #{lbranch} was #{behind} commit(s) behind of " \
|
50
|
+
"#{remote}/#{rbranch}. resetting local branch to remote"
|
51
|
+
puts "git branch -f #{lbranch} -t refs/remotes/#{remote}/#{rbranch} >/dev/null"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module GithubBackup
|
5
|
+
class JSONStore
|
6
|
+
def initialize(path)
|
7
|
+
@path = path
|
8
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
9
|
+
end
|
10
|
+
|
11
|
+
def data
|
12
|
+
@data || load!
|
13
|
+
end
|
14
|
+
|
15
|
+
def load!
|
16
|
+
@data = exists? ? JSON.parse(File.read(@path)) : {}
|
17
|
+
@data['_read_at'] = Time.now
|
18
|
+
@data
|
19
|
+
end
|
20
|
+
|
21
|
+
def exists?
|
22
|
+
File.exist?(@path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](key)
|
26
|
+
data[key]
|
27
|
+
end
|
28
|
+
|
29
|
+
def []=(key, value)
|
30
|
+
data[key] = value
|
31
|
+
end
|
32
|
+
|
33
|
+
def save
|
34
|
+
return false unless @data
|
35
|
+
@data['_saved_at'] = Time.now
|
36
|
+
File.open(@path, 'w') do |file|
|
37
|
+
file.write(to_s)
|
38
|
+
end
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete!
|
43
|
+
File.unlink(@path) if File.exist?(@path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
JSON.pretty_generate(data)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: github_backup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Clink
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: link_header
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: http
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Automatically clones your github repos and makes git bundles
|
84
|
+
email:
|
85
|
+
- code@alexclink.com
|
86
|
+
executables:
|
87
|
+
- github-backup
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".ruby-gemset"
|
94
|
+
- ".ruby-version"
|
95
|
+
- Gemfile
|
96
|
+
- Gemfile.lock
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- bin/console
|
100
|
+
- bin/setup
|
101
|
+
- exe/github-backup
|
102
|
+
- github_backup.gemspec
|
103
|
+
- lib/github_backup.rb
|
104
|
+
- lib/github_backup/api.rb
|
105
|
+
- lib/github_backup/config.rb
|
106
|
+
- lib/github_backup/git.rb
|
107
|
+
- lib/github_backup/helpers.rb
|
108
|
+
- lib/github_backup/json_store.rb
|
109
|
+
- lib/github_backup/version.rb
|
110
|
+
homepage: http://alexclink.com/gems/github-backup
|
111
|
+
licenses: []
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubygems_version: 3.0.3
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Create backups of your github repos
|
132
|
+
test_files: []
|