git-multirepo 1.0.0.beta60 → 1.0.0.beta61
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/.gitattributes +2 -2
- data/.gitbugtraq +3 -3
- data/.gitignore +38 -38
- data/.rspec +2 -2
- data/.rubocop.yml +79 -79
- data/CHANGELOG.md +75 -71
- data/Gemfile +4 -4
- data/Gemfile.lock +49 -47
- data/LICENSE +22 -22
- data/README.md +179 -179
- data/Rakefile +1 -1
- data/bin/multi +11 -11
- data/docs/bug-repros/91565510-repro.sh +20 -20
- data/git-multirepo.gemspec +32 -32
- data/lib/git-multirepo.rb +3 -3
- data/lib/multirepo/commands/add-command.rb +51 -51
- data/lib/multirepo/commands/branch-command.rb +88 -88
- data/lib/multirepo/commands/checkout-command.rb +127 -127
- data/lib/multirepo/commands/clone-command.rb +68 -68
- data/lib/multirepo/commands/command.rb +87 -87
- data/lib/multirepo/commands/commands.rb +15 -15
- data/lib/multirepo/commands/do-command.rb +101 -101
- data/lib/multirepo/commands/graph-command.rb +43 -43
- data/lib/multirepo/commands/init-command.rb +121 -121
- data/lib/multirepo/commands/inspect-command.rb +48 -48
- data/lib/multirepo/commands/install-command.rb +170 -170
- data/lib/multirepo/commands/merge-command.rb +249 -249
- data/lib/multirepo/commands/open-command.rb +55 -55
- data/lib/multirepo/commands/remove-command.rb +48 -48
- data/lib/multirepo/commands/uninit-command.rb +18 -18
- data/lib/multirepo/commands/update-command.rb +112 -112
- data/lib/multirepo/config.rb +19 -19
- data/lib/multirepo/files/config-entry.rb +39 -39
- data/lib/multirepo/files/config-file.rb +52 -48
- data/lib/multirepo/files/lock-entry.rb +29 -29
- data/lib/multirepo/files/lock-file.rb +62 -58
- data/lib/multirepo/files/meta-file.rb +51 -47
- data/lib/multirepo/files/tracking-file.rb +9 -9
- data/lib/multirepo/files/tracking-files.rb +65 -65
- data/lib/multirepo/git/branch.rb +32 -32
- data/lib/multirepo/git/change.rb +11 -11
- data/lib/multirepo/git/commit.rb +7 -7
- data/lib/multirepo/git/git-runner.rb +56 -56
- data/lib/multirepo/git/git.rb +10 -10
- data/lib/multirepo/git/ref.rb +38 -38
- data/lib/multirepo/git/remote.rb +17 -17
- data/lib/multirepo/git/repo.rb +129 -129
- data/lib/multirepo/hooks/post-commit-hook.rb +23 -23
- data/lib/multirepo/hooks/pre-commit-hook.rb +35 -35
- data/lib/multirepo/info.rb +5 -5
- data/lib/multirepo/logic/dependency.rb +6 -6
- data/lib/multirepo/logic/merge-descriptor.rb +95 -95
- data/lib/multirepo/logic/node.rb +72 -72
- data/lib/multirepo/logic/performer.rb +55 -55
- data/lib/multirepo/logic/repo-selection.rb +25 -25
- data/lib/multirepo/logic/revision-selection.rb +15 -15
- data/lib/multirepo/logic/revision-selector.rb +23 -23
- data/lib/multirepo/logic/version-comparer.rb +10 -10
- data/lib/multirepo/multirepo-exception.rb +6 -6
- data/lib/multirepo/output/extra-output.rb +12 -12
- data/lib/multirepo/output/teamcity-extra-output.rb +11 -11
- data/lib/multirepo/utility/console.rb +52 -52
- data/lib/multirepo/utility/popen-runner.rb +27 -27
- data/lib/multirepo/utility/system-runner.rb +14 -14
- data/lib/multirepo/utility/utils.rb +99 -99
- data/lib/multirepo/utility/verbosity.rb +6 -6
- data/resources/.gitconfig +2 -2
- data/resources/post-commit +6 -6
- data/resources/pre-commit +6 -6
- data/spec/integration/init_spec.rb +19 -19
- data/spec/spec_helper.rb +89 -89
- metadata +9 -15
@@ -1,170 +1,170 @@
|
|
1
|
-
require "terminal-table"
|
2
|
-
|
3
|
-
require "multirepo/utility/console"
|
4
|
-
require "multirepo/utility/utils"
|
5
|
-
require "multirepo/output/extra-output"
|
6
|
-
require "multirepo/git/repo"
|
7
|
-
require "multirepo/logic/performer"
|
8
|
-
require "multirepo/commands/checkout-command"
|
9
|
-
|
10
|
-
module MultiRepo
|
11
|
-
class InstallCommand < Command
|
12
|
-
self.command = "install"
|
13
|
-
self.summary = "Clones and checks out dependencies as defined in the version-controlled multirepo metadata files and installs git-multirepo's local git hooks."
|
14
|
-
|
15
|
-
def self.options
|
16
|
-
[
|
17
|
-
['[--hooks]', 'Only install local git hooks.'],
|
18
|
-
['[--ci]', 'Perform a continuous-integration-aware install (such as on a CI build server or agent).']
|
19
|
-
].concat(super)
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(argv)
|
23
|
-
@hooks = argv.flag?("hooks")
|
24
|
-
@ci = argv.flag?("ci")
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
28
|
-
def validate!
|
29
|
-
super
|
30
|
-
unless Utils.only_one_true?(@hooks, @ci)
|
31
|
-
help! "You can't provide more than one operation modifier (--hooks, --ci, etc.)"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def run
|
36
|
-
ensure_in_work_tree unless @ci
|
37
|
-
ensure_multirepo_tracked
|
38
|
-
|
39
|
-
if @hooks
|
40
|
-
Console.log_step("Installing hooks in main repo and all dependencies...")
|
41
|
-
install_hooks_step
|
42
|
-
else
|
43
|
-
Console.log_step("Installing dependencies...")
|
44
|
-
log_ci_info if @ci
|
45
|
-
full_install
|
46
|
-
end
|
47
|
-
|
48
|
-
Console.log_step("Done!")
|
49
|
-
end
|
50
|
-
|
51
|
-
def full_install
|
52
|
-
install_dependencies_step
|
53
|
-
install_hooks_step unless @ci
|
54
|
-
update_gitconfigs_step unless @ci
|
55
|
-
end
|
56
|
-
|
57
|
-
def install_dependencies_step
|
58
|
-
# Read config entries as-is on disk, without prior checkout
|
59
|
-
config_entries = ConfigFile.new(".").load_entries
|
60
|
-
Console.log_substep("Installing #{config_entries.count} dependencies...")
|
61
|
-
|
62
|
-
# Clone or fetch all configured dependencies to make sure nothing is missing locally
|
63
|
-
Performer.depth_ordered_dependencies.each { |d| clone_or_fetch(d) }
|
64
|
-
|
65
|
-
# Checkout the appropriate branches as specified in the lock file
|
66
|
-
ExtraOutput.progress("Checking out appropriate dependency revisions") if @ci
|
67
|
-
checkout_command = CheckoutCommand.new(CLAide::ARGV.new([]))
|
68
|
-
mode = @ci ? RevisionSelection::AS_LOCK : RevisionSelection::LATEST
|
69
|
-
checkout_command.dependencies_checkout_step(mode)
|
70
|
-
end
|
71
|
-
|
72
|
-
def install_hooks_step
|
73
|
-
perform_in_main_repo_and_dependencies("Installed git hooks") { |repo| install_hooks(repo) }
|
74
|
-
end
|
75
|
-
|
76
|
-
def update_gitconfigs_step
|
77
|
-
perform_in_main_repo_and_dependencies("Updated .git/config file") { |repo| update_gitconfig(repo) }
|
78
|
-
end
|
79
|
-
|
80
|
-
def perform_in_main_repo_and_dependencies(message_prefix, &operation)
|
81
|
-
operation.call(".")
|
82
|
-
Console.log_substep("#{message_prefix} in main repo")
|
83
|
-
|
84
|
-
multirepo_enabled_dependencies.each do |config_entry|
|
85
|
-
operation.call(config_entry.repo.path)
|
86
|
-
Console.log_substep("#{message_prefix} in multirepo-enabled dependency '#{config_entry.repo.path}'")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Repo operations
|
91
|
-
|
92
|
-
def clone_or_fetch(dependency)
|
93
|
-
if dependency.config_entry.repo.exists?
|
94
|
-
check_repo_validity(dependency)
|
95
|
-
|
96
|
-
Console.log_substep("Working copy '#{dependency.config_entry.repo.path}' already exists, fetching...")
|
97
|
-
ExtraOutput.progress("Fetching #{dependency.config_entry.repo.basename}") if @ci
|
98
|
-
fetch_repo(dependency)
|
99
|
-
else
|
100
|
-
Console.log_substep("Cloning #{dependency.config_entry.url} into '#{dependency.config_entry.repo.path}'")
|
101
|
-
ExtraOutput.progress("Cloning into #{dependency.config_entry.repo.basename}") if @ci
|
102
|
-
clone_repo(dependency)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def fetch_repo(dependency)
|
107
|
-
unless dependency.config_entry.repo.fetch
|
108
|
-
ExtraOutput.error("Failed to fetch #{dependency.config_entry.repo.basename}") if @ci
|
109
|
-
fail MultiRepoException, "Could not fetch from remote #{dependency.config_entry.repo.remote('origin').url}"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def clone_repo(dependency)
|
114
|
-
options = { :branch => dependency.lock_entry.branch, :quiet => @ci }
|
115
|
-
unless dependency.config_entry.repo.clone(dependency.config_entry.url, options)
|
116
|
-
ExtraOutput.error("Failed to clone #{dependency.config_entry.repo.basename}") if @ci
|
117
|
-
fail MultiRepoException, "Could not clone remote #{dependency.config_entry.url} with branch #{dependency.lock_entry.branch}"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Validation
|
122
|
-
|
123
|
-
def check_repo_validity(dependency)
|
124
|
-
unless dependency.config_entry.repo.remote("origin").url == dependency.config_entry.url
|
125
|
-
ExtraOutput.error("Repo #{dependency.config_entry.path} origin URL does not match config") if @ci
|
126
|
-
fail MultiRepoException, "'#{dependency.config_entry.path}' origin URL (#{dependency.config_entry.repo.remote('origin').url}) does not match entry (#{dependency.config_entry.url})!"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# Logging
|
131
|
-
|
132
|
-
def log_ci_info
|
133
|
-
Console.log_info("Performing continuous-integration-aware install")
|
134
|
-
Console.log_info("Using git-multirepo #{MultiRepo::VERSION}")
|
135
|
-
|
136
|
-
main_repo = Repo.new(".")
|
137
|
-
|
138
|
-
log_merge_commit_warning(main_repo)
|
139
|
-
log_merge_table(main_repo)
|
140
|
-
end
|
141
|
-
|
142
|
-
def log_merge_commit_warning(main_repo)
|
143
|
-
if main_repo.head.merge_commit?
|
144
|
-
Console.log_warning("[MERGE COMMIT] The checked-out main repo revision is a merge commit.")
|
145
|
-
Console.log_warning("[MERGE COMMIT] Lock file might not represent a valid project state.")
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def log_merge_table(main_repo)
|
150
|
-
meta_file = MetaFile.new(".").load
|
151
|
-
main_repo_branch = main_repo.current_branch
|
152
|
-
|
153
|
-
puts Terminal::Table.new do |t|
|
154
|
-
t.title = "Revision Info"
|
155
|
-
t.add_row ["Tracked Using", "git-multirepo #{meta_file.version}"]
|
156
|
-
t.add_separator
|
157
|
-
t.add_row ["Main Repo", commit_info(main_repo.head.commit_id, (main_repo_branch.name rescue nil))]
|
158
|
-
t.add_separator
|
159
|
-
LockFile.new(".").load_entries.each do |lock_entry|
|
160
|
-
branch_name = lock_entry.branch
|
161
|
-
t.add_row [lock_entry.name, commit_info(lock_entry.head, branch_name)]
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def commit_info(commit_id, branch_name)
|
167
|
-
commit_id + (branch_name ? " (on branch #{branch_name})" : "")
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
1
|
+
require "terminal-table"
|
2
|
+
|
3
|
+
require "multirepo/utility/console"
|
4
|
+
require "multirepo/utility/utils"
|
5
|
+
require "multirepo/output/extra-output"
|
6
|
+
require "multirepo/git/repo"
|
7
|
+
require "multirepo/logic/performer"
|
8
|
+
require "multirepo/commands/checkout-command"
|
9
|
+
|
10
|
+
module MultiRepo
|
11
|
+
class InstallCommand < Command
|
12
|
+
self.command = "install"
|
13
|
+
self.summary = "Clones and checks out dependencies as defined in the version-controlled multirepo metadata files and installs git-multirepo's local git hooks."
|
14
|
+
|
15
|
+
def self.options
|
16
|
+
[
|
17
|
+
['[--hooks]', 'Only install local git hooks.'],
|
18
|
+
['[--ci]', 'Perform a continuous-integration-aware install (such as on a CI build server or agent).']
|
19
|
+
].concat(super)
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(argv)
|
23
|
+
@hooks = argv.flag?("hooks")
|
24
|
+
@ci = argv.flag?("ci")
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate!
|
29
|
+
super
|
30
|
+
unless Utils.only_one_true?(@hooks, @ci)
|
31
|
+
help! "You can't provide more than one operation modifier (--hooks, --ci, etc.)"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def run
|
36
|
+
ensure_in_work_tree unless @ci
|
37
|
+
ensure_multirepo_tracked
|
38
|
+
|
39
|
+
if @hooks
|
40
|
+
Console.log_step("Installing hooks in main repo and all dependencies...")
|
41
|
+
install_hooks_step
|
42
|
+
else
|
43
|
+
Console.log_step("Installing dependencies...")
|
44
|
+
log_ci_info if @ci
|
45
|
+
full_install
|
46
|
+
end
|
47
|
+
|
48
|
+
Console.log_step("Done!")
|
49
|
+
end
|
50
|
+
|
51
|
+
def full_install
|
52
|
+
install_dependencies_step
|
53
|
+
install_hooks_step unless @ci
|
54
|
+
update_gitconfigs_step unless @ci
|
55
|
+
end
|
56
|
+
|
57
|
+
def install_dependencies_step
|
58
|
+
# Read config entries as-is on disk, without prior checkout
|
59
|
+
config_entries = ConfigFile.new(".").load_entries
|
60
|
+
Console.log_substep("Installing #{config_entries.count} dependencies...")
|
61
|
+
|
62
|
+
# Clone or fetch all configured dependencies to make sure nothing is missing locally
|
63
|
+
Performer.depth_ordered_dependencies.each { |d| clone_or_fetch(d) }
|
64
|
+
|
65
|
+
# Checkout the appropriate branches as specified in the lock file
|
66
|
+
ExtraOutput.progress("Checking out appropriate dependency revisions") if @ci
|
67
|
+
checkout_command = CheckoutCommand.new(CLAide::ARGV.new([]))
|
68
|
+
mode = @ci ? RevisionSelection::AS_LOCK : RevisionSelection::LATEST
|
69
|
+
checkout_command.dependencies_checkout_step(mode)
|
70
|
+
end
|
71
|
+
|
72
|
+
def install_hooks_step
|
73
|
+
perform_in_main_repo_and_dependencies("Installed git hooks") { |repo| install_hooks(repo) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def update_gitconfigs_step
|
77
|
+
perform_in_main_repo_and_dependencies("Updated .git/config file") { |repo| update_gitconfig(repo) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def perform_in_main_repo_and_dependencies(message_prefix, &operation)
|
81
|
+
operation.call(".")
|
82
|
+
Console.log_substep("#{message_prefix} in main repo")
|
83
|
+
|
84
|
+
multirepo_enabled_dependencies.each do |config_entry|
|
85
|
+
operation.call(config_entry.repo.path)
|
86
|
+
Console.log_substep("#{message_prefix} in multirepo-enabled dependency '#{config_entry.repo.path}'")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Repo operations
|
91
|
+
|
92
|
+
def clone_or_fetch(dependency)
|
93
|
+
if dependency.config_entry.repo.exists?
|
94
|
+
check_repo_validity(dependency)
|
95
|
+
|
96
|
+
Console.log_substep("Working copy '#{dependency.config_entry.repo.path}' already exists, fetching...")
|
97
|
+
ExtraOutput.progress("Fetching #{dependency.config_entry.repo.basename}") if @ci
|
98
|
+
fetch_repo(dependency)
|
99
|
+
else
|
100
|
+
Console.log_substep("Cloning #{dependency.config_entry.url} into '#{dependency.config_entry.repo.path}'")
|
101
|
+
ExtraOutput.progress("Cloning into #{dependency.config_entry.repo.basename}") if @ci
|
102
|
+
clone_repo(dependency)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def fetch_repo(dependency)
|
107
|
+
unless dependency.config_entry.repo.fetch
|
108
|
+
ExtraOutput.error("Failed to fetch #{dependency.config_entry.repo.basename}") if @ci
|
109
|
+
fail MultiRepoException, "Could not fetch from remote #{dependency.config_entry.repo.remote('origin').url}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def clone_repo(dependency)
|
114
|
+
options = { :branch => dependency.lock_entry.branch, :quiet => @ci }
|
115
|
+
unless dependency.config_entry.repo.clone(dependency.config_entry.url, options)
|
116
|
+
ExtraOutput.error("Failed to clone #{dependency.config_entry.repo.basename}") if @ci
|
117
|
+
fail MultiRepoException, "Could not clone remote #{dependency.config_entry.url} with branch #{dependency.lock_entry.branch}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Validation
|
122
|
+
|
123
|
+
def check_repo_validity(dependency)
|
124
|
+
unless dependency.config_entry.repo.remote("origin").url == dependency.config_entry.url
|
125
|
+
ExtraOutput.error("Repo #{dependency.config_entry.path} origin URL does not match config") if @ci
|
126
|
+
fail MultiRepoException, "'#{dependency.config_entry.path}' origin URL (#{dependency.config_entry.repo.remote('origin').url}) does not match entry (#{dependency.config_entry.url})!"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Logging
|
131
|
+
|
132
|
+
def log_ci_info
|
133
|
+
Console.log_info("Performing continuous-integration-aware install")
|
134
|
+
Console.log_info("Using git-multirepo #{MultiRepo::VERSION}")
|
135
|
+
|
136
|
+
main_repo = Repo.new(".")
|
137
|
+
|
138
|
+
log_merge_commit_warning(main_repo)
|
139
|
+
log_merge_table(main_repo)
|
140
|
+
end
|
141
|
+
|
142
|
+
def log_merge_commit_warning(main_repo)
|
143
|
+
if main_repo.head.merge_commit?
|
144
|
+
Console.log_warning("[MERGE COMMIT] The checked-out main repo revision is a merge commit.")
|
145
|
+
Console.log_warning("[MERGE COMMIT] Lock file might not represent a valid project state.")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def log_merge_table(main_repo)
|
150
|
+
meta_file = MetaFile.new(".").load
|
151
|
+
main_repo_branch = main_repo.current_branch
|
152
|
+
|
153
|
+
puts Terminal::Table.new do |t|
|
154
|
+
t.title = "Revision Info"
|
155
|
+
t.add_row ["Tracked Using", "git-multirepo #{meta_file.version}"]
|
156
|
+
t.add_separator
|
157
|
+
t.add_row ["Main Repo", commit_info(main_repo.head.commit_id, (main_repo_branch.name rescue nil))]
|
158
|
+
t.add_separator
|
159
|
+
LockFile.new(".").load_entries.each do |lock_entry|
|
160
|
+
branch_name = lock_entry.branch
|
161
|
+
t.add_row [lock_entry.name, commit_info(lock_entry.head, branch_name)]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def commit_info(commit_id, branch_name)
|
167
|
+
commit_id + (branch_name ? " (on branch #{branch_name})" : "")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|