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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -2
  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 +75 -71
  8. data/Gemfile +4 -4
  9. data/Gemfile.lock +49 -47
  10. data/LICENSE +22 -22
  11. data/README.md +179 -179
  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 +32 -32
  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 +15 -15
  23. data/lib/multirepo/commands/do-command.rb +101 -101
  24. data/lib/multirepo/commands/graph-command.rb +43 -43
  25. data/lib/multirepo/commands/init-command.rb +121 -121
  26. data/lib/multirepo/commands/inspect-command.rb +48 -48
  27. data/lib/multirepo/commands/install-command.rb +170 -170
  28. data/lib/multirepo/commands/merge-command.rb +249 -249
  29. data/lib/multirepo/commands/open-command.rb +55 -55
  30. data/lib/multirepo/commands/remove-command.rb +48 -48
  31. data/lib/multirepo/commands/uninit-command.rb +18 -18
  32. data/lib/multirepo/commands/update-command.rb +112 -112
  33. data/lib/multirepo/config.rb +19 -19
  34. data/lib/multirepo/files/config-entry.rb +39 -39
  35. data/lib/multirepo/files/config-file.rb +52 -48
  36. data/lib/multirepo/files/lock-entry.rb +29 -29
  37. data/lib/multirepo/files/lock-file.rb +62 -58
  38. data/lib/multirepo/files/meta-file.rb +51 -47
  39. data/lib/multirepo/files/tracking-file.rb +9 -9
  40. data/lib/multirepo/files/tracking-files.rb +65 -65
  41. data/lib/multirepo/git/branch.rb +32 -32
  42. data/lib/multirepo/git/change.rb +11 -11
  43. data/lib/multirepo/git/commit.rb +7 -7
  44. data/lib/multirepo/git/git-runner.rb +56 -56
  45. data/lib/multirepo/git/git.rb +10 -10
  46. data/lib/multirepo/git/ref.rb +38 -38
  47. data/lib/multirepo/git/remote.rb +17 -17
  48. data/lib/multirepo/git/repo.rb +129 -129
  49. data/lib/multirepo/hooks/post-commit-hook.rb +23 -23
  50. data/lib/multirepo/hooks/pre-commit-hook.rb +35 -35
  51. data/lib/multirepo/info.rb +5 -5
  52. data/lib/multirepo/logic/dependency.rb +6 -6
  53. data/lib/multirepo/logic/merge-descriptor.rb +95 -95
  54. data/lib/multirepo/logic/node.rb +72 -72
  55. data/lib/multirepo/logic/performer.rb +55 -55
  56. data/lib/multirepo/logic/repo-selection.rb +25 -25
  57. data/lib/multirepo/logic/revision-selection.rb +15 -15
  58. data/lib/multirepo/logic/revision-selector.rb +23 -23
  59. data/lib/multirepo/logic/version-comparer.rb +10 -10
  60. data/lib/multirepo/multirepo-exception.rb +6 -6
  61. data/lib/multirepo/output/extra-output.rb +12 -12
  62. data/lib/multirepo/output/teamcity-extra-output.rb +11 -11
  63. data/lib/multirepo/utility/console.rb +52 -52
  64. data/lib/multirepo/utility/popen-runner.rb +27 -27
  65. data/lib/multirepo/utility/system-runner.rb +14 -14
  66. data/lib/multirepo/utility/utils.rb +99 -99
  67. data/lib/multirepo/utility/verbosity.rb +6 -6
  68. data/resources/.gitconfig +2 -2
  69. data/resources/post-commit +6 -6
  70. data/resources/pre-commit +6 -6
  71. data/spec/integration/init_spec.rb +19 -19
  72. data/spec/spec_helper.rb +89 -89
  73. 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