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,16 +1,16 @@
1
- require_relative "git"
2
-
3
- module MultiRepo
4
- class Remote
5
- attr_accessor :name
6
-
7
- def initialize(repo, name)
8
- @repo = repo
9
- @name = name
10
- end
11
-
12
- def url
13
- Git.run_in_working_dir(@repo.path, "config --get remote.#{@name}.url", Runner::Verbosity::NEVER_OUTPUT).strip
14
- end
15
- end
1
+ require_relative "git"
2
+
3
+ module MultiRepo
4
+ class Remote
5
+ attr_accessor :name
6
+
7
+ def initialize(repo, name)
8
+ @repo = repo
9
+ @name = name
10
+ end
11
+
12
+ def url
13
+ Git.run_in_working_dir(@repo.path, "config --get remote.#{@name}.url", Runner::Verbosity::NEVER_OUTPUT).strip
14
+ end
15
+ end
16
16
  end
@@ -1,67 +1,72 @@
1
- require_relative "branch"
2
- require_relative "remote"
3
- require_relative "change"
4
-
5
- module MultiRepo
6
- class Repo
7
- attr_accessor :path
8
- attr_accessor :basename
9
-
10
- def initialize(path)
11
- @path = path
12
- @basename = Pathname.new(path).basename.to_s
13
- end
14
-
15
- # Inspection
16
-
17
- def exists?
18
- Git.is_inside_git_repo(@path)
19
- end
20
-
21
- def current_branch
22
- branch = Git.run_in_working_dir(@path, "rev-parse --abbrev-ref HEAD", Runner::Verbosity::NEVER_OUTPUT).strip
23
- branch != "HEAD" ? branch : nil
24
- end
25
-
26
- def head_hash
27
- Git.run_in_working_dir(@path, "rev-parse HEAD", Runner::Verbosity::NEVER_OUTPUT).strip
28
- end
29
-
30
- def changes
31
- output = Git.run_in_working_dir(@path, "status --porcelain", Runner::Verbosity::NEVER_OUTPUT)
32
- lines = output.split("\n").each{ |f| f.strip }.delete_if{ |f| f == "" }
33
- lines.map { |l| Change.new(l) }
34
- end
35
-
36
- def is_clean?
37
- return changes.count == 0
38
- end
39
-
40
- # Operations
41
-
42
- def fetch
43
- Git.run_in_working_dir(@path, "fetch --progress", Runner::Verbosity::ALWAYS_OUTPUT)
44
- Runner.last_command_succeeded
45
- end
46
-
47
- def clone(url)
48
- Git.run_in_current_dir("clone #{url} #{@path} --progress", Runner::Verbosity::ALWAYS_OUTPUT)
49
- Runner.last_command_succeeded
50
- end
51
-
52
- def checkout(ref)
53
- Git.run_in_working_dir(@path, "checkout #{ref}", Runner::Verbosity::OUTPUT_ON_ERROR)
54
- Runner.last_command_succeeded
55
- end
56
-
57
- # Remotes and branches
58
-
59
- def branch(name)
60
- Branch.new(self, name)
61
- end
62
-
63
- def remote(name)
64
- Remote.new(self, name)
65
- end
66
- end
1
+ require_relative "branch"
2
+ require_relative "remote"
3
+ require_relative "commit"
4
+ require_relative "change"
5
+
6
+ module MultiRepo
7
+ class Repo
8
+ attr_accessor :path
9
+ attr_accessor :basename
10
+
11
+ def initialize(path)
12
+ @path = path
13
+ @basename = Pathname.new(path).basename.to_s
14
+ end
15
+
16
+ # Inspection
17
+
18
+ def exists?
19
+ Git.is_inside_git_repo(@path)
20
+ end
21
+
22
+ def current_branch
23
+ branch = Git.run_in_working_dir(@path, "rev-parse --abbrev-ref HEAD", Runner::Verbosity::NEVER_OUTPUT).strip
24
+ branch != "HEAD" ? branch : nil
25
+ end
26
+
27
+ def head_hash
28
+ Git.run_in_working_dir(@path, "rev-parse HEAD", Runner::Verbosity::NEVER_OUTPUT).strip
29
+ end
30
+
31
+ def changes
32
+ output = Git.run_in_working_dir(@path, "status --porcelain", Runner::Verbosity::NEVER_OUTPUT)
33
+ lines = output.split("\n").each{ |f| f.strip }.delete_if{ |f| f == "" }
34
+ lines.map { |l| Change.new(l) }
35
+ end
36
+
37
+ def is_clean?
38
+ return changes.count == 0
39
+ end
40
+
41
+ # Operations
42
+
43
+ def fetch
44
+ Git.run_in_working_dir(@path, "fetch --progress", Runner::Verbosity::ALWAYS_OUTPUT)
45
+ Runner.last_command_succeeded
46
+ end
47
+
48
+ def clone(url)
49
+ Git.run_in_current_dir("clone #{url} #{@path} --progress", Runner::Verbosity::ALWAYS_OUTPUT)
50
+ Runner.last_command_succeeded
51
+ end
52
+
53
+ def checkout(ref)
54
+ Git.run_in_working_dir(@path, "checkout #{ref}", Runner::Verbosity::OUTPUT_ON_ERROR)
55
+ Runner.last_command_succeeded
56
+ end
57
+
58
+ # Remotes and branches
59
+
60
+ def branch(name)
61
+ Branch.new(self, name)
62
+ end
63
+
64
+ def remote(name)
65
+ Remote.new(self, name)
66
+ end
67
+
68
+ def commit(ref)
69
+ Commit.new(self, ref)
70
+ end
71
+ end
67
72
  end
