git-multirepo 1.0.0.beta27 → 1.0.0.beta29

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +38 -38
  3. data/.rspec +2 -2
  4. data/Gemfile +4 -4
  5. data/Gemfile.lock +38 -38
  6. data/LICENSE +22 -22
  7. data/README.md +141 -141
  8. data/Rakefile +2 -2
  9. data/bin/multi +10 -10
  10. data/git-multirepo.gemspec +29 -29
  11. data/lib/commands.rb +11 -11
  12. data/lib/git-multirepo.rb +1 -3
  13. data/lib/info.rb +4 -4
  14. data/lib/multirepo/commands/add-command.rb +50 -51
  15. data/lib/multirepo/commands/branch-command.rb +59 -59
  16. data/lib/multirepo/commands/checkout-command.rb +139 -119
  17. data/lib/multirepo/commands/clone-command.rb +69 -69
  18. data/lib/multirepo/commands/command.rb +62 -62
  19. data/lib/multirepo/commands/fetch-command.rb +23 -23
  20. data/lib/multirepo/commands/init-command.rb +94 -51
  21. data/lib/multirepo/commands/install-command.rb +104 -87
  22. data/lib/multirepo/commands/open-command.rb +25 -25
  23. data/lib/multirepo/commands/remove-command.rb +48 -48
  24. data/lib/multirepo/commands/uninit-command.rb +19 -19
  25. data/lib/multirepo/commands/update-command.rb +53 -47
  26. data/lib/multirepo/config.rb +15 -15
  27. data/lib/multirepo/files/config-entry.rb +34 -34
  28. data/lib/multirepo/files/config-file.rb +33 -37
  29. data/lib/multirepo/files/lock-entry.rb +25 -25
  30. data/lib/multirepo/files/lock-file.rb +44 -39
  31. data/lib/multirepo/git/branch.rb +27 -27
  32. data/lib/multirepo/git/change.rb +10 -10
  33. data/lib/multirepo/git/commit.rb +18 -0
  34. data/lib/multirepo/git/git.rb +42 -42
  35. data/lib/multirepo/git/remote.rb +15 -15
  36. data/lib/multirepo/git/repo.rb +71 -66
  37. data/lib/multirepo/hooks/pre-commit-hook.rb +29 -25
  38. data/lib/multirepo/multirepo-exception.rb +5 -5
  39. data/lib/multirepo/utility/console.rb +51 -51
  40. data/lib/multirepo/utility/runner.rb +32 -32
  41. data/lib/multirepo/utility/utils.rb +66 -54
  42. data/resources/.gitconfig +3 -0
  43. data/resources/pre-commit +5 -5
  44. data/spec/integration/init_spec.rb +18 -22
  45. data/spec/spec_helper.rb +89 -89
  46. metadata +5 -7
  47. data/lib/multirepo/hooks/post-merge-hook.rb +0 -20
  48. data/lib/multirepo/hooks/prepare-commit-msg-hook.rb +0 -28
  49. data/resources/post-merge +0 -6
  50. data/resources/prepare-commit-msg +0 -6
