git-multirepo 1.0.0.beta38 → 1.0.0.beta39

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 422c984238cb4049bcededa9a63ac57ca1d13445
4
- data.tar.gz: f9e95a0941a9160fc5b714d76bd5c3664c35ba67
3
+ metadata.gz: 94c594ab8e4c0338d3e5e70bb31d4315c1b7fbf0
4
+ data.tar.gz: 0a9b1e7b957e605d17a053abc01c262f7c3c56fb
5
5
  SHA512:
6
- metadata.gz: 73835b202c7a7d5e0104cca153488d57bc3173f30efcb04cea4f0a277f4c522215de0e50dcbeab6cd4216987f794268b6e8fd852d4b62bdbdefd6793ad6878ff
7
- data.tar.gz: 7590706f24a5ca82f2275dbeb361fe251223ccdb6797f959a9fbeb941c0f0b7d852958ca2e01586bdac2be10ccd33a2c4627c732b9e7aadc5ccdebf86b405be9
6
+ metadata.gz: 4179388b91395ade82973ab214327ea34560c3a39d06db5eb4bc6e9461309f39f9ab47611bfb82bfd88f27336a758120c24ea520c6e3b3be3a687ea8ce6b7715
7
+ data.tar.gz: 7ab8047c6256c0001a317d19e398bb0d4093e57f6bd9b7d9bf89339bc39603539ab70513d5c032f049b58219d922fe18c289246809d4182ec96b79954c2d977d
data/.multirepo.meta CHANGED
@@ -1,2 +1,2 @@
1
1
  --- !ruby/object:MultiRepo::MetaFile
2
- version: 1.0.0.beta37
2
+ version: 1.0.0.beta38
data/Gemfile.lock CHANGED
@@ -1,10 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git-multirepo (1.0.0.beta25)
4
+ git-multirepo (1.0.0.beta38)
5
5
  claide (~> 0.8, >= 0.8.0)
6
6
  colored (~> 1.2)
7
7
  os (~> 0.9.6)
8
+ ruby-graphviz (~> 1.2.1)
9
+ terminal-table (~> 1.4.5)
8
10
 
9
11
  GEM
10
12
  remote: https://rubygems.org/
@@ -26,6 +28,8 @@ GEM
26
28
  rspec-mocks (3.1.3)
27
29
  rspec-support (~> 3.1.0)
28
30
  rspec-support (3.1.2)
31
+ ruby-graphviz (1.2.2)
32
+ terminal-table (1.4.5)
29
33
 
30
34
  PLATFORMS
31
35
  ruby
data/README.md CHANGED
@@ -123,9 +123,10 @@ Here is a quick rundown of commands available to you in git-multirepo:
123
123
  | clean | Performs a 'git clean -df' on the main repo and all dependencies. |
124
124
  | clone | Clones the specified repository in a subfolder, then installs it. |
125
125
  | fetch | Performs a git fetch on all dependencies. |
126
+ | graph | Graphs the dependency tree from the current repository. |
126
127
  | install | Clones and checks out dependencies as defined in the version-controlled multirepo metadata files and installs git-multirepo's local git hooks. |
127
128
  | merge | Performs a git merge on all dependencies and the main repo, in the proper order. |
128
- | open | Opens all dependencies in the current OS's file explorer. |
129
+ | open | Opens repositories in the OS's file explorer. |
129
130
  | remove | Removes the specified dependency from multirepo. |
130
131
  | update | Force-updates the multirepo tracking files. |
131
132
  | uninit | Removes all traces of multirepo in the current multirepo repository. |
Binary file
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_runtime_dependency "colored", "~> 1.2"
28
28
  spec.add_runtime_dependency "os", "~> 0.9.6"
29
29
  spec.add_runtime_dependency "terminal-table", "~> 1.4.5"
30
+ spec.add_runtime_dependency "ruby-graphviz", "~> 1.2.1"
30
31
  end
data/lib/commands.rb CHANGED
@@ -5,6 +5,7 @@ require_relative "multirepo/commands/checkout-command"
5
5
  require_relative "multirepo/commands/clean-command"
6
6
  require_relative "multirepo/commands/clone-command"
7
7
  require_relative "multirepo/commands/fetch-command"
8
+ require_relative "multirepo/commands/graph-command"
8
9
  require_relative "multirepo/commands/init-command"
9
10
  require_relative "multirepo/commands/install-command"
10
11
  require_relative "multirepo/commands/merge-command"
data/lib/info.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module MultiRepo
2
2
  NAME = "git-multirepo"
3
- VERSION = "1.0.0.beta38"
3
+ VERSION = "1.0.0.beta39"
4
4
  DESCRIPTION = "Track multiple Git repositories side-by-side."
5
5
  end
@@ -1,6 +1,7 @@
1
1
  require "multirepo/utility/console"
2
2
  require "multirepo/files/config-file"
3
3
  require "multirepo/files/tracking-files"
4
+ require "multirepo/logic/performer"
4
5
 
5
6
  module MultiRepo
6
7
  class BranchCommand < Command
@@ -11,14 +12,14 @@ module MultiRepo
11
12
  [
12
13
  ['<branch name>', 'The name of the branch to create and checkout.'],
13
14
  ['[--force]', 'Force creating the branch even if the repos contain uncommmitted changes.'],
14
- ['[--no-track]', 'Do not configure as a remote-tracking branch on creation.']
15
+ ['[--no-push]', 'Do not push the branch on creation.']
15
16
  ].concat(super)
16
17
  end
17
18
 
18
19
  def initialize(argv)
19
20
  @branch_name = argv.shift_argument
20
21
  @force = argv.flag?("force")
21
- @remote_tracking = argv.flag?("track", true)
22
+ @remote_tracking = argv.flag?("push", true)
22
23
  super
23
24
  end
24
25
 
@@ -35,32 +36,48 @@ module MultiRepo
35
36
  Console.log_step("Branching...")
36
37
 
37
38
  main_repo = Repo.new(".")
38
- config_file = ConfigFile.new(".")
39
- repos = config_file.load_entries.map{ |entry| entry.repo }.push(main_repo)
40
39
 
41
- if !Utils.ensure_working_copies_clean(repos) && !@force
42
- raise MultiRepoException, "Can't branch because not all repos are clean"
40
+ # Ensure the main repo is clean
41
+ raise MultiRepoException, "Main repo is not clean; multi branch aborted" unless main_repo.clean?
42
+
43
+ # Ensure dependencies are clean
44
+ config_entries = ConfigFile.new(".").load_entries
45
+ unless Utils.ensure_dependencies_clean(config_entries)
46
+ raise MultiRepoException, "Dependencies are not clean; multi branch aborted"
43
47
  end
44
48
 
45
- repos.each do |repo|
46
- if @remote_tracking
47
- Console.log_substep("Branching, checking out and pushing '#{repo.path}' #{@branch_name} ...")
48
- else
49
- Console.log_substep("Branching and checking out '#{repo.path}' #{@branch_name} (not pushed) ...")
50
- end
51
-
52
- branch = repo.branch(@branch_name)
53
- branch.create(@remote_tracking) unless branch.exists?
54
- branch.checkout
49
+ # Branch dependencies
50
+ Performer.perform_on_dependencies do |config_entry, lock_entry|
51
+ perform_branch(config_entry.repo)
55
52
  end
56
-
57
- Console.log_substep("Updating and committing tracking files")
58
- TrackingFiles.update
59
- TrackingFiles.commit("[multirepo] Post-branch tracking files update")
60
-
53
+
54
+ # Branch the main repo
55
+ perform_branch(main_repo)
56
+
61
57
  Console.log_step("Done!")
62
58
  rescue MultiRepoException => e
63
59
  Console.log_error(e.message)
64
60
  end
61
+
62
+ def perform_branch(repo)
63
+ Console.log_substep("Branching '#{repo.path}' ...")
64
+ Console.log_info("Creating and checking out branch #{@branch_name} ...")
65
+
66
+ branch = repo.branch(@branch_name)
67
+ branch.create unless branch.exists?
68
+ branch.checkout
69
+
70
+ if Utils.is_multirepo_enabled(repo.path)
71
+ Console.log_info("Updating and committing tracking files")
72
+ tracking_files = TrackingFiles.new(repo.path)
73
+ tracking_files.update
74
+ tracking_files.commit("[multirepo] Post-branch tracking files update")
75
+ end
76
+
77
+ if @remote_tracking
78
+ Console.log_info("Pushing #{@branch_name} to origin/#{@branch_name}")
79
+ repo.branch(@branch_name).push
80
+ end
81
+ end
65
82
  end
66
83
  end
@@ -25,7 +25,9 @@ module MultiRepo
25
25
  def validate!
26
26
  super
27
27
  help! "You must specify a branch or commit id to checkout" unless @ref
28
- help! "You can't provide more than one operation modifier (--latest, --exact, etc.)" if @checkout_latest && @checkout_exact
28
+ unless validate_only_one_flag(@checkout_latest, @checkout_exact)
29
+ help! "You can't provide more than one operation modifier (--latest, --exact, etc.)"
30
+ end
29
31
  end
30
32
 
31
33
  def run
@@ -54,6 +54,10 @@ module MultiRepo
54
54
  def multirepo_enabled_dependencies
55
55
  ConfigFile.new(".").load_entries.select { |e| Utils.is_multirepo_enabled(e.repo.path) }
56
56
  end
57
+
58
+ def validate_only_one_flag(*flags)
59
+ flags.reduce(0) { |count, flag| count += 1 if flag; count } <= 1
60
+ end
57
61
 
58
62
  def ensure_in_work_tree
59
63
  repo = Repo.new(".")
@@ -0,0 +1,46 @@
1
+ require "os"
2
+ require "graphviz"
3
+
4
+ require "multirepo/utility/utils"
5
+ require "multirepo/utility/console"
6
+ require "multirepo/logic/node"
7
+
8
+ module MultiRepo
9
+ class GraphCommand < Command
10
+ self.command = "graph"
11
+ self.summary = "Graphs the dependency tree from the current repository."
12
+
13
+ def run
14
+ super
15
+ ensure_in_work_tree
16
+ ensure_multirepo_enabled
17
+
18
+ root = Node.new(".")
19
+ graph = GraphViz.new(:G, :type => :digraph)
20
+ build_graph_recursive(graph, root)
21
+
22
+ path = File.expand_path("~/Desktop/#{root.name}-graph.png")
23
+
24
+ begin
25
+ graph.output(:png => path)
26
+ Utils.open_in_default_app(path)
27
+ rescue StandardError => e
28
+ Console.log_error(e.message)
29
+ raise MultiRepoException, "Could not generate graph image because an error occurred during graph generation"
30
+ end
31
+
32
+ Console.log_step("Generated graph image #{path}")
33
+ rescue MultiRepoException => e
34
+ Console.log_error(e.message)
35
+ end
36
+
37
+ def build_graph_recursive(graph, node)
38
+ parent_graph_node = graph.add_nodes(node.name)
39
+ node.children.each do |child_node|
40
+ child_graph_node = graph.add_nodes(child_node.name)
41
+ graph.add_edges(parent_graph_node, child_graph_node)
42
+ build_graph_recursive(graph, child_node)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -77,7 +77,7 @@ module MultiRepo
77
77
  end
78
78
 
79
79
  def update_gitattributes_step
80
- TrackingFiles::FILES.each do |f|
80
+ TrackingFiles.new(".").files.each do |f|
81
81
  filename = f.filename
82
82
  regex_escaped_filename = Regexp.quote(filename)
83
83
  Utils.append_if_missing("./.gitattributes", /^#{regex_escaped_filename} .*/, "#{filename} merge=ours")
@@ -29,7 +29,9 @@ module MultiRepo
29
29
  def validate!
30
30
  super
31
31
  help! "You must specify a ref to merge" unless @ref
32
- help! "You can't provide more than one operation modifier (--latest, --exact, etc.)" if @checkout_latest && @checkout_exact
32
+ unless validate_only_one_flag(@checkout_latest, @checkout_exact)
33
+ help! "You can't provide more than one operation modifier (--latest, --exact, etc.)"
34
+ end
33
35
  end
34
36
 
35
37
  def run
@@ -6,22 +6,53 @@ require "multirepo/utility/utils"
6
6
  module MultiRepo
7
7
  class OpenCommand < Command
8
8
  self.command = "open"
9
- self.summary = "Opens all dependencies in the current OS's file explorer."
9
+ self.summary = "Opens repositories in the OS's file explorer."
10
+
11
+ def self.options
12
+ [
13
+ ['[--main]', 'Open the main repository.'],
14
+ ['[--all]', 'Open the main repository and all dependencies.'],
15
+ ].concat(super)
16
+ end
17
+
18
+ def initialize(argv)
19
+ @main_only = argv.flag?("main")
20
+ @all = argv.flag?("all")
21
+ super
22
+ end
23
+
24
+ def validate!
25
+ super
26
+ unless validate_only_one_flag(@main_only, @all)
27
+ help! "You can't provide more than one operation modifier (--deps, --main, etc.)"
28
+ end
29
+ end
10
30
 
11
31
  def run
12
32
  super
13
33
  ensure_in_work_tree
14
34
  ensure_multirepo_enabled
15
35
 
16
- ConfigFile.new(".").load_entries.each do |entry|
17
- if OS.osx?
18
- `open "#{entry.repo.path}"`
19
- elsif OS.windows?
20
- `explorer "#{Utils.convert_to_windows_path(entry.repo.path)}"`
21
- end
36
+ if @main_only
37
+ open_main
38
+ elsif @all
39
+ open_dependencies
40
+ open_main
41
+ else
42
+ open_dependencies
22
43
  end
23
44
  rescue MultiRepoException => e
24
45
  Console.log_error(e.message)
25
46
  end
47
+
48
+ def open_main
49
+ Utils.reveal_in_default_file_browser(".")
50
+ end
51
+
52
+ def open_dependencies
53
+ ConfigFile.new(".").load_entries.each do |entry|
54
+ Utils.reveal_in_default_file_browser(entry.repo.path)
55
+ end
56
+ end
26
57
  end
27
58
  end
@@ -10,7 +10,7 @@ module MultiRepo
10
10
  ensure_in_work_tree
11
11
 
12
12
  FileUtils.rm_f(".multirepo")
13
- TrackingFiles.delete
13
+ TrackingFiles.new(".").delete
14
14
  uninstall_hooks
15
15
 
16
16
  Console.log_step("All traces of multirepo have been removed from this repository")
@@ -41,7 +41,8 @@ module MultiRepo
41
41
  end
42
42
 
43
43
  def update_lock_file_step(log_message)
44
- changed = TrackingFiles.update
44
+ tracking_files = TrackingFiles.new(".")
45
+ changed = tracking_files.update
45
46
 
46
47
  if changed
47
48
  Console.log_substep("Updated tracking files")
@@ -50,7 +51,7 @@ module MultiRepo
50
51
  end
51
52
 
52
53
  if @commit
53
- committed = TrackingFiles.commit("[multirepo] Updated tracking files manually")
54
+ committed = tracking_files.commit("[multirepo] Updated tracking files manually")
54
55
  Console.log_substep("Committed tracking files") if committed
55
56
  elsif changed
56
57
  Console.log_substep(log_message)
@@ -4,39 +4,44 @@ require_relative "lock-file"
4
4
 
5
5
  module MultiRepo
6
6
  class TrackingFiles
7
- FILES = [MetaFile.new("."), LockFile.new(".")]
7
+ attr_accessor :files
8
8
 
9
- def self.update
9
+ def initialize(path)
10
+ @path = path
11
+ @files = [MetaFile.new(path), LockFile.new(path)]
12
+ end
13
+
14
+ def update
10
15
  updated = false
11
- FILES.each { |f| updated |= f.update }
16
+ files.each { |f| updated |= f.update }
12
17
  return updated
13
18
  end
14
19
 
15
- def self.stage
16
- GitRunner.run_in_current_dir("add --force -- #{files_pathspec}", Runner::Verbosity::OUTPUT_ON_ERROR)
20
+ def stage
21
+ GitRunner.run_in_working_dir(@path, "add --force -- #{files_pathspec}", Runner::Verbosity::OUTPUT_ON_ERROR)
17
22
  end
18
23
 
19
- def self.commit(message)
24
+ def commit(message)
20
25
  stage
21
26
 
22
- output = GitRunner.run_in_current_dir("ls-files --modified --others -- #{files_pathspec}", Runner::Verbosity::OUTPUT_NEVER)
27
+ output = GitRunner.run_in_working_dir(@path, "ls-files --modified --others -- #{files_pathspec}", Runner::Verbosity::OUTPUT_NEVER)
23
28
  files_are_untracked_or_modified = output.strip != ""
24
29
 
25
- output = GitRunner.run_in_current_dir("diff --name-only --cached -- #{files_pathspec}", Runner::Verbosity::OUTPUT_NEVER)
30
+ output = GitRunner.run_in_working_dir(@path, "diff --name-only --cached -- #{files_pathspec}", Runner::Verbosity::OUTPUT_NEVER)
26
31
  files_are_staged = output.strip != ""
27
32
 
28
33
  must_commit = files_are_untracked_or_modified || files_are_staged
29
- GitRunner.run_in_current_dir("commit -m \"#{message}\" --only -- #{files_pathspec}", Runner::Verbosity::OUTPUT_ON_ERROR) if must_commit
30
-
34
+ GitRunner.run_in_working_dir(@path, "commit --no-verify -m \"#{message}\" --only -- #{files_pathspec}", Runner::Verbosity::OUTPUT_ON_ERROR) if must_commit
35
+
31
36
  return must_commit
32
37
  end
33
38
 
34
- def self.delete
35
- FILES.each { |f| FileUtils.rm_f(f.file) }
39
+ def delete
40
+ files.each { |f| FileUtils.rm_f(f.file) }
36
41
  end
37
42
 
38
- def self.files_pathspec
39
- FILES.map{ |f| f.file }.join(" ")
43
+ def files_pathspec
44
+ files.map{ |f| File.basename(f.file) }.join(" ")
40
45
  end
41
46
  end
42
47
  end
@@ -15,9 +15,12 @@ module MultiRepo
15
15
  branch_names.include?(@name)
16
16
  end
17
17
 
18
- def create(remote_tracking = false)
18
+ def create
19
19
  GitRunner.run_in_working_dir(@repo.path, "branch #{@name}", Runner::Verbosity::OUTPUT_ON_ERROR)
20
- GitRunner.run_in_working_dir(@repo.path, "push -u origin #{name}", Runner::Verbosity::OUTPUT_ON_ERROR) if remote_tracking
20
+ end
21
+
22
+ def push
23
+ GitRunner.run_in_working_dir(@repo.path, "push -u origin #{@name}", Runner::Verbosity::OUTPUT_ON_ERROR)
21
24
  end
22
25
 
23
26
  def checkout
@@ -13,7 +13,15 @@ module MultiRepo
13
13
  end
14
14
 
15
15
  def self.run_in_working_dir(path, git_command, verbosity)
16
- full_command = "#{git_executable} -C \"#{path}\" #{git_command}";
16
+ if path == "."
17
+ # It is always better to skip -C when running git commands in the
18
+ # current directory (especially in hooks). Doing this prevents
19
+ # any future issues because we automatically fallback to non-"-C" for ".".
20
+ # Fixes bug: https://www.pivotaltracker.com/story/show/94505654
21
+ return run_in_current_dir(git_command, verbosity)
22
+ else
23
+ full_command = "#{git_executable} -C \"#{path}\" #{git_command}";
24
+ end
17
25
 
18
26
  # True fix for the -C flag issue in pre-commit hook where the status command would
19
27
  # fail to provide correct results if a pathspec was provided when performing a commit.
@@ -11,7 +11,7 @@ module MultiRepo
11
11
  Console.log_step("Performing post-commit operations...")
12
12
 
13
13
  # Works around bug #91565510 (https://www.pivotaltracker.com/story/show/91565510)
14
- TrackingFiles.stage
14
+ TrackingFiles.new(".").stage
15
15
  Console.log_info("Cleaned-up staging area")
16
16
 
17
17
  exit 0 # Success!
@@ -17,8 +17,10 @@ module MultiRepo
17
17
  exit 1
18
18
  end
19
19
 
20
- TrackingFiles.update
21
- TrackingFiles.stage
20
+ tracking_files = TrackingFiles.new(".")
21
+ tracking_files.update
22
+ tracking_files.stage
23
+
22
24
  Console.log_info("Updated and staged tracking files")
23
25
 
24
26
  exit 0 # Success!
@@ -10,6 +10,10 @@ module MultiRepo
10
10
  @depth = depth
11
11
  end
12
12
 
13
+ def name
14
+ Pathname.new(File.expand_path(@path)).basename.to_s
15
+ end
16
+
13
17
  def children
14
18
  return [] unless Utils.is_multirepo_enabled(@path)
15
19
  config_entries = ConfigFile.new(@path).load_entries
@@ -54,6 +54,22 @@ module MultiRepo
54
54
  components.join(File::ALT_SEPARATOR)
55
55
  end
56
56
 
57
+ def self.reveal_in_default_file_browser(unix_path)
58
+ if OS.osx?
59
+ system %{open "#{unix_path}"}
60
+ elsif OS.windows?
61
+ system %{explorer "#{Utils.convert_to_windows_path(unix_path)}"}
62
+ end
63
+ end
64
+
65
+ def self.open_in_default_app(unix_path)
66
+ if OS.osx?
67
+ system %{open "#{unix_path}"}
68
+ elsif OS.windows?
69
+ system %{cmd /c "start C:\\#{Utils.convert_to_windows_path(unix_path)}"}
70
+ end
71
+ end
72
+
57
73
  def self.append_if_missing(path, pattern, string_to_append)
58
74
  unless File.exists?(path)
59
75
  File.open(path, 'w') { |f| f.puts(string_to_append) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-multirepo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta38
4
+ version: 1.0.0.beta39
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michaël Fortin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-12 00:00:00.000000000 Z
11
+ date: 2015-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - ~>
115
115
  - !ruby/object:Gem::Version
116
116
  version: 1.4.5
117
+ - !ruby/object:Gem::Dependency
118
+ name: ruby-graphviz
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ~>
122
+ - !ruby/object:Gem::Version
123
+ version: 1.2.1
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ~>
129
+ - !ruby/object:Gem::Version
130
+ version: 1.2.1
117
131
  description: Track multiple Git repositories side-by-side.
118
132
  email:
119
133
  - fortinmike@irradiated.net
@@ -151,6 +165,7 @@ files:
151
165
  - lib/multirepo/commands/clone-command.rb
152
166
  - lib/multirepo/commands/command.rb
153
167
  - lib/multirepo/commands/fetch-command.rb
168
+ - lib/multirepo/commands/graph-command.rb
154
169
  - lib/multirepo/commands/init-command.rb
155
170
  - lib/multirepo/commands/install-command.rb
156
171
  - lib/multirepo/commands/merge-command.rb