git-multirepo 1.0.0.beta65 → 1.0.0.beta66

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +4 -4
  3. data/.gitbugtraq +3 -3
  4. data/.gitignore +38 -38
  5. data/.rspec +2 -2
  6. data/.rubocop.yml +79 -79
  7. data/CHANGELOG.md +95 -91
  8. data/Gemfile +4 -4
  9. data/Gemfile.lock +47 -47
  10. data/LICENSE +22 -22
  11. data/README.md +178 -178
  12. data/Rakefile +1 -1
  13. data/bin/multi +11 -11
  14. data/docs/bug-repros/91565510-repro.sh +20 -20
  15. data/git-multirepo.gemspec +31 -31
  16. data/lib/git-multirepo.rb +3 -3
  17. data/lib/multirepo/commands/add-command.rb +51 -51
  18. data/lib/multirepo/commands/branch-command.rb +88 -88
  19. data/lib/multirepo/commands/checkout-command.rb +127 -127
  20. data/lib/multirepo/commands/clone-command.rb +68 -68
  21. data/lib/multirepo/commands/command.rb +87 -87
  22. data/lib/multirepo/commands/commands.rb +14 -14
  23. data/lib/multirepo/commands/do-command.rb +101 -101
  24. data/lib/multirepo/commands/init-command.rb +121 -121
  25. data/lib/multirepo/commands/inspect-command.rb +48 -48
  26. data/lib/multirepo/commands/install-command.rb +170 -170
  27. data/lib/multirepo/commands/merge-command.rb +251 -249
  28. data/lib/multirepo/commands/open-command.rb +55 -55
  29. data/lib/multirepo/commands/remove-command.rb +48 -48
  30. data/lib/multirepo/commands/uninit-command.rb +18 -18
  31. data/lib/multirepo/commands/update-command.rb +112 -112
  32. data/lib/multirepo/config.rb +19 -19
  33. data/lib/multirepo/files/config-entry.rb +39 -39
  34. data/lib/multirepo/files/config-file.rb +52 -52
  35. data/lib/multirepo/files/lock-entry.rb +29 -29
  36. data/lib/multirepo/files/lock-file.rb +62 -62
  37. data/lib/multirepo/files/meta-file.rb +51 -51
  38. data/lib/multirepo/files/tracking-file.rb +9 -9
  39. data/lib/multirepo/files/tracking-files.rb +64 -64
  40. data/lib/multirepo/git/branch.rb +32 -32
  41. data/lib/multirepo/git/change.rb +11 -11
  42. data/lib/multirepo/git/commit.rb +7 -7
  43. data/lib/multirepo/git/git-runner.rb +56 -56
  44. data/lib/multirepo/git/git.rb +10 -10
  45. data/lib/multirepo/git/ref.rb +38 -38
  46. data/lib/multirepo/git/remote.rb +17 -17
  47. data/lib/multirepo/git/repo.rb +129 -129
  48. data/lib/multirepo/hooks/post-commit-hook.rb +23 -23
  49. data/lib/multirepo/hooks/pre-commit-hook.rb +35 -35
  50. data/lib/multirepo/info.rb +5 -5
  51. data/lib/multirepo/logic/dependency.rb +6 -6
  52. data/lib/multirepo/logic/merge-descriptor.rb +95 -95
  53. data/lib/multirepo/logic/node.rb +72 -72
  54. data/lib/multirepo/logic/performer.rb +55 -55
  55. data/lib/multirepo/logic/repo-selection.rb +25 -25
  56. data/lib/multirepo/logic/revision-selection.rb +15 -15
  57. data/lib/multirepo/logic/revision-selector.rb +23 -23
  58. data/lib/multirepo/logic/version-comparer.rb +10 -10
  59. data/lib/multirepo/multirepo-exception.rb +6 -6
  60. data/lib/multirepo/output/extra-output.rb +12 -12
  61. data/lib/multirepo/output/teamcity-extra-output.rb +11 -11
  62. data/lib/multirepo/utility/console.rb +52 -52
  63. data/lib/multirepo/utility/popen-runner.rb +27 -27
  64. data/lib/multirepo/utility/system-runner.rb +14 -14
  65. data/lib/multirepo/utility/utils.rb +99 -99
  66. data/lib/multirepo/utility/verbosity.rb +6 -6
  67. data/resources/.gitconfig +2 -2
  68. data/resources/post-commit +0 -0
  69. data/resources/pre-commit +0 -0
  70. data/spec/integration/init_spec.rb +19 -19
  71. data/spec/spec_helper.rb +89 -89
  72. metadata +3 -3