@@ -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
- ['<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 tracked by multirepo
54
- unless Utils.is_multirepo_tracked(main_repo_path)
55
- raise MultiRepoException, "Ref #{@ref} is not tracked by multirepo"
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 tracked by multirepo
54
+ unless Utils.is_multirepo_tracked(main_repo_path)
55
+ raise MultiRepoException, "Ref #{@ref} is not tracked by multirepo"
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.full_install
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,63 +1,63 @@
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 multirepo-enabled
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_enabled
56
- raise MultiRepoException, "multirepo is not initialized in this repository." unless Utils.is_multirepo_enabled(".")
57
- end
58
-
59
- def ensure_multirepo_tracked
60
- raise MultiRepoException, "This revision is not tracked by multirepo." unless Utils.is_multirepo_tracked(".")
61
- end
62
- end
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(path)
32
+ actual_path = path || "."
33
+ Utils.install_hook("pre-commit", actual_path)
34
+ end
35
+
36
+ def uninstall_hooks
37
+ File.delete(".git/hooks/pre-commit")
38
+ end
39
+
40
+ def update_gitconfig(path)
41
+ actual_path = path || "."
42
+ resource_file = Utils.path_for_resource(".gitconfig")
43
+ target_file = File.join(actual_path, '.git/config')
44
+
45
+ template = File.read(resource_file)
46
+ first_template_line = template.lines.first
47
+
48
+ Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
49
+ end
50
+
51
+ def multirepo_enabled_dependencies
52
+ ConfigFile.load.select { |e| Utils.is_multirepo_enabled(e.repo.path) }
53
+ end
54
+
55
+ def ensure_multirepo_enabled
56
+ raise MultiRepoException, "multirepo is not initialized in this repository." unless Utils.is_multirepo_enabled(".")
57
+ end
58
+
59
+ def ensure_multirepo_tracked
60
+ raise MultiRepoException, "This revision is not tracked by multirepo." unless Utils.is_multirepo_tracked(".")
61
+ end
62
+ end
63
63
  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_enabled
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_enabled
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,95 @@
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 self.options
13
+ [['[--extras]', 'Keep the current .multirepo config file as-is and initialize everything else.']].concat(super)
14
+ end
15
+
16
+ def initialize(argv)
17
+ @only_extras = argv.flag?("extras")
18
+ super
19
+ end
20
+
21
+ def run
22
+ validate_in_work_tree
23
+
24
+ if @only_extras
25
+ Console.log_step("Initializing extras...")
26
+ initialize_extras_step
27
+ else
28
+ Console.log_step("Initializing multirepo...")
29
+ full_initialize_step
30
+ end
31
+
32
+ Console.log_step("Done!")
33
+ rescue MultiRepoException => e
34
+ Console.log_error(e.message)
35
+ end
36
+
37
+ def full_initialize_step
38
+ if ConfigFile.exists?
39
+ reinitialize = Console.ask_yes_no(".multirepo file already exists. Reinitialize?")
40
+ raise MultiRepoException, "Initialization aborted" unless reinitialize
41
+ end
42
+
43
+ Console.log_substep("Creating new multirepo config...")
44
+
45
+ add_sibling_repos_step
46
+ initialize_extras_step
47
+ end
48
+
49
+ def add_sibling_repos_step
50
+ sibling_repos = Utils.sibling_repos
51
+
52
+ if sibling_repos.any?
53
+ entries = []
54
+ sibling_repos.each do |repo|
55
+ origin_desc = repo.remote('origin').url || "[none]"
56
+ current_branch = repo.current_branch
57
+ if Console.ask_yes_no("Do you want to add '#{repo.path}' as a dependency?\n [origin: '#{origin_desc}', branch: #{current_branch}]")
58
+ entries.push(ConfigEntry.new(repo))
59
+ Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
60
+ end
61
+ end
62
+
63
+ ConfigFile.save(entries)
64
+ else
65
+ Console.log_info("There are no sibling repositories to add")
66
+ end
67
+ end
68
+
69
+ def initialize_extras_step
70
+ install_hooks_step
71
+ update_gitattributes_step
72
+ update_gitconfig_step
73
+ end
74
+
75
+ def install_hooks_step
76
+ install_hooks(".")
77
+ Console.log_substep("Installed git hooks")
78
+ end
79
+
80
+ def update_gitattributes_step
81
+ Utils.append_if_missing("./.gitattributes", /^.multirepo.lock .*/, ".multirepo.lock merge=ours")
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 check_repo_exists
91
+ if !Dir.exists?(@repo.path) then raise MultiRepoException, "There is no folder at path '#{@repo.path}'" end
92
+ if !@repo.exists? then raise MultiRepoException, "'#{@repo.path}' is not a repository" end
93
+ end
94
+ end
52
95
  end