lib/fig/repository.rb in fig-0.1.67 vs lib/fig/repository.rb in fig-0.1.69
- old
+ new
@@ -1,29 +1,28 @@
+require 'fileutils'
require 'set'
require 'socket'
require 'sys/admin'
require 'tmpdir'
require 'fig'
require 'fig/at_exit'
-require 'fig/command'
require 'fig/logging'
require 'fig/not_found_error'
require 'fig/package_cache'
require 'fig/package_descriptor'
require 'fig/parser'
require 'fig/repository_error'
-require 'fig/statement/archive'
-require 'fig/statement/resource'
-require 'fig/url_access_error'
+require 'fig/repository_package_publisher'
module Fig; end
# Overall management of a repository. Handles local operations itself;
# defers remote operations to others.
class Fig::Repository
METADATA_SUBDIRECTORY = '_meta'
+ PACKAGE_FILE_IN_REPO = '.fig'
RESOURCES_FILE = 'resources.tar.gz'
VERSION_FILE_NAME = 'repository-format-version'
VERSION_SUPPORTED = 1
def self.is_url?(url)
@@ -32,17 +31,17 @@
def initialize(
os,
local_repository_directory,
application_config,
- remote_repository_user,
+ publish_listeners,
check_include_versions
)
@operating_system = os
@local_repository_directory = local_repository_directory
@application_config = application_config
- @remote_repository_user = remote_repository_user
+ @publish_listeners = publish_listeners
@parser = Fig::Parser.new(application_config, check_include_versions)
initialize_local_repository()
reset_cached_data()
@@ -121,42 +120,35 @@
FileUtils.rm_rf(local_dir_for_package(descriptor))
return
end
- def publish_package(package_statements, descriptor, local_only)
+ def publish_package(
+ package_statements, descriptor, local_only, source_package, was_forced
+ )
check_local_repository_format()
if not local_only
check_remote_repository_format()
end
- validate_asset_names(package_statements)
+ publisher = Fig::RepositoryPackagePublisher.new
+ publisher.operating_system = @operating_system
+ publisher.publish_listeners = @publish_listeners
+ publisher.package_statements = package_statements
+ publisher.descriptor = descriptor
+ publisher.source_package = source_package
+ publisher.was_forced = was_forced
+ publisher.base_temp_dir = base_temp_dir
+ publisher.local_dir_for_package = local_dir_for_package(descriptor)
+ publisher.remote_dir_for_package = remote_dir_for_package(descriptor)
+ publisher.local_only = local_only
+ publisher.local_fig_file_for_package =
+ local_fig_file_for_package(descriptor)
+ publisher.remote_fig_file_for_package =
+ remote_fig_file_for_package(descriptor)
- temp_dir = publish_temp_dir()
- @operating_system.delete_and_recreate_directory(temp_dir)
- local_dir = local_dir_for_package(descriptor)
- @operating_system.delete_and_recreate_directory(local_dir)
- fig_file = File.join(temp_dir, PACKAGE_FILE_IN_REPO)
- content = publish_package_content_and_derive_dot_fig_contents(
- package_statements, descriptor, local_dir, local_only
- )
- @operating_system.write(fig_file, content)
-
- if not local_only
- @operating_system.upload(
- fig_file,
- remote_fig_file_for_package(descriptor),
- @remote_repository_user
- )
- end
- @operating_system.copy(
- fig_file, local_fig_file_for_package(descriptor)
- )
-
- FileUtils.rm_rf(temp_dir)
-
- return true
+ return publisher.publish_package()
end
def update_unconditionally()
@update_condition = :unconditionally
end
@@ -165,16 +157,12 @@
@update_condition = :if_missing
end
private
- PACKAGE_FILE_IN_REPO = '.fig'
-
def initialize_local_repository()
- if not File.exist?(@local_repository_directory)
- Dir.mkdir(@local_repository_directory)
- end
+ FileUtils.mkdir_p(@local_repository_directory)
version_file = local_version_file()
if not File.exist?(version_file)
File.open(version_file, 'w') { |handle| handle.write(VERSION_SUPPORTED) }
end
@@ -259,35 +247,10 @@
end
return version_string.to_i()
end
- def validate_asset_names(package_statements)
- asset_statements = package_statements.select { |s| s.is_asset? }
-
- asset_names = Set.new()
- asset_statements.each do
- |statement|
-
- asset_name = statement.asset_name()
- if not asset_name.nil?
- if asset_name == RESOURCES_FILE
- Fig::Logging.fatal \
- %Q<You cannot have an asset with the name "#{RESOURCES_FILE}"#{statement.position_string()} due to Fig implementation details.>
- end
-
- if asset_names.include?(asset_name)
- Fig::Logging.fatal \
- %Q<Found multiple archives with the name "#{asset_name}"#{statement.position_string()}. If these were allowed, archives would overwrite each other.>
- raise Fig::RepositoryError.new
- else
- asset_names.add(asset_name)
- end
- end
- end
- end
-
def remote_repository_url()
return @application_config.remote_repository_url()
end
def should_update?(descriptor)
@@ -324,16 +287,20 @@
return
end
def install_package(descriptor, temp_dir)
+ remote_fig_file = remote_fig_file_for_package(descriptor)
+ local_dir = local_dir_for_package(descriptor)
+ local_fig_file = fig_file_for_package_download(local_dir)
+ return if not @operating_system.download(remote_fig_file, local_fig_file)
+
@operating_system.delete_and_recreate_directory(temp_dir)
- remote_fig_file = remote_fig_file_for_package(descriptor)
- local_fig_file = fig_file_for_package_download(temp_dir)
+ temp_fig_file = fig_file_for_package_download(temp_dir)
- return if not @operating_system.download(remote_fig_file, local_fig_file)
+ @operating_system.download(remote_fig_file, temp_fig_file)
package = read_package_from_directory(temp_dir, descriptor)
package.archive_urls.each do |archive_url|
if not Fig::Repository.is_url?(archive_url)
@@ -347,37 +314,17 @@
remote_dir_for_package(descriptor) + '/' + resource_url
end
@operating_system.download_resource(resource_url, temp_dir)
end
- local_dir = local_dir_for_package(descriptor)
FileUtils.rm_rf(local_dir)
FileUtils.mkdir_p( File.dirname(local_dir) )
FileUtils.mv(temp_dir, local_dir)
return
end
- # 'resources' is an Array of fileglob patterns: ['tmp/foo/file1',
- # 'tmp/foo/*.jar']
- def expand_globs_from(resources)
- expanded_files = []
-
- resources.each do
- |path|
-
- globbed_files = Dir.glob(path)
- if globbed_files.empty?
- expanded_files << path
- else
- expanded_files.concat(globbed_files)
- end
- end
-
- return expanded_files
- end
-
def read_package_from_directory(directory, descriptor)
dot_fig_file = File.join(directory, PACKAGE_FILE_IN_REPO)
if not File.exist?(dot_fig_file)
Fig::Logging.fatal %Q<Fig file not found for package "#{descriptor.name || '<unnamed>'}". There is nothing in "#{dot_fig_file}".>
raise Fig::RepositoryError.new
@@ -430,14 +377,10 @@
def base_temp_dir()
File.join(@local_repository_directory, 'tmp')
end
- def publish_temp_dir()
- File.join(base_temp_dir(), 'publish')
- end
-
def package_download_temp_dir(descriptor)
base_directory = File.join(base_temp_dir(), 'package-download')
FileUtils.mkdir_p(base_directory)
return Dir.mktmpdir(
@@ -445,164 +388,7 @@
)
end
def package_missing?(descriptor)
not File.exist?(local_fig_file_for_package(descriptor))
- end
-
- def publish_package_content_and_derive_dot_fig_contents(
- package_statements, descriptor, local_dir, local_only
- )
- header_strings = derive_package_metadata_comments(
- package_statements, descriptor
- )
- deparsed_statement_strings = publish_package_content(
- package_statements, descriptor, local_dir, local_only
- )
-
- statement_strings = [header_strings, deparsed_statement_strings].flatten()
- return statement_strings.join("\n").gsub(/\n{3,}/, "\n\n").strip() + "\n"
- end
-
- def derive_package_metadata_comments(package_statements, descriptor)
- now = Time.now()
-
- asset_statements =
- package_statements.select { |statement| statement.is_asset? }
- asset_strings =
- asset_statements.collect { |statement| statement.unparse('# ') }
- asset_summary = nil
-
- if asset_strings.empty?
- asset_summary = [
- %q<#>,
- %q<# There were no asset statements in the unpublished package definition.>
- ]
- else
- asset_summary = [
- %q<#>,
- %q<# Original asset statements: >,
- %q<#>,
- asset_strings
- ]
- end
-
- return [
- %Q<# Publishing information for #{descriptor.to_string()}:>,
- %q<#>,
- %Q<# Time: #{now} (epoch: #{now.to_i()})>,
- %Q<# User: #{Sys::Admin.get_login()}>,
- %Q<# Host: #{Socket.gethostname()}>,
- %Q<# Args: "#{ARGV.join %q[", "]}">,
- %Q<# Fig: v#{Fig::VERSION}>,
- asset_summary,
- %Q<\n>,
- ].flatten()
- end
-
- # Deals with Archive and Resource statements. It downloads any remote
- # files (those where the statement references a URL as opposed to a local
- # file) and then copies all files into the local repository and the remote
- # repository (if not a local-only publish).
- #
- # Returns the deparsed strings for the resource statements with URLs
- # replaced with in-package paths.
- def publish_package_content(
- package_statements, descriptor, local_dir, local_only
- )
- return create_resource_archive(package_statements).map do |statement|
- if statement.is_asset?
- asset_name = statement.asset_name()
- asset_remote = "#{remote_dir_for_package(descriptor)}/#{asset_name}"
-
- if Fig::Repository.is_url?(statement.url)
- asset_local = File.join(publish_temp_dir(), asset_name)
-
- begin
- @operating_system.download(statement.url, asset_local)
- rescue Fig::NotFoundError
- Fig::Logging.fatal "Could not download #{statement.url}."
- raise Fig::RepositoryError.new
- end
- else
- asset_local = statement.url
- check_asset_path(asset_local)
- end
-
- if not local_only
- @operating_system.upload(
- asset_local, asset_remote, @remote_repository_user
- )
- end
-
- @operating_system.copy(asset_local, local_dir + '/' + asset_name)
- if statement.is_a?(Fig::Statement::Archive)
- @operating_system.unpack_archive(local_dir, asset_name)
- end
-
- statement.class.new(nil, nil, asset_name).unparse('')
- else
- statement.unparse('')
- end
- end
- end
-
- # Grabs all of the Resource statements that don't reference URLs, creates a
- # "resources.tar.gz" file containing all the referenced files, strips the
- # Resource statements out of the statements, replacing them with a single
- # Archive statement. Thus the caller should substitute its set of
- # statements with the return value.
- def create_resource_archive(package_statements)
- asset_paths = []
- new_package_statements = package_statements.reject do |statement|
- if (
- statement.is_a?(Fig::Statement::Resource) &&
- ! Fig::Repository.is_url?(statement.url)
- )
- asset_paths << statement.url
- true
- else
- false
- end
- end
-
- if asset_paths.size > 0
- asset_paths = expand_globs_from(asset_paths)
- check_asset_paths(asset_paths)
-
- file = RESOURCES_FILE
- @operating_system.create_archive(file, asset_paths)
- new_package_statements.unshift(
- Fig::Statement::Archive.new(nil, nil, file)
- )
- Fig::AtExit.add { File.delete(file) }
- end
-
- return new_package_statements
- end
-
- def check_asset_path(asset_path)
- if not File.exist?(asset_path)
- Fig::Logging.fatal "Could not find file #{asset_path}."
- raise Fig::RepositoryError.new
- end
-
- return
- end
-
- def check_asset_paths(asset_paths)
- non_existing_paths =
- asset_paths.select {|path| ! File.exist?(path) && ! File.symlink?(path) }
-
- if not non_existing_paths.empty?
- if non_existing_paths.size > 1
- Fig::Logging.fatal "Could not find files: #{ non_existing_paths.join(', ') }"
- else
- Fig::Logging.fatal "Could not find file #{non_existing_paths[0]}."
- end
-
- raise Fig::RepositoryError.new
- end
-
- return
end
end