@@ -1,26 +1,30 @@
1
- require "multirepo/files/config-file"
2
- require "multirepo/files/lock-file"
3
- require "multirepo/utility/utils"
4
- require "multirepo/utility/console"
5
-
6
- module MultiRepo
7
- class PreCommitHook
8
- def self.run
9
- Config.instance.running_git_hook = true
10
-
11
- Console.log_step("Performing pre-commit operations...")
12
-
13
- dependencies_clean = Utils.ensure_dependencies_clean(ConfigFile.load)
14
-
15
- if !dependencies_clean
16
- Console.log_error("You must commit changes to your dependencies before you can commit this repo")
17
- exit 1
18
- end
19
-
20
- LockFile.update
21
- Console.log_info("Updated and staged lock file with current HEAD revisions for all dependencies")
22
-
23
- exit 0 # Success!
24
- end
25
- end
1
+ require "multirepo/files/config-file"
2
+ require "multirepo/files/lock-file"
3
+ require "multirepo/utility/utils"
4
+ require "multirepo/utility/console"
5
+
6
+ module MultiRepo
7
+ class PreCommitHook
8
+ def self.run
9
+ Config.instance.running_git_hook = true
10
+
11
+ Console.log_step("Performing pre-commit operations...")
12
+
13
+ dependencies_clean = Utils.ensure_dependencies_clean(ConfigFile.load)
14
+
15
+ if !dependencies_clean
16
+ Console.log_error("You must commit changes to your dependencies before you can commit this repo")
17
+ exit 1
18
+ end
19
+
20
+ LockFile.update
21
+ LockFile.stage
22
+ Console.log_info("Updated and staged lock file with current HEAD revisions for all dependencies")
23
+
24
+ exit 0 # Success!
25
+ rescue StandardError => e
26
+ Console.log_error("Pre-commit hook failed to execute! #{e.message}")
27
+ exit 1 # Something went wrong!
28
+ end
29
+ end
26
30
  end
@@ -1,6 +1,6 @@
1
- require "claide/informative_error"
2
-
3
- module MultiRepo
4
- class MultiRepoException < StandardError
5
- end
1
+ require "claide/informative_error"
2
+
3
+ module MultiRepo
4
+ class MultiRepoException < StandardError
5
+ end
6
6
  end
@@ -1,52 +1,52 @@
1
- require "colored"
2
-
3
- module MultiRepo
4
- class Console
5
- def self.log_step(message)
6
- print_prefix
7
- puts $stdout.isatty ? message.bold.green : message
8
- end
9
-
10
- def self.log_substep(message)
11
- print_prefix
12
- puts $stdout.isatty ? message.blue : message
13
- end
14
-
15
- def self.log_info(message)
16
- print_prefix
17
- puts $stdout.isatty ? message.white : message
18
- end
19
-
20
- def self.log_warning(message)
21
- print_prefix
22
- puts $stdout.isatty ? message.yellow : message
23
- end
24
-
25
- def self.log_error(message)
26
- print_prefix
27
- puts $stdout.isatty ? message.red : message
28
- end
29
-
30
- def self.ask_yes_no(message)
31
- answered = false
32
- while !answered
33
- print_prefix
34
- print message
35
- print " (y/n) "
36
-
37
- case $stdin.gets.strip.downcase
38
- when "y", "yes"
39
- answered = true
40
- return true
41
- when "n", "no"
42
- answered = true
43
- return false
44
- end
45
- end
46
- end
47
-
48
- def self.print_prefix
49
- print $stdout.isatty ? "> ".white : "[multirepo] "
50
- end
51
- end
1
+ require "colored"
2
+
3
+ module MultiRepo
4
+ class Console
5
+ def self.log_step(message)
6
+ print_prefix
7
+ puts $stdout.isatty ? message.bold.green : message
8
+ end
9
+
10
+ def self.log_substep(message)
11
+ print_prefix
12
+ puts $stdout.isatty ? message.blue : message
13
+ end
14
+
15
+ def self.log_info(message)
16
+ print_prefix
17
+ puts $stdout.isatty ? message.white : message
18
+ end
19
+
20
+ def self.log_warning(message)
21
+ print_prefix
22
+ puts $stdout.isatty ? message.yellow : message
23
+ end
24
+
25
+ def self.log_error(message)
26
+ print_prefix
27
+ puts $stdout.isatty ? message.red : message
28
+ end
29
+
30
+ def self.ask_yes_no(message)
31
+ answered = false
32
+ while !answered
33
+ print_prefix
34
+ print message
35
+ print " (y/n) "
36
+
37
+ case $stdin.gets.strip.downcase
38
+ when "y", "yes"
39
+ answered = true
40
+ return true
41
+ when "n", "no"
42
+ answered = true
43
+ return false
44
+ end
45
+ end
46
+ end
47
+
48
+ def self.print_prefix
49
+ print $stdout.isatty ? "> ".white : "[multirepo] "
50
+ end
51
+ end
52
52
  end
@@ -1,33 +1,33 @@
1
- require "open3"
2
- require "multirepo/utility/console"
3
-
4
- module MultiRepo
5
- class Runner
6
- class Verbosity
7
- NEVER_OUTPUT = 0
8
- ALWAYS_OUTPUT = 1
9
- OUTPUT_ON_ERROR = 2
10
- end
11
-
12
- class << self
13
- attr_accessor :last_command_succeeded
14
- end
15
-
16
- def self.run(cmd, verbosity)
17
- lines = []
18
- Open3.popen2e(cmd) do |stdin, stdout_and_stderr, thread|
19
- stdout_and_stderr.each do |line|
20
- Console.log_info(line.rstrip) if verbosity == Verbosity::ALWAYS_OUTPUT || Config.instance.verbose
21
- lines << line
22
- end
23
- @last_command_succeeded = thread.value.success?
24
- end
25
-
26
- output = lines.join("").rstrip
27
-
28
- Console.log_error(output) if !@last_command_succeeded && verbosity == Verbosity::OUTPUT_ON_ERROR
29
-
30
- return output
31
- end
32
- end
1
+ require "open3"
2
+ require "multirepo/utility/console"
3
+
4
+ module MultiRepo
5
+ class Runner
6
+ class Verbosity
7
+ NEVER_OUTPUT = 0
8
+ ALWAYS_OUTPUT = 1
9
+ OUTPUT_ON_ERROR = 2
10
+ end
11
+
12
+ class << self
13
+ attr_accessor :last_command_succeeded
14
+ end
15
+
16
+ def self.run(cmd, verbosity)
17
+ lines = []
18
+ Open3.popen2e(cmd) do |stdin, stdout_and_stderr, thread|
19
+ stdout_and_stderr.each do |line|
20
+ Console.log_info(line.rstrip) if verbosity == Verbosity::ALWAYS_OUTPUT || Config.instance.verbose
21
+ lines << line
22
+ end
23
+ @last_command_succeeded = thread.value.success?
24
+ end
25
+
26
+ output = lines.join("").rstrip
27
+
28
+ Console.log_error(output) if !@last_command_succeeded && verbosity == Verbosity::OUTPUT_ON_ERROR
29
+
30
+ return output
31
+ end
32
+ end
33
33
  end
@@ -1,55 +1,67 @@
1
- require "fileutils"
2
-
3
- module MultiRepo
4
- class Utils
5
- def self.path_for_resource(resource_name)
6
- gem_path = Gem::Specification.find_by_name("git-multirepo").gem_dir
7
- File.join(gem_path, "resources/#{resource_name}")
8
- end
9
-
10
- def self.is_multirepo_enabled(path)
11
- File.exists?(File.join(path, ".multirepo"))
12
- end
13
-
14
- def self.is_multirepo_tracked(path)
15
- is_multirepo_enabled(path) && File.exists?(File.join(path, ".multirepo.lock"))
16
- end
17
-
18
- def self.install_hook(name, path)
19
- FileUtils.cp(path_for_resource(name), File.join(path, ".git/hooks"))
20
- end
21
-
22
- def self.sibling_repos
23
- sibling_directories = Dir['../*/']
24
- sibling_repos = sibling_directories.map{ |d| Repo.new(d) }.select{ |r| r.exists? }
25
- sibling_repos.delete_if{ |r| Pathname.new(r.path).realpath == Pathname.new(".").realpath }
26
- end
27
-
28
- def self.ensure_dependencies_clean(config_entries)
29
- clean = true
30
- config_entries.each do |e|
31
- next unless e.repo.exists?
32
- dependency_clean = e.repo.is_clean?
33
- clean &= dependency_clean
34
- Console.log_info("Dependency '#{e.repo.path}' is clean") if dependency_clean
35
- Console.log_warning("Dependency '#{e.repo.path}' contains uncommitted changes") unless dependency_clean
36
- end
37
- return clean
38
- end
39
-
40
- def self.ensure_working_copies_clean(repos)
41
- clean = true
42
- repos.each do |repo|
43
- dependency_clean = repo.is_clean?
44
- clean &= dependency_clean
45
- Console.log_warning("Repo '#{repo.path}' contains uncommitted changes") unless dependency_clean
46
- end
47
- return clean
48
- end
49
-
50
- def self.convert_to_windows_path(unix_path)
51
- components = Pathname.new(unix_path).each_filename.to_a
52
- components.join(File::ALT_SEPARATOR)
53
- end
54
- end
1
+ require "fileutils"
2
+
3
+ module MultiRepo
4
+ class Utils
5
+ def self.path_for_resource(resource_name)
6
+ gem_path = Gem::Specification.find_by_name("git-multirepo").gem_dir
7
+ File.join(gem_path, "resources/#{resource_name}")
8
+ end
9
+
10
+ def self.is_multirepo_enabled(path)
11
+ File.exists?(File.join(path, ".multirepo"))
12
+ end
13
+
14
+ def self.is_multirepo_tracked(path)
15
+ is_multirepo_enabled(path) && File.exists?(File.join(path, ".multirepo.lock"))
16
+ end
17
+
18
+ def self.install_hook(name, path)
19
+ destination_path = File.join(path, ".git/hooks")
20
+ destination_file = File.join(destination_path, name)
21
+ FileUtils.cp(path_for_resource(name), destination_file)
22
+ FileUtils.chmod(0755, destination_file) # -rwxr-xr-x
23
+ end
24
+
25
+ def self.sibling_repos
26
+ sibling_directories = Dir['../*/']
27
+ sibling_repos = sibling_directories.map{ |d| Repo.new(d) }.select{ |r| r.exists? }
28
+ sibling_repos.delete_if{ |r| Pathname.new(r.path).realpath == Pathname.new(".").realpath }
29
+ end
30
+
31
+ def self.ensure_dependencies_clean(config_entries)
32
+ clean = true
33
+ config_entries.each do |e|
34
+ next unless e.repo.exists?
35
+ dependency_clean = e.repo.is_clean?
36
+ clean &= dependency_clean
37
+ Console.log_info("Dependency '#{e.repo.path}' is clean") if dependency_clean
38
+ Console.log_warning("Dependency '#{e.repo.path}' contains uncommitted changes") unless dependency_clean
39
+ end
40
+ return clean
41
+ end
42
+
43
+ def self.ensure_working_copies_clean(repos)
44
+ clean = true
45
+ repos.each do |repo|
46
+ dependency_clean = repo.is_clean?
47
+ clean &= dependency_clean
48
+ Console.log_warning("Repo '#{repo.path}' contains uncommitted changes") unless dependency_clean
49
+ end
50
+ return clean
51
+ end
52
+
53
+ def self.convert_to_windows_path(unix_path)
54
+ components = Pathname.new(unix_path).each_filename.to_a
55
+ components.join(File::ALT_SEPARATOR)
56
+ end
57
+
58
+ def self.append_if_missing(path, pattern, string_to_append)
59
+ unless File.exists?(path)
60
+ File.open(path, 'w') { |f| f.puts(string_to_append) }
61
+ else
62
+ string_located = File.readlines(path).grep(pattern).any?
63
+ File.open(path, 'a') { |f| f.puts(string_to_append) } unless string_located
64
+ end
65
+ end
66
+ end
55
67
  end