require "English" require "tempfile" require "svn/error" require "svn/util" require "svn/delta" require "svn/ext/fs" module Svn module Fs Util.set_constants(Ext::Fs, self) Util.set_methods(Ext::Fs, self) @@fs_pool = Svn::Core::Pool.new Fs.initialize(@@fs_pool) class << self def modules print_modules("") end end FileSystem = SWIG::TYPE_p_svn_fs_t class FileSystem class << self def create(path, config) Fs.create(path, config) end def delete(path) Fs.delete_fs(path) end def open(path, config) Fs.open(path, config) end alias new open def hotcopy(src, dest, clean=false) Fs.hotcopy(src, dest, clean) end end def set_warning_func(&func) Fs.set_warning_func_wrapper(self, func) end def path Fs.path(self) end def open_txn(name) Fs.open_txn(self, name) end def purge_txn(id) Fs.purge_txn(self, id) end def transaction(rev=nil, flags=0) txn = Fs.begin_txn2(self, rev || youngest_rev, flags) if block_given? yield(txn) txn.commit if transactions.include?(txn.name) else txn end end def youngest_rev Fs.youngest_rev(self) end def prop(name, rev=nil) value = Fs.revision_prop(self, rev || youngest_rev, name) if value and name == Svn::Core::PROP_REVISION_DATE Time.parse_svn_format(value) else value end end def set_prop(name, value, rev=nil) Fs.change_rev_prop(self, rev || youngest_rev, name, value) end def proplist(rev=nil) list = Fs.revision_proplist(self, rev || youngest_rev) date_str = list[Svn::Core::PROP_REVISION_DATE] if date_str list[Svn::Core::PROP_REVISION_DATE] = Time.parse_svn_format(date_str) end list end def transactions Fs.list_transactions(self) end def root(rev=nil) Fs.revision_root(self, rev || youngest_rev) end def access Fs.get_access(self) end def access=(new_access) Fs.set_access(self, new_access) end def deltify_revision(rev=nil) Fs.deltify_revision(self, rev || youngest_rev) end def uuid Fs.get_uuid(self) end def uuid=(new_uuid) Fs.set_uuid(self, new_uuid) end def lock(path, token=nil, comment=nil, dav_comment=true, expiration_date=nil, current_rev=nil, steal_lock=false) if expiration_date expiration_date = expiration_date.to_apr_time else expiration_date = 0 end current_rev ||= youngest_rev Fs.lock(self, path, token, comment, dav_comment, expiration_date, current_rev, steal_lock) end def unlock(path, token, break_lock=false) Fs.unlock(self, path, token, break_lock) end def generate_lock_token Fs.generate_lock_token(self) end def get_lock(path) Fs.get_lock(self, path) end def get_locks(path) locks = [] receiver = Proc.new do |lock| locks << lock yield(lock) if block_given? end Fs.get_locks(self, path, receiver) locks end def history(path, start_rev, end_rev, cross_copies=true, authz_read_func=nil) hist = [] history_func = Proc.new do |path, revision| yield(path, revision) if block_given? hist << [path, revision] end Repos.history2(self, path, history_func, authz_read_func, start_rev, end_rev, cross_copies) hist end def trace_node_locations(fs_path, location_revisions, peg_rev=nil, &authz_read_func) peg_rev ||= youngest_rev Repos.trace_node_locations(self, fs_path, peg_rev, location_revisions, authz_read_func) end end Access = SWIG::TYPE_p_svn_fs_access_t class Access class << self def new(username) Fs.create_access(username) end end def username Fs.access_get_username(self) end def add_lock_token(token) Fs.access_add_lock_token(self, token) end end Transaction = SWIG::TYPE_p_svn_fs_txn_t class Transaction def name Fs.txn_name(self) end def prop(name) value = Fs.txn_prop(self, name) if name == Svn::Core::PROP_REVISION_DATE and value value = Time.parse_svn_format(value) end value end def set_prop(name, value, validate=true) if validate Repos.fs_change_txn_prop(self, name, value) else Fs.change_txn_prop(self, name, value) end end def base_revision Fs.txn_base_revision(self) end def root Fs.txn_root(self) end def proplist list = Fs.txn_proplist(self) date_str = list[Svn::Core::PROP_REVISION_DATE] if list[Svn::Core::PROP_REVISION_DATE] list[Svn::Core::PROP_REVISION_DATE] = Time.parse_svn_format(date_str) end list end def abort Fs.abort_txn(self) end def commit result = Fs.commit_txn(self) if result.is_a?(Array) result else [nil, result] end end end Root = SWIG::TYPE_p_svn_fs_root_t class Root attr_reader :editor def dir?(path) Fs.is_dir(self, path) end def file?(path) Fs.is_file(self, path) end def revision Fs.revision_root_revision(self) end def name Fs.txn_root_name(self) end def fs Fs.root_fs_wrapper(self) end def node_id(path) Fs.node_id(self, path) end def node_created_rev(path) Fs.node_created_rev(self, path) end def node_created_path(path) Fs.node_created_path(self, path) end def node_prop(path, key) Fs.node_prop(self, path, key) end def set_node_prop(path, key, value, validate=true) if validate Repos.fs_change_node_prop(self, path, key, value) else Fs.change_node_prop(self, path, key, value) end end def node_proplist(path) Fs.node_proplist(self, path) end alias node_prop_list node_proplist def check_path(path) Fs.check_path(self, path) end def file_length(path) Fs.file_length(self, path) end def file_md5_checksum(path) Fs.file_md5_checksum(self, path) end def file_contents(path) stream = Fs.file_contents(self, path) if block_given? begin yield stream ensure stream.close end else stream end end def close Fs.close_root(self) end def dir_entries(path) entries = {} Fs.dir_entries(self, path).each do |name, entry| entries[name] = entry end entries end def dir_delta(src_path, src_entry, tgt_root, tgt_path, editor, text_deltas=false, recurse=true, entry_props=false, ignore_ancestry=false, &authz_read_func) Repos.dir_delta(self, src_path, src_entry, tgt_root, tgt_path, editor, authz_read_func, text_deltas, recurse, entry_props, ignore_ancestry) end def replay(editor, base_dir=nil, low_water_mark=nil, send_deltas=false, &callback) base_dir ||= "" low_water_mark ||= Core::INVALID_REVNUM Repos.replay2(self, base_dir, low_water_mark, send_deltas, editor, callback) end def copied_from(path) Fs.copied_from(self, path) end def txn_root? Fs.is_txn_root(self) end def revision_root? Fs.is_revision_root(self) end def paths_changed Fs.paths_changed(self) end def node_history(path) Fs.node_history(self, path) end def props_changed?(path1, root2, path2) Fs.props_changed(self, path1, root2, path2) end def merge(target_path, source_root, source_path, ancestor_root, ancestor_path) Fs.merge(source_root, source_path, self, target_path, ancestor_root, ancestor_path) end def make_dir(path) Fs.make_dir(self, path) end def delete(path) Fs.delete(self, path) end def copy(to_path, from_root, from_path) Fs.copy(from_root, from_path, self, to_path) end def revision_link(from_root, path) Fs.revision_link(from_root, self, path) end def make_file(path) Fs.make_file(self, path) end def apply_textdelta(path, base_checksum=nil, result_checksum=nil) handler, handler_baton = Fs.apply_textdelta(self, path, base_checksum, result_checksum) handler.baton = handler_baton handler end def apply_text(path, result_checksum=nil) Fs.apply_text(self, path, result_checksum) end def contents_changed?(path1, root2, path2) Fs.contents_changed(self, path1, root2, path2) end def file_delta_stream(source_root, source_path, target_path) Fs.get_file_delta_stream(source_root, source_path, self, target_path) end def stat(path) Repos.stat(self, path) end def committed_info(path) rev, date, author = Repos.get_committed_info(self, path) date = Time.parse_svn_format(date) if date [rev, date, author] end def closest_copy(path) Fs.closest_copy(self, path) end end History = SWIG::TYPE_p_svn_fs_history_t class History def location Fs.history_location(self) end def prev(cross_copies=true) Fs.history_prev(self, cross_copies) end end DirectoryEntry = Dirent Id = SWIG::TYPE_p_svn_fs_id_t class Id def to_s unparse end def unparse Fs.unparse_id(self) end def compare(other) Fs.compare_ids(self, other) end def related?(other) Fs.check_related(self, other) end end class PathChange def modify? change_kind == Svn::Fs::PATH_CHANGE_MODIFY end def add? change_kind == Svn::Fs::PATH_CHANGE_ADD end def text_mod? text_mod end end class FileDiff def initialize(root1, path1, root2, path2) @tempfile1 = nil @tempfile2 = nil @binary = nil @root1 = root1 @path1 = path1 @root2 = root2 @path2 = path2 end def binary? if @binary.nil? @binary = _binary?(@root1, @path1) @binary ||= _binary?(@root2, @path2) end @binary end def files if @tempfile1 [@tempfile1, @tempfile2] else @tempfile1 = Tempfile.new("svn_fs") @tempfile2 = Tempfile.new("svn_fs") dump_contents(@tempfile1, @root1, @path1) dump_contents(@tempfile2, @root2, @path2) [@tempfile1, @tempfile2] end end def diff files @diff ||= Core::Diff.file_diff(@tempfile1.path, @tempfile2.path) end def unified(label1, label2) if diff and diff.diff? diff.unified(label1, label2) else "" end end private def dump_contents(tempfile, root, path) if root and path begin tempfile.open root.file_contents(path) do |stream| tempfile.print(stream.read) end ensure tempfile.close end end end def _binary?(root, path) if root and path prop = root.node_prop(path, Core::PROP_MIME_TYPE) prop and Core.binary_mime_type?(prop) end end end end end