lib/pairtree.rb in pairtree-0.0.0 vs lib/pairtree.rb in pairtree-0.1.0
- old
+ new
@@ -1,7 +1,78 @@
require 'pairtree/identifier'
require 'pairtree/path'
require 'pairtree/obj'
require 'pairtree/root'
-require 'pairtree/client'
+
+require 'fileutils'
+
module Pairtree
+ class IdentifierError < Exception; end
+ class PathError < Exception; end
+ class VersionMismatch < Exception; end
+
+ SPEC_VERSION = 0.1
+
+ ##
+ # Instantiate a pairtree at a given path location
+ # @param [String] path The path in which the pairtree resides
+ # @param [Hash] args Pairtree options
+ # @option args [String] :prefix (nil) the identifier prefix used throughout the pairtree
+ # @option args [String] :version (Pairtree::SPEC_VERSION) the version of the pairtree spec that this tree conforms to
+ # @option args [Boolean] :create (false) if true, create the pairtree and its directory structure if it doesn't already exist
+ def self.at path, args = {}
+ args = { :prefix => nil, :version => nil, :create => false }.merge(args)
+ args[:version] ||= SPEC_VERSION
+ args[:version] = args[:version].to_f
+
+ root_path = File.join(path, 'pairtree_root')
+ prefix_file = File.join(path, 'pairtree_prefix')
+ version_file = File.join(path, pairtree_version_filename(args[:version]))
+ existing_version_file = Dir[File.join(path, "pairtree_version*")].sort.last
+
+ if args.delete(:create)
+ if File.exists?(path) and not File.directory?(path)
+ raise PathError, "#{path} exists, but is not a valid pairtree root"
+ end
+ FileUtils.mkdir_p(root_path)
+
+ unless File.exists? prefix_file
+ File.open(prefix_file, 'w') { |f| f.write(args[:prefix].to_s) }
+ end
+
+ if existing_version_file
+ if existing_version_file != version_file
+ stored_version = existing_version_file.scan(/([0-9]+)_([0-9]+)/).flatten.join('.').to_f
+ raise VersionMismatch, "Version #{args[:version]} specified, but #{stored_version} found."
+ end
+ else
+ args[:version] ||= SPEC_VERSION
+ version_file = File.join(path, pairtree_version_filename(args[:version]))
+ File.open(version_file, 'w') { |f| f.write %{This directory conforms to Pairtree Version #{args[:version]}. Updated spec: http://www.cdlib.org/inside/diglib/pairtree/pairtreespec.html} }
+ existing_version_file = version_file
+ end
+ else
+ unless File.directory? root_path
+ raise PathError, "#{path} does not point to an existing pairtree"
+ end
+ end
+
+ stored_prefix = File.read(prefix_file)
+ unless args[:prefix].nil? or args[:prefix].to_s == stored_prefix
+ raise IdentifierError, "Specified prefix #{args[:prefix].inspect} does not match stored prefix #{stored_prefix.inspect}"
+ end
+ args[:prefix] = stored_prefix
+
+ stored_version = existing_version_file.scan(/([0-9]+)_([0-9]+)/).flatten.join('.').to_f
+ args[:version] ||= stored_version
+ unless args[:version] == stored_version
+ raise VersionMismatch, "Version #{args[:version]} specified, but #{stored_version} found."
+ end
+
+ Pairtree::Root.new(File.join(path, 'pairtree_root'), args)
+ end
+
+ private
+ def self.pairtree_version_filename(version)
+ "pairtree_version#{version.to_s.gsub(/\./,'_')}"
+ end
end