@@ -1,87 +1,87 @@
1
- require "claide"
2
-
3
- require "multirepo/info"
4
- require "multirepo/multirepo-exception"
5
- require "multirepo/config"
6
- require "multirepo/files/config-file"
7
- require "multirepo/files/lock-file"
8
-
9
- module MultiRepo
10
- class Command < CLAide::Command
11
- self.abstract_command = true
12
- self.command = "multi"
13
- self.version = VERSION
14
- self.description = DESCRIPTION
15
-
16
- def self.report_error(exception)
17
- if exception.instance_of?(MultiRepoException)
18
- Console.log_error(exception.message)
19
- exit 1
20
- end
21
- fail exception
22
- end
23
-
24
- def initialize(argv)
25
- @argv = argv
26
- Config.instance.verbose |= argv.flag?("verbose") ? true : false
27
- Config.instance.extra_output ||= argv.option("extra-output")
28
- Config.instance.git_executable ||= argv.option("git-exe", "git")
29
- super
30
- end
31
-
32
- def run
33
- help!
34
- end
35
-
36
- def validate!
37
- super
38
- path = Config.instance.git_executable
39
- is_git_exe = path =~ /.*(git)|(git.exe)$/
40
- file_exists = path == "git" || File.exist?(path)
41
- help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
42
- end
43
-
44
- def install_hooks(path)
45
- actual_path = path || "."
46
- Utils.install_hook("pre-commit", actual_path)
47
- Utils.install_hook("post-commit", actual_path)
48
- end
49
-
50
- def uninstall_hooks
51
- FileUtils.rm_f(".git/hooks/pre-commit")
52
- FileUtils.rm_f(".git/hooks/post-commit")
53
- end
54
-
55
- def update_gitconfig(path)
56
- actual_path = path || "."
57
- resource_file = Utils.path_for_resource(".gitconfig")
58
- target_file = File.join(actual_path, '.git/config')
59
-
60
- template = File.read(resource_file)
61
- first_template_line = template.lines.first
62
-
63
- Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
64
- end
65
-
66
- def multirepo_enabled_dependencies
67
- ConfigFile.new(".").load_entries.select { |e| Utils.multirepo_enabled?(e.repo.path) }
68
- end
69
-
70
- def ensure_in_work_tree
71
- repo = Repo.new(".")
72
- fail MultiRepoException, "Not a git repository" unless repo.exists?
73
- fail MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
74
- end
75
-
76
- def ensure_multirepo_enabled
77
- fail MultiRepoException, "multirepo is not initialized in this repository." unless Utils.multirepo_enabled?(".")
78
- end
79
-
80
- def ensure_multirepo_tracked
81
- fail MultiRepoException, "Revision is not tracked by multirepo." unless Utils.multirepo_tracked?(".")
82
-
83
- lock_file_valid = LockFile.new(".").validate!
84
- fail MultiRepoException, "Revision is multirepo-enabled but contains a corrupted lock file!" unless lock_file_valid
85
- end
86
- end
87
- end
1
+ require "claide"
2
+
3
+ require "multirepo/info"
4
+ require "multirepo/multirepo-exception"
5
+ require "multirepo/config"
6
+ require "multirepo/files/config-file"
7
+ require "multirepo/files/lock-file"
8
+
9
+ module MultiRepo
10
+ class Command < CLAide::Command
11
+ self.abstract_command = true
12
+ self.command = "multi"
13
+ self.version = VERSION
14
+ self.description = DESCRIPTION
15
+
16
+ def self.report_error(exception)
17
+ if exception.instance_of?(MultiRepoException)
18
+ Console.log_error(exception.message)
19
+ exit 1
20
+ end
21
+ fail exception
22
+ end
23
+
24
+ def initialize(argv)
25
+ @argv = argv
26
+ Config.instance.verbose |= argv.flag?("verbose") ? true : false
27
+ Config.instance.extra_output ||= argv.option("extra-output")
28
+ Config.instance.git_executable ||= argv.option("git-exe", "git")
29
+ super
30
+ end
31
+
32
+ def run
33
+ help!
34
+ end
35
+
36
+ def validate!
37
+ super
38
+ path = Config.instance.git_executable
39
+ is_git_exe = path =~ /.*(git)|(git.exe)$/
40
+ file_exists = path == "git" || File.exist?(path)
41
+ help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
42
+ end
43
+
44
+ def install_hooks(path)
45
+ actual_path = path || "."
46
+ Utils.install_hook("pre-commit", actual_path)
47
+ Utils.install_hook("post-commit", actual_path)
48
+ end
49
+
50
+ def uninstall_hooks
51
+ FileUtils.rm_f(".git/hooks/pre-commit")
52
+ FileUtils.rm_f(".git/hooks/post-commit")
53
+ end
54
+
55
+ def update_gitconfig(path)
56
+ actual_path = path || "."
57
+ resource_file = Utils.path_for_resource(".gitconfig")
58
+ target_file = File.join(actual_path, '.git/config')
59
+
60
+ template = File.read(resource_file)
61
+ first_template_line = template.lines.first
62
+
63
+ Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
64
+ end
65
+
66
+ def multirepo_enabled_dependencies
67
+ ConfigFile.new(".").load_entries.select { |e| Utils.multirepo_enabled?(e.repo.path) }
68
+ end
69
+
70
+ def ensure_in_work_tree
71
+ repo = Repo.new(".")
72
+ fail MultiRepoException, "Not a git repository" unless repo.exists?
73
+ fail MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
74
+ end
75
+
76
+ def ensure_multirepo_enabled
77
+ fail MultiRepoException, "multirepo is not initialized in this repository." unless Utils.multirepo_enabled?(".")
78
+ end
79
+
80
+ def ensure_multirepo_tracked
81
+ fail MultiRepoException, "Revision is not tracked by multirepo." unless Utils.multirepo_tracked?(".")
82
+
83
+ lock_file_valid = LockFile.new(".").validate!
84
+ fail MultiRepoException, "Revision is multirepo-enabled but contains a corrupted lock file!" unless lock_file_valid
85
+ end
86
+ end
87
+ end
@@ -1,14 +1,14 @@
1
- require_relative "command"
2
- require_relative "add-command"
3
- require_relative "branch-command"
4
- require_relative "checkout-command"
5
- require_relative "clone-command"
6
- require_relative "do-command"
7
- require_relative "init-command"
8
- require_relative "inspect-command"
9
- require_relative "install-command"
10
- require_relative "merge-command"
11
- require_relative "open-command"
12
- require_relative "remove-command"
13
- require_relative "uninit-command"
14
- require_relative "update-command"
1
+ require_relative "command"
2
+ require_relative "add-command"
3
+ require_relative "branch-command"
4
+ require_relative "checkout-command"
5
+ require_relative "clone-command"
6
+ require_relative "do-command"
7
+ require_relative "init-command"
8
+ require_relative "inspect-command"
9
+ require_relative "install-command"
10
+ require_relative "merge-command"
11
+ require_relative "open-command"
12
+ require_relative "remove-command"
13
+ require_relative "uninit-command"
14
+ require_relative "update-command"
@@ -1,101 +1,101 @@
1
- require_relative "command"
2
- require "multirepo/utility/console"
3
- require "multirepo/utility/utils"
4
- require "multirepo/files/config-file"
5
- require "multirepo/git/repo"
6
- require "multirepo/git/git-runner"
7
- require "multirepo/logic/performer"
8
- require "multirepo/logic/repo-selection"
9
-
10
- module MultiRepo
11
- class DoCommand < Command
12
- self.command = "do"
13
- self.summary = "Perform an arbitrary Git operation in the main repository, dependency repositories or all repositories."
14
-
15
- def self.options
16
- [
17
- ['"<operation>"', 'The git command to perform, between quotes, omitting the executable name (ex: "reset --hard HEAD")'],
18
- ['[--main]', 'Perform the operation in the main repository only.'],
19
- ['[--deps]', 'Perform the operation in dependencies only.'],
20
- ['[--all]', 'Perform the operation in the main repository and all dependencies.']
21
- ].concat(super)
22
- end
23
-
24
- def initialize(argv)
25
- @operation = argv.shift_argument
26
- @repo_selection = RepoSelection.new(argv)
27
- super
28
- end
29
-
30
- def validate!
31
- super
32
- help! "You must provide a git operation to perform" unless @operation
33
- help! "You can't provide more than one operation modifier (--deps, --main, etc.)" unless @repo_selection.valid?
34
- end
35
-
36
- def run
37
- ensure_in_work_tree
38
- ensure_multirepo_enabled
39
-
40
- @operation = @operation.sub(/^git /, "")
41
-
42
- success = true
43
- case @repo_selection.value
44
- when RepoSelection::MAIN
45
- confirm_main_repo_operation
46
- success &= perform_operation_on_main(@operation)
47
- when RepoSelection::DEPS
48
- confirm_dependencies_operation
49
- success &= perform_operation_on_dependencies(@operation)
50
- when RepoSelection::ALL
51
- confirm_main_repo_operation
52
- confirm_dependencies_operation
53
- success &= perform_operation_on_dependencies(@operation) # Ordered dependencies first
54
- success &= perform_operation_on_main(@operation) # Main last
55
- end
56
-
57
- Console.log_warning("Some operations finished with non-zero exit status. Please review the above.") unless success
58
- end
59
-
60
- def perform_operation_on_main(operation)
61
- perform_operation(".", operation)
62
- end
63
-
64
- def perform_operation_on_dependencies(operation)
65
- success = true
66
- Performer.depth_ordered_dependencies.each do |dependency|
67
- success &= perform_operation(dependency.config_entry.repo.path, operation)
68
- end
69
- return success
70
- end
71
-
72
- def perform_operation(path, operation)
73
- Console.log_step("Performing operation on '#{path}'")
74
- GitRunner.run_as_system(path, operation)
75
- GitRunner.last_command_succeeded
76
- end
77
-
78
- def confirm_main_repo_operation
79
- unless main_repo_clean?
80
- Console.log_warning("Main repo contains uncommitted changes")
81
- fail MultiRepoException, "Aborted" unless Console.ask("Proceed anyway?")
82
- end
83
- end
84
-
85
- def confirm_dependencies_operation
86
- unless dependencies_clean?
87
- Console.log_warning("Some dependencies contain uncommitted changes")
88
- fail MultiRepoException, "Aborted" unless Console.ask("Proceed anyway?")
89
- end
90
- end
91
-
92
- def main_repo_clean?
93
- Repo.new(".").clean?
94
- end
95
-
96
- def dependencies_clean?
97
- config_entries = ConfigFile.new(".").load_entries
98
- return Utils.dependencies_clean?(config_entries)
99
- end
100
- end
101
- end
1
+ require_relative "command"
2
+ require "multirepo/utility/console"
3
+ require "multirepo/utility/utils"
4
+ require "multirepo/files/config-file"
5
+ require "multirepo/git/repo"
6
+ require "multirepo/git/git-runner"
7
+ require "multirepo/logic/performer"
8
+ require "multirepo/logic/repo-selection"
9
+
10
+ module MultiRepo
11
+ class DoCommand < Command
12
+ self.command = "do"
13
+ self.summary = "Perform an arbitrary Git operation in the main repository, dependency repositories or all repositories."
14
+
15
+ def self.options
16
+ [
17
+ ['"<operation>"', 'The git command to perform, between quotes, omitting the executable name (ex: "reset --hard HEAD")'],
18
+ ['[--main]', 'Perform the operation in the main repository only.'],
19
+ ['[--deps]', 'Perform the operation in dependencies only.'],
20
+ ['[--all]', 'Perform the operation in the main repository and all dependencies.']
21
+ ].concat(super)
22
+ end
23
+
24
+ def initialize(argv)
25
+ @operation = argv.shift_argument
26
+ @repo_selection = RepoSelection.new(argv)
27
+ super
28
+ end
29
+
30
+ def validate!
31
+ super
32
+ help! "You must provide a git operation to perform" unless @operation
33
+ help! "You can't provide more than one operation modifier (--deps, --main, etc.)" unless @repo_selection.valid?
34
+ end
35
+
36
+ def run
37
+ ensure_in_work_tree
38
+ ensure_multirepo_enabled
39
+
40
+ @operation = @operation.sub(/^git /, "")
41
+
42
+ success = true
43
+ case @repo_selection.value
44
+ when RepoSelection::MAIN
45
+ confirm_main_repo_operation
46
+ success &= perform_operation_on_main(@operation)
47
+ when RepoSelection::DEPS
48
+ confirm_dependencies_operation
49
+ success &= perform_operation_on_dependencies(@operation)
50
+ when RepoSelection::ALL
51
+ confirm_main_repo_operation
52
+ confirm_dependencies_operation
53
+ success &= perform_operation_on_dependencies(@operation) # Ordered dependencies first
54
+ success &= perform_operation_on_main(@operation) # Main last
55
+ end
56
+
57
+ Console.log_warning("Some operations finished with non-zero exit status. Please review the above.") unless success
58
+ end
59
+
60
+ def perform_operation_on_main(operation)
61
+ perform_operation(".", operation)
62
+ end
63
+
64
+ def perform_operation_on_dependencies(operation)
65
+ success = true
66
+ Performer.depth_ordered_dependencies.each do |dependency|
67
+ success &= perform_operation(dependency.config_entry.repo.path, operation)
68
+ end
69
+ return success
70
+ end
71
+
72
+ def perform_operation(path, operation)
73
+ Console.log_step("Performing operation on '#{path}'")
74
+ GitRunner.run_as_system(path, operation)
75
+ GitRunner.last_command_succeeded
76
+ end
77
+
78
+ def confirm_main_repo_operation
79
+ unless main_repo_clean?
80
+ Console.log_warning("Main repo contains uncommitted changes")
81
+ fail MultiRepoException, "Aborted" unless Console.ask("Proceed anyway?")
82
+ end
83
+ end
84
+
85
+ def confirm_dependencies_operation
86
+ unless dependencies_clean?
87
+ Console.log_warning("Some dependencies contain uncommitted changes")
88
+ fail MultiRepoException, "Aborted" unless Console.ask("Proceed anyway?")
89
+ end
90
+ end
91
+
92
+ def main_repo_clean?
93
+ Repo.new(".").clean?
94
+ end
95
+
96
+ def dependencies_clean?
97
+ config_entries = ConfigFile.new(".").load_entries
98
+ return Utils.dependencies_clean?(config_entries)
99
+ end
100
+ end
101
+ end
@@ -1,121 +1,121 @@
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/files/tracking-files"
6
- require "multirepo/commands/command"
7
-
8
- module MultiRepo
9
- class InitCommand < Command
10
- self.command = "init"
11
- self.summary = "Initialize the current repository as a multirepo project."
12
-
13
- def self.options
14
- [['[--extras]', 'Keep the current .multirepo config file as-is and initialize everything else.']].concat(super)
15
- end
16
-
17
- def initialize(argv)
18
- @only_extras = argv.flag?("extras")
19
- super
20
- end
21
-
22
- def run
23
- ensure_in_work_tree
24
-
25
- if @only_extras
26
- ensure_multirepo_enabled
27
- Console.log_step("Initializing extras...")
28
- initialize_extras_step
29
- else
30
- Console.log_step("Initializing multirepo...")
31
- full_initialize_step
32
- end
33
-
34
- Console.log_step("Done!")
35
- end
36
-
37
- def full_initialize_step
38
- if ConfigFile.new(".").exists?
39
- reinitialize = Console.ask(".multirepo file already exists. Reinitialize?")
40
- fail MultiRepoException, "Initialization aborted" unless reinitialize
41
- end
42
-
43
- unless add_sibling_repos_step
44
- fail MultiRepoException, "There are no sibling repositories to track as dependencies. Initialization aborted."
45
- end
46
-
47
- initialize_extras_step
48
- end
49
-
50
- def add_sibling_repos_step
51
- sibling_repos = Utils.sibling_repos
52
- return false unless sibling_repos.any?
53
-
54
- Console.log_substep("Creating new multirepo config...")
55
-
56
- valid_repos = find_valid_repos(sibling_repos)
57
- entries = create_entries(valid_repos)
58
-
59
- fail MultiRepoException, "No sibling repositories were added as dependencies; init aborted" unless entries.any?
60
-
61
- ConfigFile.new(".").save_entries(entries)
62
- return true
63
- end
64
-
65
- def initialize_extras_step
66
- install_hooks_step
67
- update_gitattributes_step
68
- update_gitconfig_step
69
- end
70
-
71
- def install_hooks_step
72
- install_hooks(".")
73
- Console.log_substep("Installed git hooks")
74
- end
75
-
76
- def update_gitattributes_step
77
- TrackingFiles.new(".").files.each do |f|
78
- filename = f.filename
79
- regex_escaped_filename = Regexp.quote(filename)
80
- Utils.append_if_missing("./.gitattributes", /^#{regex_escaped_filename} .*/, "#{filename} merge=ours")
81
- end
82
- Console.log_substep("Updated .gitattributes file")
83
- end
84
-
85
- def update_gitconfig_step
86
- update_gitconfig(".")
87
- Console.log_substep("Updated .git/config file")
88
- end
89
-
90
- def find_valid_repos(repos)
91
- repos.select do |repo|
92
- next true if repo.head_born?
93
- Console.log_warning("Ignoring repo '#{repo.path}' because its HEAD is unborn. You must perform at least one commit.")
94
- end
95
- end
96
-
97
- def create_entries(repos)
98
- entries = []
99
- repos.each do |repo|
100
- origin_url = repo.remote('origin').url
101
- current_branch_name = repo.current_branch.name
102
-
103
- next unless Console.ask("Do you want to add '#{repo.path}' as a dependency?\n [origin: #{origin_url || 'NONE'}, branch: #{current_branch_name}]")
104
-
105
- unless origin_url
106
- Console.log_warning("Repo 'origin' remote url is not set; skipping")
107
- next
108
- end
109
-
110
- entries.push(ConfigEntry.new(repo))
111
- Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
112
- end
113
- return entries
114
- end
115
-
116
- def check_repo_exists
117
- fail MultiRepoException, "There is no folder at path '#{@repo.path}'" unless Dir.exist?(@repo.path)
118
- fail MultiRepoException, "'#{@repo.path}' is not a repository" unless @repo.exists?
119
- end
120
- end
121
- 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/files/tracking-files"
6
+ require "multirepo/commands/command"
7
+
8
+ module MultiRepo
9
+ class InitCommand < Command
10
+ self.command = "init"
11
+ self.summary = "Initialize the current repository as a multirepo project."
12
+
13
+ def self.options
14
+ [['[--extras]', 'Keep the current .multirepo config file as-is and initialize everything else.']].concat(super)
15
+ end
16
+
17
+ def initialize(argv)
18
+ @only_extras = argv.flag?("extras")
19
+ super
20
+ end
21
+
22
+ def run
23
+ ensure_in_work_tree
24
+
25
+ if @only_extras
26
+ ensure_multirepo_enabled
27
+ Console.log_step("Initializing extras...")
28
+ initialize_extras_step
29
+ else
30
+ Console.log_step("Initializing multirepo...")
31
+ full_initialize_step
32
+ end
33
+
34
+ Console.log_step("Done!")
35
+ end
36
+
37
+ def full_initialize_step
38
+ if ConfigFile.new(".").exists?
39
+ reinitialize = Console.ask(".multirepo file already exists. Reinitialize?")
40
+ fail MultiRepoException, "Initialization aborted" unless reinitialize
41
+ end
42
+
43
+ unless add_sibling_repos_step
44
+ fail MultiRepoException, "There are no sibling repositories to track as dependencies. Initialization aborted."
45
+ end
46
+
47
+ initialize_extras_step
48
+ end
49
+
50
+ def add_sibling_repos_step
51
+ sibling_repos = Utils.sibling_repos
52
+ return false unless sibling_repos.any?
53
+
54
+ Console.log_substep("Creating new multirepo config...")
55
+
56
+ valid_repos = find_valid_repos(sibling_repos)
57
+ entries = create_entries(valid_repos)
58
+
59
+ fail MultiRepoException, "No sibling repositories were added as dependencies; init aborted" unless entries.any?
60
+
61
+ ConfigFile.new(".").save_entries(entries)
62
+ return true
63
+ end
64
+
65
+ def initialize_extras_step
66
+ install_hooks_step
67
+ update_gitattributes_step
68
+ update_gitconfig_step
69
+ end
70
+
71
+ def install_hooks_step
72
+ install_hooks(".")
73
+ Console.log_substep("Installed git hooks")
74
+ end
75
+
76
+ def update_gitattributes_step
77
+ TrackingFiles.new(".").files.each do |f|
78
+ filename = f.filename
79
+ regex_escaped_filename = Regexp.quote(filename)
80
+ Utils.append_if_missing("./.gitattributes", /^#{regex_escaped_filename} .*/, "#{filename} merge=ours")
81
+ end
82
+ Console.log_substep("Updated .gitattributes file")
83
+ end
84
+
85
+ def update_gitconfig_step
86
+ update_gitconfig(".")
87
+ Console.log_substep("Updated .git/config file")
88
+ end
89
+
90
+ def find_valid_repos(repos)
91
+ repos.select do |repo|
92
+ next true if repo.head_born?
93
+ Console.log_warning("Ignoring repo '#{repo.path}' because its HEAD is unborn. You must perform at least one commit.")
94
+ end
95
+ end
96
+
97
+ def create_entries(repos)
98
+ entries = []
99
+ repos.each do |repo|
100
+ origin_url = repo.remote('origin').url
101
+ current_branch_name = repo.current_branch.name
102
+
103
+ next unless Console.ask("Do you want to add '#{repo.path}' as a dependency?\n [origin: #{origin_url || 'NONE'}, branch: #{current_branch_name}]")
104
+
105
+ unless origin_url
106
+ Console.log_warning("Repo 'origin' remote url is not set; skipping")
107
+ next
108
+ end
109
+
110
+ entries.push(ConfigEntry.new(repo))
111
+ Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
112
+ end
113
+ return entries
114
+ end
115
+
116
+ def check_repo_exists
117
+ fail MultiRepoException, "There is no folder at path '#{@repo.path}'" unless Dir.exist?(@repo.path)
118
+ fail MultiRepoException, "'#{@repo.path}' is not a repository" unless @repo.exists?
119
+ end
120
+ end
121
+ end