git-multirepo 1.0.0.beta21 → 1.0.0.beta24
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 +4 -4
- data/.gitignore +38 -38
- data/.rspec +2 -2
- data/Gemfile +4 -4
- data/Gemfile.lock +37 -37
- data/LICENSE +22 -22
- data/README.md +141 -139
- data/Rakefile +2 -2
- data/bin/multi +10 -10
- data/docs/git-multirepo-cheatsheet.docx +0 -0
- data/git-multirepo.gemspec +29 -29
- data/lib/commands.rb +11 -11
- data/lib/git-multirepo.rb +2 -2
- data/lib/info.rb +4 -4
- data/lib/multirepo/commands/add-command.rb +51 -51
- data/lib/multirepo/commands/branch-command.rb +52 -52
- data/lib/multirepo/commands/checkout-command.rb +119 -119
- data/lib/multirepo/commands/clone-command.rb +69 -69
- data/lib/multirepo/commands/command.rb +58 -50
- data/lib/multirepo/commands/fetch-command.rb +23 -23
- data/lib/multirepo/commands/init-command.rb +51 -51
- data/lib/multirepo/commands/install-command.rb +87 -87
- data/lib/multirepo/commands/open-command.rb +25 -25
- data/lib/multirepo/commands/remove-command.rb +48 -48
- data/lib/multirepo/commands/uninit-command.rb +20 -20
- data/lib/multirepo/commands/update-command.rb +47 -47
- data/lib/multirepo/config.rb +15 -12
- data/lib/multirepo/files/config-entry.rb +34 -34
- data/lib/multirepo/files/config-file.rb +37 -37
- data/lib/multirepo/files/lock-entry.rb +25 -25
- data/lib/multirepo/files/lock-file.rb +39 -39
- data/lib/multirepo/git/branch.rb +27 -27
- data/lib/multirepo/git/change.rb +10 -10
- data/lib/multirepo/git/git.rb +42 -38
- data/lib/multirepo/git/remote.rb +15 -15
- data/lib/multirepo/git/repo.rb +66 -66
- data/lib/multirepo/hooks/post-merge-hook.rb +19 -19
- data/lib/multirepo/hooks/pre-commit-hook.rb +25 -25
- data/lib/multirepo/hooks/prepare-commit-msg-hook.rb +27 -27
- data/lib/multirepo/multirepo-exception.rb +5 -5
- data/lib/multirepo/utility/console.rb +51 -51
- data/lib/multirepo/utility/runner.rb +32 -32
- data/lib/multirepo/utility/utils.rb +51 -51
- data/resources/post-merge +5 -5
- data/resources/pre-commit +5 -5
- data/resources/prepare-commit-msg +5 -5
- data/spec/integration/init_spec.rb +22 -22
- data/spec/spec_helper.rb +89 -89
- metadata +4 -3
@@ -1,70 +1,70 @@
|
|
1
|
-
require "multirepo/utility/console"
|
2
|
-
require "multirepo/utility/utils"
|
3
|
-
require "multirepo/git/repo"
|
4
|
-
require_relative "install-command"
|
5
|
-
|
6
|
-
module MultiRepo
|
7
|
-
class CloneCommand < Command
|
8
|
-
self.command = "clone"
|
9
|
-
self.summary = "Clones the specified repository in a subfolder, then installs it."
|
10
|
-
|
11
|
-
def self.options
|
12
|
-
[
|
13
|
-
['
|
14
|
-
['
|
15
|
-
['[ref]', 'The branch, tag or commit id to checkout. Checkout will use "master" if unspecified.']
|
16
|
-
].concat(super)
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(argv)
|
20
|
-
@url = argv.shift_argument
|
21
|
-
@name = argv.shift_argument
|
22
|
-
@ref = argv.shift_argument || "master"
|
23
|
-
super
|
24
|
-
end
|
25
|
-
|
26
|
-
def validate!
|
27
|
-
super
|
28
|
-
help! "You must specify a repository to clone" unless @url
|
29
|
-
help! "You must specify a containing folder name" unless @name
|
30
|
-
end
|
31
|
-
|
32
|
-
def run
|
33
|
-
Console.log_step("Cloning #{@url} ...")
|
34
|
-
|
35
|
-
raise MultiRepoException, "A directory named #{@name} already exists" if Dir.exists?(@name)
|
36
|
-
|
37
|
-
main_repo_path = "#{@name}/#{@name}"
|
38
|
-
main_repo = Repo.new(main_repo_path)
|
39
|
-
|
40
|
-
# Recursively create the directory where we'll clone the main repo
|
41
|
-
FileUtils.mkpath(main_repo_path)
|
42
|
-
|
43
|
-
# Clone the specified remote in the just-created directory
|
44
|
-
raise MultiRepoException, "Could not clone repo from #{@url}" unless main_repo.clone(@url)
|
45
|
-
|
46
|
-
# Checkout the specified main repo ref so that install reads the proper config file
|
47
|
-
unless main_repo.checkout(@ref)
|
48
|
-
raise MultiRepoException, "Couldn't perform checkout of main repo #{@ref}!"
|
49
|
-
end
|
50
|
-
|
51
|
-
Console.log_substep("Checked out main repo #{@ref}")
|
52
|
-
|
53
|
-
# Make sure the ref we just checked out is multirepo-enabled
|
54
|
-
unless Utils.is_multirepo_enabled(main_repo_path)
|
55
|
-
raise MultiRepoException, "Ref #{@ref} is not multirepo-enabled"
|
56
|
-
end
|
57
|
-
|
58
|
-
# Install
|
59
|
-
original_path = Dir.pwd
|
60
|
-
Dir.chdir(main_repo_path)
|
61
|
-
install_command = InstallCommand.new(CLAide::ARGV.new([]))
|
62
|
-
install_command.install_dependencies_step
|
63
|
-
Dir.chdir(original_path)
|
64
|
-
|
65
|
-
Console.log_step("Done!")
|
66
|
-
rescue MultiRepoException => e
|
67
|
-
Console.log_error(e.message)
|
68
|
-
end
|
69
|
-
end
|
1
|
+
require "multirepo/utility/console"
|
2
|
+
require "multirepo/utility/utils"
|
3
|
+
require "multirepo/git/repo"
|
4
|
+
require_relative "install-command"
|
5
|
+
|
6
|
+
module MultiRepo
|
7
|
+
class CloneCommand < Command
|
8
|
+
self.command = "clone"
|
9
|
+
self.summary = "Clones the specified repository in a subfolder, then installs it."
|
10
|
+
|
11
|
+
def self.options
|
12
|
+
[
|
13
|
+
['<url>', 'The repository to clone.'],
|
14
|
+
['<name>', 'The name of the containing folder that will be created.'],
|
15
|
+
['[<ref>]', 'The branch, tag or commit id to checkout. Checkout will use "master" if unspecified.']
|
16
|
+
].concat(super)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(argv)
|
20
|
+
@url = argv.shift_argument
|
21
|
+
@name = argv.shift_argument
|
22
|
+
@ref = argv.shift_argument || "master"
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate!
|
27
|
+
super
|
28
|
+
help! "You must specify a repository to clone" unless @url
|
29
|
+
help! "You must specify a containing folder name" unless @name
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
Console.log_step("Cloning #{@url} ...")
|
34
|
+
|
35
|
+
raise MultiRepoException, "A directory named #{@name} already exists" if Dir.exists?(@name)
|
36
|
+
|
37
|
+
main_repo_path = "#{@name}/#{@name}"
|
38
|
+
main_repo = Repo.new(main_repo_path)
|
39
|
+
|
40
|
+
# Recursively create the directory where we'll clone the main repo
|
41
|
+
FileUtils.mkpath(main_repo_path)
|
42
|
+
|
43
|
+
# Clone the specified remote in the just-created directory
|
44
|
+
raise MultiRepoException, "Could not clone repo from #{@url}" unless main_repo.clone(@url)
|
45
|
+
|
46
|
+
# Checkout the specified main repo ref so that install reads the proper config file
|
47
|
+
unless main_repo.checkout(@ref)
|
48
|
+
raise MultiRepoException, "Couldn't perform checkout of main repo #{@ref}!"
|
49
|
+
end
|
50
|
+
|
51
|
+
Console.log_substep("Checked out main repo #{@ref}")
|
52
|
+
|
53
|
+
# Make sure the ref we just checked out is multirepo-enabled
|
54
|
+
unless Utils.is_multirepo_enabled(main_repo_path)
|
55
|
+
raise MultiRepoException, "Ref #{@ref} is not multirepo-enabled"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Install
|
59
|
+
original_path = Dir.pwd
|
60
|
+
Dir.chdir(main_repo_path)
|
61
|
+
install_command = InstallCommand.new(CLAide::ARGV.new([]))
|
62
|
+
install_command.install_dependencies_step
|
63
|
+
Dir.chdir(original_path)
|
64
|
+
|
65
|
+
Console.log_step("Done!")
|
66
|
+
rescue MultiRepoException => e
|
67
|
+
Console.log_error(e.message)
|
68
|
+
end
|
69
|
+
end
|
70
70
|
end
|
@@ -1,51 +1,59 @@
|
|
1
|
-
require "claide"
|
2
|
-
|
3
|
-
require "info"
|
4
|
-
require "multirepo/multirepo-exception"
|
5
|
-
require "multirepo/config"
|
6
|
-
|
7
|
-
module MultiRepo
|
8
|
-
class Command < CLAide::Command
|
9
|
-
self.abstract_command = true
|
10
|
-
self.command = "multi"
|
11
|
-
self.version = VERSION
|
12
|
-
self.description = DESCRIPTION
|
13
|
-
|
14
|
-
def initialize(argv)
|
15
|
-
Config.instance.verbose = argv.flag?("verbose") ? true : false
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
1
|
+
require "claide"
|
2
|
+
|
3
|
+
require "info"
|
4
|
+
require "multirepo/multirepo-exception"
|
5
|
+
require "multirepo/config"
|
6
|
+
|
7
|
+
module MultiRepo
|
8
|
+
class Command < CLAide::Command
|
9
|
+
self.abstract_command = true
|
10
|
+
self.command = "multi"
|
11
|
+
self.version = VERSION
|
12
|
+
self.description = DESCRIPTION
|
13
|
+
|
14
|
+
def initialize(argv)
|
15
|
+
Config.instance.verbose = argv.flag?("verbose") ? true : false
|
16
|
+
Config.instance.git_executable = argv.option("git-exe", "git")
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate!
|
21
|
+
path = Config.instance.git_executable
|
22
|
+
is_git_exe = path =~ /.*(git)|(git.exe)$/
|
23
|
+
file_exists = path == "git" || File.exists?(path)
|
24
|
+
help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_in_work_tree
|
28
|
+
raise MultiRepoException, "Not a git repository" unless Git.is_inside_git_repo(".")
|
29
|
+
end
|
30
|
+
|
31
|
+
def install_hooks_in_multirepo_enabled_dependencies
|
32
|
+
# Install the local git hooks in dependency repos
|
33
|
+
# if they are themselves tracked with multirepo
|
34
|
+
ConfigFile.load.each do |entry|
|
35
|
+
if Utils.is_multirepo_enabled(entry.repo.path)
|
36
|
+
install_hooks(entry.repo.path)
|
37
|
+
Console.log_substep("Installed hooks in multirepo-enabled dependency '#{entry.repo.path}'")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def install_hooks(path = nil)
|
43
|
+
actual_path = path || "."
|
44
|
+
Utils.install_hook("pre-commit", actual_path)
|
45
|
+
Utils.install_hook("prepare-commit-msg", actual_path)
|
46
|
+
Utils.install_hook("post-merge", actual_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
def uninstall_hooks
|
50
|
+
File.delete(".git/hooks/pre-commit")
|
51
|
+
File.delete(".git/hooks/prepare-commit-msg")
|
52
|
+
File.delete(".git/hooks/post-merge")
|
53
|
+
end
|
54
|
+
|
55
|
+
def ensure_multirepo_initialized
|
56
|
+
raise MultiRepoException, "multirepo is not initialized in this repository." unless Utils.is_multirepo_enabled(".")
|
57
|
+
end
|
58
|
+
end
|
51
59
|
end
|
@@ -1,24 +1,24 @@
|
|
1
|
-
require "multirepo/utility/console"
|
2
|
-
|
3
|
-
module MultiRepo
|
4
|
-
class FetchCommand < Command
|
5
|
-
self.command = "fetch"
|
6
|
-
self.summary = "Performs a git fetch on all dependencies."
|
7
|
-
|
8
|
-
def run
|
9
|
-
validate_in_work_tree
|
10
|
-
ensure_multirepo_initialized
|
11
|
-
|
12
|
-
Console.log_step("Fetching dependencies...")
|
13
|
-
|
14
|
-
ConfigFile.load.each do |entry|
|
15
|
-
Console.log_substep("Fetching from #{entry.repo.remote('origin').url}...")
|
16
|
-
entry.repo.fetch
|
17
|
-
end
|
18
|
-
|
19
|
-
Console.log_step("Done!")
|
20
|
-
rescue MultiRepoException => e
|
21
|
-
Console.log_error(e.message)
|
22
|
-
end
|
23
|
-
end
|
1
|
+
require "multirepo/utility/console"
|
2
|
+
|
3
|
+
module MultiRepo
|
4
|
+
class FetchCommand < Command
|
5
|
+
self.command = "fetch"
|
6
|
+
self.summary = "Performs a git fetch on all dependencies."
|
7
|
+
|
8
|
+
def run
|
9
|
+
validate_in_work_tree
|
10
|
+
ensure_multirepo_initialized
|
11
|
+
|
12
|
+
Console.log_step("Fetching dependencies...")
|
13
|
+
|
14
|
+
ConfigFile.load.each do |entry|
|
15
|
+
Console.log_substep("Fetching from #{entry.repo.remote('origin').url}...")
|
16
|
+
entry.repo.fetch
|
17
|
+
end
|
18
|
+
|
19
|
+
Console.log_step("Done!")
|
20
|
+
rescue MultiRepoException => e
|
21
|
+
Console.log_error(e.message)
|
22
|
+
end
|
23
|
+
end
|
24
24
|
end
|
@@ -1,52 +1,52 @@
|
|
1
|
-
require "multirepo/utility/console"
|
2
|
-
require "multirepo/utility/utils"
|
3
|
-
require "multirepo/files/config-file"
|
4
|
-
require "multirepo/files/lock-file"
|
5
|
-
require "multirepo/commands/command"
|
6
|
-
|
7
|
-
module MultiRepo
|
8
|
-
class InitCommand < Command
|
9
|
-
self.command = "init"
|
10
|
-
self.summary = "Initialize the current repository as a multirepo project."
|
11
|
-
|
12
|
-
def run
|
13
|
-
validate_in_work_tree
|
14
|
-
Console.log_step("Initializing new multirepo config...")
|
15
|
-
|
16
|
-
if ConfigFile.exists?
|
17
|
-
return unless Console.ask_yes_no(".multirepo file already exists. Reinitialize?")
|
18
|
-
end
|
19
|
-
|
20
|
-
sibling_repos = Utils.sibling_repos
|
21
|
-
|
22
|
-
if sibling_repos.any?
|
23
|
-
entries = []
|
24
|
-
sibling_repos.each do |repo|
|
25
|
-
origin_desc = repo.remote('origin').url || "[none]"
|
26
|
-
current_branch = repo.current_branch
|
27
|
-
if Console.ask_yes_no("Do you want to add '#{repo.path}' as a dependency?\n [origin: '#{origin_desc}', branch: #{current_branch}]")
|
28
|
-
entries.push(ConfigEntry.new(repo))
|
29
|
-
Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
ConfigFile.save(entries)
|
34
|
-
ConfigFile.stage
|
35
|
-
else
|
36
|
-
Console.log_info("There are no sibling repositories to add")
|
37
|
-
end
|
38
|
-
|
39
|
-
install_hooks
|
40
|
-
Console.log_substep("Installed git hooks")
|
41
|
-
|
42
|
-
Console.log_step("Done!")
|
43
|
-
rescue MultiRepoException => e
|
44
|
-
Console.log_error(e.message)
|
45
|
-
end
|
46
|
-
|
47
|
-
def check_repo_exists
|
48
|
-
if !Dir.exists?(@repo.path) then raise MultiRepoException, "There is no folder at path '#{@repo.path}'" end
|
49
|
-
if !@repo.exists? then raise MultiRepoException, "'#{@repo.path}' is not a repository" end
|
50
|
-
end
|
51
|
-
end
|
1
|
+
require "multirepo/utility/console"
|
2
|
+
require "multirepo/utility/utils"
|
3
|
+
require "multirepo/files/config-file"
|
4
|
+
require "multirepo/files/lock-file"
|
5
|
+
require "multirepo/commands/command"
|
6
|
+
|
7
|
+
module MultiRepo
|
8
|
+
class InitCommand < Command
|
9
|
+
self.command = "init"
|
10
|
+
self.summary = "Initialize the current repository as a multirepo project."
|
11
|
+
|
12
|
+
def run
|
13
|
+
validate_in_work_tree
|
14
|
+
Console.log_step("Initializing new multirepo config...")
|
15
|
+
|
16
|
+
if ConfigFile.exists?
|
17
|
+
return unless Console.ask_yes_no(".multirepo file already exists. Reinitialize?")
|
18
|
+
end
|
19
|
+
|
20
|
+
sibling_repos = Utils.sibling_repos
|
21
|
+
|
22
|
+
if sibling_repos.any?
|
23
|
+
entries = []
|
24
|
+
sibling_repos.each do |repo|
|
25
|
+
origin_desc = repo.remote('origin').url || "[none]"
|
26
|
+
current_branch = repo.current_branch
|
27
|
+
if Console.ask_yes_no("Do you want to add '#{repo.path}' as a dependency?\n [origin: '#{origin_desc}', branch: #{current_branch}]")
|
28
|
+
entries.push(ConfigEntry.new(repo))
|
29
|
+
Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
ConfigFile.save(entries)
|
34
|
+
ConfigFile.stage
|
35
|
+
else
|
36
|
+
Console.log_info("There are no sibling repositories to add")
|
37
|
+
end
|
38
|
+
|
39
|
+
install_hooks
|
40
|
+
Console.log_substep("Installed git hooks")
|
41
|
+
|
42
|
+
Console.log_step("Done!")
|
43
|
+
rescue MultiRepoException => e
|
44
|
+
Console.log_error(e.message)
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_repo_exists
|
48
|
+
if !Dir.exists?(@repo.path) then raise MultiRepoException, "There is no folder at path '#{@repo.path}'" end
|
49
|
+
if !@repo.exists? then raise MultiRepoException, "'#{@repo.path}' is not a repository" end
|
50
|
+
end
|
51
|
+
end
|
52
52
|
end
|
@@ -1,88 +1,88 @@
|
|
1
|
-
require "multirepo/utility/console"
|
2
|
-
require "multirepo/utility/utils"
|
3
|
-
require "multirepo/git/repo"
|
4
|
-
require "multirepo/commands/checkout-command"
|
5
|
-
|
6
|
-
module MultiRepo
|
7
|
-
class InstallCommand < Command
|
8
|
-
self.command = "install"
|
9
|
-
self.summary = "Clones and checks out dependencies as defined in the version-controlled multirepo metadata files and installs git-multirepo's local git hooks."
|
10
|
-
|
11
|
-
def self.options
|
12
|
-
[['
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(argv)
|
16
|
-
@hooks = argv.flag?("hooks")
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
def run
|
21
|
-
validate_in_work_tree
|
22
|
-
ensure_multirepo_initialized
|
23
|
-
|
24
|
-
if @hooks
|
25
|
-
Console.log_step("Installing hooks in main repo and all dependencies...")
|
26
|
-
install_hooks_step
|
27
|
-
else
|
28
|
-
Console.log_step("Cloning dependencies and installing hooks...")
|
29
|
-
install_dependencies_step
|
30
|
-
end
|
31
|
-
|
32
|
-
Console.log_step("Done!")
|
33
|
-
rescue MultiRepoException => e
|
34
|
-
Console.log_error(e.message)
|
35
|
-
end
|
36
|
-
|
37
|
-
def install_dependencies_step
|
38
|
-
# Read config entries as-is on disk, without prior checkout
|
39
|
-
config_entries = ConfigFile.load
|
40
|
-
Console.log_substep("Installing #{config_entries.count} dependencies...");
|
41
|
-
|
42
|
-
# Clone or fetch all configured dependencies to make sure nothing is missing locally
|
43
|
-
config_entries.each { |entry| clone_or_fetch(entry) }
|
44
|
-
|
45
|
-
# Checkout the appropriate branches as specified in the lock file
|
46
|
-
checkout_command = CheckoutCommand.new(CLAide::ARGV.new([]))
|
47
|
-
checkout_command.dependencies_checkout_step(CheckoutCommand::CheckoutMode::LATEST)
|
48
|
-
|
49
|
-
install_hooks_step
|
50
|
-
end
|
51
|
-
|
52
|
-
def install_hooks_step
|
53
|
-
install_hooks
|
54
|
-
Console.log_substep("Installed git hooks in main repo")
|
55
|
-
|
56
|
-
install_hooks_in_multirepo_enabled_dependencies
|
57
|
-
end
|
58
|
-
|
59
|
-
def clone_or_fetch(entry)
|
60
|
-
if entry.repo.exists?
|
61
|
-
check_repo_validity(entry)
|
62
|
-
fetch_repo(entry)
|
63
|
-
else
|
64
|
-
clone_repo(entry)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Repo operations
|
69
|
-
|
70
|
-
def fetch_repo(entry)
|
71
|
-
Console.log_substep("Working copy '#{entry.repo.path}' already exists, fetching instead...")
|
72
|
-
raise MultiRepoException, "Could not fetch from remote #{entry.repo.remote('origin').url}" unless entry.repo.fetch
|
73
|
-
end
|
74
|
-
|
75
|
-
def clone_repo(entry)
|
76
|
-
Console.log_substep("Cloning #{entry.url} into '#{entry.repo.path}'")
|
77
|
-
raise MultiRepoException, "Could not clone remote #{entry.url}" unless entry.repo.clone(entry.url)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Validation
|
81
|
-
|
82
|
-
def check_repo_validity(entry)
|
83
|
-
unless entry.repo.remote("origin").url == entry.url
|
84
|
-
raise MultiRepoException, "'#{entry.path}' origin URL (#{entry.repo.remote('origin').url}) does not match entry (#{entry.url})!"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
1
|
+
require "multirepo/utility/console"
|
2
|
+
require "multirepo/utility/utils"
|
3
|
+
require "multirepo/git/repo"
|
4
|
+
require "multirepo/commands/checkout-command"
|
5
|
+
|
6
|
+
module MultiRepo
|
7
|
+
class InstallCommand < Command
|
8
|
+
self.command = "install"
|
9
|
+
self.summary = "Clones and checks out dependencies as defined in the version-controlled multirepo metadata files and installs git-multirepo's local git hooks."
|
10
|
+
|
11
|
+
def self.options
|
12
|
+
[['[--hooks]', 'Only install local git hooks.']].concat(super)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(argv)
|
16
|
+
@hooks = argv.flag?("hooks")
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
validate_in_work_tree
|
22
|
+
ensure_multirepo_initialized
|
23
|
+
|
24
|
+
if @hooks
|
25
|
+
Console.log_step("Installing hooks in main repo and all dependencies...")
|
26
|
+
install_hooks_step
|
27
|
+
else
|
28
|
+
Console.log_step("Cloning dependencies and installing hooks...")
|
29
|
+
install_dependencies_step
|
30
|
+
end
|
31
|
+
|
32
|
+
Console.log_step("Done!")
|
33
|
+
rescue MultiRepoException => e
|
34
|
+
Console.log_error(e.message)
|
35
|
+
end
|
36
|
+
|
37
|
+
def install_dependencies_step
|
38
|
+
# Read config entries as-is on disk, without prior checkout
|
39
|
+
config_entries = ConfigFile.load
|
40
|
+
Console.log_substep("Installing #{config_entries.count} dependencies...");
|
41
|
+
|
42
|
+
# Clone or fetch all configured dependencies to make sure nothing is missing locally
|
43
|
+
config_entries.each { |entry| clone_or_fetch(entry) }
|
44
|
+
|
45
|
+
# Checkout the appropriate branches as specified in the lock file
|
46
|
+
checkout_command = CheckoutCommand.new(CLAide::ARGV.new([]))
|
47
|
+
checkout_command.dependencies_checkout_step(CheckoutCommand::CheckoutMode::LATEST)
|
48
|
+
|
49
|
+
install_hooks_step
|
50
|
+
end
|
51
|
+
|
52
|
+
def install_hooks_step
|
53
|
+
install_hooks
|
54
|
+
Console.log_substep("Installed git hooks in main repo")
|
55
|
+
|
56
|
+
install_hooks_in_multirepo_enabled_dependencies
|
57
|
+
end
|
58
|
+
|
59
|
+
def clone_or_fetch(entry)
|
60
|
+
if entry.repo.exists?
|
61
|
+
check_repo_validity(entry)
|
62
|
+
fetch_repo(entry)
|
63
|
+
else
|
64
|
+
clone_repo(entry)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Repo operations
|
69
|
+
|
70
|
+
def fetch_repo(entry)
|
71
|
+
Console.log_substep("Working copy '#{entry.repo.path}' already exists, fetching instead...")
|
72
|
+
raise MultiRepoException, "Could not fetch from remote #{entry.repo.remote('origin').url}" unless entry.repo.fetch
|
73
|
+
end
|
74
|
+
|
75
|
+
def clone_repo(entry)
|
76
|
+
Console.log_substep("Cloning #{entry.url} into '#{entry.repo.path}'")
|
77
|
+
raise MultiRepoException, "Could not clone remote #{entry.url}" unless entry.repo.clone(entry.url)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Validation
|
81
|
+
|
82
|
+
def check_repo_validity(entry)
|
83
|
+
unless entry.repo.remote("origin").url == entry.url
|
84
|
+
raise MultiRepoException, "'#{entry.path}' origin URL (#{entry.repo.remote('origin').url}) does not match entry (#{entry.url})!"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
88
|
end
|