gitlab-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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6222d511159cc2efb2af20f5320e858450b762a9
4
+ data.tar.gz: f72a95329b0156318369228b697f593ff60bf63e
5
+ SHA512:
6
+ metadata.gz: abbc9eb12af61b6ba0ffa05c64ad1f6049ab26ae3001eff442f68b5d723f0ab63979ea8ce3c8528670ac53d8424030949645ce8ada9031ad6606d0b6a74741ba
7
+ data.tar.gz: 7eb60590b881fd322ddcd32dce4001c3268f547f4c6dc4e63e76587c385ca0b057b79fdf5ed7fa8e362d330b5ff5857d637de9d8df2ec3fbc4d0758a4af3d737
@@ -0,0 +1,7 @@
1
+ *.gem
2
+
3
+ .yardoc/
4
+ doc/
5
+ pkg/
6
+
7
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012 - 2015, Seth Jackson, Uwe Kleinmann
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # GitLab Backup
2
+
3
+ A command line tool for backing up GitLab repositories.
4
+
5
+
6
+ ## Prerequisites
7
+
8
+ * [Git](http://git-scm.com/)
9
+ * [Ruby](https://www.ruby-lang.org/) (>= 2.1.0)
10
+
11
+ To backup your repositories you **must** have the git on your `PATH`.
12
+
13
+
14
+ ## Installation
15
+
16
+ $ gem install gitlab-backup
17
+
18
+
19
+ ## Usage
20
+
21
+ $ gitlab-backup [options] ~/backup
22
+
23
+ See the help prompt for more info:
24
+
25
+ $ gitlab-backup --help
26
+
27
+
28
+ ## Config files
29
+
30
+ You can provide a config file in the YAML format
31
+ to `gitlab-backup` via the `--config` or `-c` option.
32
+ Settings specified on the command line have precedence
33
+ over settings in the config file.
34
+
35
+ The `host` and `token` settings will be
36
+ read from the config file.
37
+
38
+ For example to backup every repository the user with the token `example` has access to
39
+ put the following in a config file and pass it to `gitlab-backup`:
40
+
41
+ host: https://gitlab.com
42
+ token: example
43
+
44
+
45
+ ## License
46
+
47
+ [ISC](LICENSE)
48
+
49
+ ## Thanks
50
+
51
+ This project is based on the [previous work](https://bitbucket.org/seth/bitbucket-backup) of Seth Jackson for bitbucket-backup.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "gitlab-backup"
4
+ require "io/console"
5
+ require "optparse"
6
+ require "yaml"
7
+
8
+ options = {}
9
+
10
+ parser = OptionParser.new do |opts|
11
+ cmd = File.basename($0)
12
+
13
+ opts.banner = "usage: #{cmd} [options] path"
14
+
15
+ opts.on("-c", "--config FILE", "Path to config file.") do |config_file|
16
+ options["config_file"] = config_file
17
+ end
18
+
19
+ opts.on("-h", "--host HOST", "GitLab host to be backed up, e.g. http://gitlab.com") do |host|
20
+ options["host"] = host
21
+ end
22
+
23
+ opts.on("-t", "--token TOKEN", "Private token for account to be backed up.") do |token|
24
+ options["token"] = token
25
+ end
26
+
27
+ opts.on("--help", "Show this help message and exit.") do
28
+ puts opts
29
+ exit
30
+ end
31
+
32
+ opts.on("-v", "--version", "Display the program's version and exit.") do
33
+ puts "#{cmd} (version #{Gitlab::Backup::VERSION})"
34
+ exit
35
+ end
36
+ end
37
+
38
+ parser.parse!
39
+
40
+ config = {}
41
+
42
+ if options["config_file"]
43
+ begin
44
+ path = File.expand_path(options["config_file"])
45
+
46
+ config = YAML.load_file(path)
47
+
48
+ unless config
49
+ puts "Error: invalid config file: #{path}."
50
+ exit
51
+ end
52
+ rescue YAML::SyntaxError, StandardError
53
+ puts "Error: invalid config file: #{path}."
54
+ exit
55
+ end
56
+ end
57
+
58
+ config.merge!(options)
59
+
60
+ if ARGV.empty? || !config["token"] || !config["host"]
61
+ puts parser.banner
62
+ exit
63
+ end
64
+
65
+ Gitlab::Backup.backup(config["host"], config["token"], ARGV.first)
@@ -0,0 +1,26 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "gitlab-backup/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "gitlab-backup"
7
+ spec.version = Gitlab::Backup::VERSION
8
+ spec.authors = ["Uwe Kleinmann"]
9
+ spec.email = "uwe@kleinmann.org"
10
+ spec.homepage = "https://github.com/kleinmann/gitlab-backup"
11
+ spec.summary = "A tool to backup repositories from any GitLab installation."
12
+ spec.description = "A tool to backup GitLab repositories to your local machine."
13
+ spec.license = "ISC"
14
+
15
+ spec.executables = "gitlab-backup"
16
+
17
+ spec.files = `git ls-files`.split
18
+
19
+ spec.required_ruby_version = ">= 2.1.0"
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rdoc", "~> 4.0"
24
+ spec.add_development_dependency "yard", "~> 0.8"
25
+ spec.add_development_dependency "redcarpet", "~> 3.2"
26
+ end
@@ -0,0 +1,3 @@
1
+ require "gitlab-backup/backup"
2
+ require "gitlab-backup/repository"
3
+ require "gitlab-backup/version"
@@ -0,0 +1,85 @@
1
+ require "net/https"
2
+ require "json"
3
+ require "pp"
4
+
5
+ module Gitlab
6
+ module Backup
7
+ # Begins the backup process.
8
+ #
9
+ # @param [String] host
10
+ # the host (and maybe port) of the GitLab instance to backup from.
11
+ #
12
+ # @param [String] token
13
+ # the private token of the user to backup repositories for.
14
+ #
15
+ # @param [String] backup_root
16
+ # the absolute or relative path of the directory to backup the repositories to.
17
+ def self.backup(host, token, backup_root)
18
+ backup_root = File.expand_path(backup_root)
19
+
20
+ puts
21
+ puts "Backing up repositories to #{backup_root}"
22
+ puts
23
+
24
+ repos = get_repo_list(host, token)
25
+
26
+ repos.each do |repo|
27
+ Gitlab::Backup::Repository.new(repo, token, backup_root).backup
28
+ end
29
+ end
30
+
31
+ # Checks if the specified SCM tool exists on the PATH
32
+ # and is executable.
33
+ #
34
+ # @return [Boolean]
35
+ # true if the SCM tool exists and is executable, false otherwise.
36
+ def self.have_git?
37
+ # From: http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
38
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
39
+
40
+ ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
41
+ exts.each do |ext|
42
+ bin = "#{path}/git#{ext}"
43
+
44
+ return bin if File.executable?(bin)
45
+ end
46
+ end
47
+
48
+ return nil
49
+ end
50
+
51
+ private
52
+ # Gets a list of the repositories the user has access to.
53
+ #
54
+ # @param [String] host
55
+ # the host (and maybe port) of the GitLab instance to backup from.
56
+ #
57
+ # @param [String] token
58
+ # the private token of the user to get repositories for.
59
+ #
60
+ # @return [Array<String>]
61
+ # the repositories the user has access to.
62
+ #
63
+ def self.get_repo_list(host, token)
64
+ uri = URI.parse("#{host}/api/v3/projects")
65
+
66
+ http = Net::HTTP.new(uri.host, uri.port)
67
+
68
+ if host =~ /\Ahttps/
69
+ http.use_ssl = true
70
+ end
71
+
72
+ request = Net::HTTP::Get.new(uri.request_uri)
73
+ request.add_field("PRIVATE-TOKEN", token)
74
+
75
+ response = http.request(request)
76
+
77
+ if response.code == "401"
78
+ puts "Invalid token."
79
+ exit
80
+ end
81
+
82
+ JSON.parse(response.body)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,104 @@
1
+ require "fileutils"
2
+ require "cgi"
3
+
4
+ module Gitlab
5
+ module Backup
6
+ # The repository to back up.
7
+ #
8
+ class Repository
9
+ # @return [Hash]
10
+ # the hash of repository data from the Gitlab API.
11
+ #
12
+ attr_reader :repo
13
+
14
+ # @return [String]
15
+ # the private token for the user with which to backup the repository with.
16
+ #
17
+ attr_reader :token
18
+
19
+ # @return [String]
20
+ # the absolute path of the directory to backup the repository to.
21
+ #
22
+ attr_reader :backup_root
23
+
24
+ # Creates a new repository.
25
+ #
26
+ # @param [Hash] repo
27
+ # the hash of repository data from the Gitlab API.
28
+ #
29
+ # @param [String] token
30
+ # the private token for the user with which to backup the repository with.
31
+ #
32
+ # @param [String] backup_root
33
+ # the absolute path of the directory to backup the repository to.
34
+ #
35
+ def initialize(repo, token, backup_root)
36
+ @repo = repo
37
+ @token = token
38
+ @backup_root = backup_root
39
+ end
40
+
41
+ # Performs a backup of the repository.
42
+ #
43
+ def backup
44
+ puts "Backing up: #{repo["name_with_namespace"]}."
45
+
46
+ unless Gitlab::Backup.have_git?
47
+ puts "Warning: git not found on PATH. Skipping..."
48
+
49
+ return
50
+ end
51
+
52
+ clone_or_update
53
+ end
54
+
55
+ private
56
+ # Performs a full backup of the repository's source code
57
+ # or wiki if the directory to which the backup would occur does not
58
+ # exist. Performs an incremental update (pull) otherwise.
59
+ #
60
+ def clone_or_update
61
+ path = dir_for_repo
62
+ uri = repo["ssh_url_to_repo"]
63
+
64
+ if File.exist?(path)
65
+ run_incremental_backup(path, uri)
66
+ else
67
+ run_full_backup(uri, path)
68
+ end
69
+ end
70
+
71
+ # Checks whether the specified path is a repository or not.
72
+ #
73
+ # @param [String] path
74
+ # the path to check.
75
+ #
76
+ # @return [Boolean]
77
+ # true if the path is the same type of repository
78
+ # that we got from the Gitlab API, false otherwise.
79
+ def repo?(path)
80
+ FileUtils.cd(path)
81
+
82
+ system "git status -s"
83
+
84
+ return $? == 0
85
+ end
86
+
87
+ def run_incremental_backup(path, uri)
88
+ return unless repo?(path)
89
+
90
+ FileUtils.cd(path)
91
+
92
+ system("git", "pull", uri)
93
+ end
94
+
95
+ def run_full_backup(uri, dest)
96
+ system("git", "clone", "--recursive", uri, dest)
97
+ end
98
+
99
+ def dir_for_repo
100
+ File.expand_path("#{backup_root}/#{repo["path_with_namespace"]}/src")
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,7 @@
1
+ module Gitlab
2
+ module Backup
3
+ # The gem's version.
4
+ #
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitlab-backup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Uwe Kleinmann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-18 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.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
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: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redcarpet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.2'
83
+ description: A tool to backup GitLab repositories to your local machine.
84
+ email: uwe@kleinmann.org
85
+ executables:
86
+ - gitlab-backup
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - bin/gitlab-backup
96
+ - gitlab-backup.gemspec
97
+ - lib/gitlab-backup.rb
98
+ - lib/gitlab-backup/backup.rb
99
+ - lib/gitlab-backup/repository.rb
100
+ - lib/gitlab-backup/version.rb
101
+ homepage: https://github.com/kleinmann/gitlab-backup
102
+ licenses:
103
+ - ISC
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: 2.1.0
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.4.5.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: A tool to backup repositories from any GitLab installation.
125
+ test_files: []
126
+ has_rdoc: