lib/teapot/controller/fetch.rb in teapot-1.1.2 vs lib/teapot/controller/fetch.rb in teapot-1.2.0
- old
+ new
@@ -21,21 +21,20 @@
require_relative '../controller'
require_relative '../repository'
module Teapot
class Controller
- def fetch
+ def fetch(**options)
resolved = Set.new
configuration = context.configuration
unresolved = context.unresolved(configuration.packages)
- tries = 0
- while tries < @options[:maximum_fetch_depth]
+ while true
configuration.packages.each do |package|
next if resolved.include? package
- fetch_package(context, configuration, package)
+ fetch_package(context, configuration, package, **options)
# We are done with this package, don't try to process it again:
resolved << package
end
@@ -47,12 +46,10 @@
# No additional packages were resolved, we have reached a fixed point:
if previously_unresolved == unresolved || unresolved.count == 0
break
end
-
- tries += 1
end
if unresolved.count > 0
log "Could not fetch all packages!".color(:red)
unresolved.each do |package|
@@ -64,80 +61,111 @@
end
private
def current_commit(package)
- IO.popen(['git', '--git-dir', (package.path + ".git").to_s, 'rev-parse', '--verify', 'HEAD']) do |io|
+ IO.popen(['git', '--git-dir', (package.path + '.git').to_s, 'rev-parse', '--verify', 'HEAD']) do |io|
io.read.chomp!
end
end
-
- def fetch_package(context, configuration, package)
- destination_path = package.path
- lock_store = configuration.lock_store
- if package.local?
- log "Linking local #{package}...".color(:cyan)
+ def current_branch(package)
+ IO.popen(['git', '--git-dir', (package.path + '.git').to_s, 'rev-parse', '--abbrev-ref', 'HEAD']) do |io|
+ io.read.chomp!
+ end
+ end
- local_path = context.root + package.options[:local]
+ def current_metadata(package)
+ {
+ branch: current_branch(package),
+ commit: current_commit(package)
+ }
+ end
+
+ def link_local_package(context, configuration, package)
+ log "Linking local #{package}...".color(:cyan)
- # Make the top level directory if required:
- destination_path.dirname.create
-
- unless destination_path.exist?
- destination_path.make_symlink(local_path)
- end
- elsif package.external?
- package_lock = nil
-
- unless @options[:unlock]
- package_lock = lock_store.transaction(true){|store| store[package.name]}
- end
+ local_path = context.root + package.options[:local]
- log "Fetching #{package}...".color(:cyan)
+ # Where we are going to put the package:
+ destination_path = package.path
- base_uri = URI(package.options[:source].to_s)
+ # Make the top level directory if required:
+ destination_path.dirname.create
- if base_uri.scheme == nil || base_uri.scheme == 'file'
- base_uri = URI "file://" + File.expand_path(base_uri.path, context.root) + "/"
- end
+ unless destination_path.exist?
+ destination_path.make_symlink(local_path)
+ end
+ end
- branch = package.options.fetch(:version, 'master')
+ def clone_or_pull_package(context, configuration, package, package_lock)
+ log "Fetching #{package}...".color(:cyan)
- if package_lock
- log "Package locked to commit: #{package_lock[:branch]}/#{package_lock[:commit]}"
+ # Where we are going to put the package:
+ destination_path = package.path
- branch = package_lock[:branch]
- end
+ base_uri = URI(package.options[:source].to_s)
- commit = package_lock ? package_lock[:commit] : nil
+ if base_uri.scheme == nil || base_uri.scheme == 'file'
+ base_uri = URI "file://" + File.expand_path(base_uri.path, context.root) + "/"
+ end
- unless destination_path.exist?
- log "Cloning package at path #{destination_path} ...".color(:cyan)
-
- begin
- external_url = package.external_url(context.root)
+ branch = package.options.fetch(:branch, 'master')
- Repository.new(destination_path).clone!(external_url, branch, commit)
- rescue
- log "Failed to clone #{external_url}...".color(:red)
+ if package_lock
+ log "Package locked to commit: #{package_lock[:branch]}/#{package_lock[:commit]}"
- raise
- end
- else
- log "Updating package at path #{destination_path} ...".color(:cyan)
+ branch = package_lock[:branch]
+ end
- commit = package_lock ? package_lock[:commit] : nil
- Repository.new(destination_path).update(branch, commit)
+ commit = package_lock ? package_lock[:commit] : nil
+
+ unless destination_path.exist?
+ log "Cloning package at path #{destination_path} ...".color(:cyan)
+
+ begin
+ external_url = package.external_url(context.root)
+
+ Repository.new(destination_path).clone!(external_url, branch, commit)
+ rescue
+ log "Failed to clone #{external_url}...".color(:red)
+
+ raise
end
+ else
+ log "Updating package at path #{destination_path} ...".color(:cyan)
+
+ commit = package_lock ? package_lock[:commit] : nil
+ Repository.new(destination_path).update(branch, commit)
+ end
+ end
+
+ def fetch_package(context, configuration, package, update: false, local: false)
+ if package.local?
+ link_local_package(context, configuration, package)
+ elsif package.external?
+ lock_store = configuration.lock_store
+ # If we are updating, don't bother reading the current branch/commit details.
+ unless update
+ package_lock = lock_store.transaction(true){|store| store[package.name]}
+ end
+
+ unless local
+ clone_or_pull_package(context, configuration, package, package_lock)
+ end
+
# Lock the package, unless it was already locked:
unless package_lock
+ metadata = current_metadata(package)
+
lock_store.transaction do |store|
- store[package.name] = {
- :branch => branch,
- :commit => current_commit(package)
- }
+ store_metadata = store[package.name]
+
+ if store_metadata.nil? or store_metadata[:commit] != metadata[:commit]
+ log("Updating lockfile for package #{package.name}: #{metadata[:commit]}...")
+ store[package.name] = metadata
+ end
end
end
end
end
end