Class: MultiRepo::InstallCommand

Inherits:
Command
  • Object
show all
Defined in:
lib/multirepo/commands/install-command.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Command

#ensure_in_work_tree, #ensure_multirepo_enabled, #ensure_multirepo_tracked, #install_hooks, #multirepo_enabled_dependencies, report_error, #uninstall_hooks, #update_gitconfig

Constructor Details

#initialize(argv) ⇒ InstallCommand

Returns a new instance of InstallCommand.



22
23
24
25
26
# File 'lib/multirepo/commands/install-command.rb', line 22

def initialize(argv)
  @hooks = argv.flag?("hooks")
  @ci = argv.flag?("ci")
  super
end

Class Method Details

.optionsObject



15
16
17
18
19
20
# File 'lib/multirepo/commands/install-command.rb', line 15

def self.options
  [
    ['[--hooks]', 'Only install local git hooks.'],
    ['[--ci]', 'Perform a continuous-integration-aware install (such as on a CI build server or agent).']
  ].concat(super)
end

Instance Method Details

#check_repo_validity(dependency) ⇒ Object

Validation



123
124
125
126
127
128
# File 'lib/multirepo/commands/install-command.rb', line 123

def check_repo_validity(dependency)
  unless dependency.config_entry.repo.remote("origin").url == dependency.config_entry.url
    ExtraOutput.error("Repo #{dependency.config_entry.path} origin URL does not match config") if @ci
    fail MultiRepoException, "'#{dependency.config_entry.path}' origin URL (#{dependency.config_entry.repo.remote('origin').url}) does not match entry (#{dependency.config_entry.url})!"
  end
end

#clone_or_fetch(dependency) ⇒ Object

Repo operations



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/multirepo/commands/install-command.rb', line 92

def clone_or_fetch(dependency)
  if dependency.config_entry.repo.exists?
    check_repo_validity(dependency)
    
    Console.log_substep("Working copy '#{dependency.config_entry.repo.path}' already exists, fetching...") 
    ExtraOutput.progress("Fetching #{dependency.config_entry.repo.basename}") if @ci
    fetch_repo(dependency)
  else
    Console.log_substep("Cloning #{dependency.config_entry.url} into '#{dependency.config_entry.repo.path}'")
    ExtraOutput.progress("Cloning into #{dependency.config_entry.repo.basename}") if @ci
    clone_repo(dependency)
  end
end

#clone_repo(dependency) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/multirepo/commands/install-command.rb', line 113

def clone_repo(dependency)
  options = { :branch => dependency.lock_entry.branch, :quiet => @ci }
  unless dependency.config_entry.repo.clone(dependency.config_entry.url, options)
    ExtraOutput.error("Failed to clone #{dependency.config_entry.repo.basename}") if @ci
    fail MultiRepoException, "Could not clone remote #{dependency.config_entry.url} with branch #{dependency.lock_entry.branch}"
  end
end

#commit_info(commit_id, branch_name) ⇒ Object



166
167
168
# File 'lib/multirepo/commands/install-command.rb', line 166

def commit_info(commit_id, branch_name)
  commit_id + (branch_name ? " (on branch #{branch_name})" : "")
end

#fetch_repo(dependency) ⇒ Object



106
107
108
109
110
111
# File 'lib/multirepo/commands/install-command.rb', line 106

def fetch_repo(dependency)
  unless dependency.config_entry.repo.fetch
    ExtraOutput.error("Failed to fetch #{dependency.config_entry.repo.basename}") if @ci
    fail MultiRepoException, "Could not fetch from remote #{dependency.config_entry.repo.remote('origin').url}"
  end
end

#full_installObject



51
52
53
54
55
# File 'lib/multirepo/commands/install-command.rb', line 51

def full_install
  install_dependencies_step
  install_hooks_step unless @ci
  update_gitconfigs_step unless @ci
end

#install_dependencies_stepObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/multirepo/commands/install-command.rb', line 57

def install_dependencies_step
  # Read config entries as-is on disk, without prior checkout
  config_entries = ConfigFile.new(".").load_entries
  Console.log_substep("Installing #{config_entries.count} dependencies...")
  
  # Clone or fetch all configured dependencies to make sure nothing is missing locally
  Performer.depth_ordered_dependencies.each { |d| clone_or_fetch(d) }
  
  # Checkout the appropriate branches as specified in the lock file
  ExtraOutput.progress("Checking out appropriate dependency revisions") if @ci
  checkout_command = CheckoutCommand.new(CLAide::ARGV.new([]))
  mode = @ci ? RevisionSelection::AS_LOCK : RevisionSelection::LATEST
  checkout_command.dependencies_checkout_step(mode, nil, @ci) # Force in CI environment
end

#install_hooks_stepObject



72
73
74
# File 'lib/multirepo/commands/install-command.rb', line 72

def install_hooks_step
  perform_in_main_repo_and_dependencies("Installed git hooks") { |repo| install_hooks(repo) }
end

#log_ci_infoObject

Logging



132
133
134
135
136
137
138
139
140
# File 'lib/multirepo/commands/install-command.rb', line 132

def log_ci_info
  Console.log_info("Performing continuous-integration-aware install")
  Console.log_info("Using git-multirepo #{MultiRepo::VERSION}")
  
  main_repo = Repo.new(".")
  
  log_merge_commit_warning(main_repo)
  log_merge_table(main_repo)
end

#log_merge_commit_warning(main_repo) ⇒ Object



142
143
144
145
146
147
# File 'lib/multirepo/commands/install-command.rb', line 142

def log_merge_commit_warning(main_repo)
  if main_repo.head.merge_commit?
    Console.log_warning("[MERGE COMMIT] The checked-out main repo revision is a merge commit.")
    Console.log_warning("[MERGE COMMIT] Lock file might not represent a valid project state.")
  end
end

#log_merge_table(main_repo) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/multirepo/commands/install-command.rb', line 149

def log_merge_table(main_repo)
  meta_file = MetaFile.new(".").load
  main_repo_branch = main_repo.current_branch
  
  puts Terminal::Table.new do |t|
    t.title = "Revision Info"
    t.add_row ["Tracked Using", "git-multirepo #{meta_file.version}"]
    t.add_separator
    t.add_row ["Main Repo", commit_info(main_repo.head.commit_id, (main_repo_branch.name rescue nil))]
    t.add_separator
    LockFile.new(".").load_entries.each do |lock_entry|
      branch_name = lock_entry.branch
      t.add_row [lock_entry.name, commit_info(lock_entry.head, branch_name)]
    end
  end
end

#perform_in_main_repo_and_dependencies(message_prefix, &operation) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'lib/multirepo/commands/install-command.rb', line 80

def perform_in_main_repo_and_dependencies(message_prefix, &operation)
  operation.call(".")
  Console.log_substep("#{message_prefix} in main repo")
  
  multirepo_enabled_dependencies.each do |config_entry|
    operation.call(config_entry.repo.path)
    Console.log_substep("#{message_prefix} in multirepo-enabled dependency '#{config_entry.repo.path}'")
  end
end

#runObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/multirepo/commands/install-command.rb', line 35

def run
  ensure_in_work_tree unless @ci
  ensure_multirepo_tracked
  
  if @hooks
    Console.log_step("Installing hooks in main repo and all dependencies...")
    install_hooks_step
  else
    Console.log_step("Installing dependencies...")
    log_ci_info if @ci
    full_install
  end
  
  Console.log_step("Done!")
end

#update_gitconfigs_stepObject



76
77
78
# File 'lib/multirepo/commands/install-command.rb', line 76

def update_gitconfigs_step
  perform_in_main_repo_and_dependencies("Updated .git/config file") { |repo| update_gitconfig(repo) }
end

#validate!Object



28
29
30
31
32
33
# File 'lib/multirepo/commands/install-command.rb', line 28

def validate!
  super
  unless Utils.only_one_true?(@hooks, @ci)
    help! "You can't provide more than one operation modifier (--hooks, --ci, etc.)"
  end
end