Class: SvnWc::RepoAccess
- Inherits:
-
Object
- Object
- SvnWc::RepoAccess
- Defined in:
- lib/svn_wc.rb
Overview
class that provides API to (common) svn operations (working copy of a repo) also exposes the svn ruby bindings directly
It aims to provide (simple) client CLI type behavior, for working directory repository management. in an API
Constant Summary collapse
- VERSION =
'0.0.6'
Instance Attribute Summary collapse
-
#ctx ⇒ Object
readonly
Returns the value of attribute ctx.
-
#cur_file ⇒ Object
– TODO revist these ++.
-
#force_checkout ⇒ Object
– TODO revist these ++.
-
#repos ⇒ Object
readonly
Returns the value of attribute repos.
-
#svn_pass ⇒ Object
– TODO revist these ++.
-
#svn_repo_config_file ⇒ Object
– TODO revist these ++.
-
#svn_repo_config_path ⇒ Object
– TODO revist these ++.
-
#svn_repo_master ⇒ Object
– TODO revist these ++.
-
#svn_repo_working_copy ⇒ Object
– TODO revist these ++.
-
#svn_user ⇒ Object
– TODO revist these ++.
Instance Method Summary collapse
-
#add(files = [], recurse = true, force = false, no_ignore = false) ⇒ Object
add entities to the repo.
-
#checkout ⇒ Object
(also: #co)
checkout.
-
#commit(files = [], msg = '') ⇒ Object
(also: #ci)
commit entities to the repository.
-
#delete(files = [], recurs = false) ⇒ Object
(also: #rm)
delete entities from the repository.
-
#diff(file = '', rev1 = '', rev2 = '') ⇒ Object
By Default compares current working directory file with ‘HEAD’ in repository (NOTE: does not yet support diff to previous revisions) – TODO support diffing previous revisions ++.
- #do_checkout(force = false) ⇒ Object
-
#info(file = nil) ⇒ Object
get detailed repository info about a specific file or (by default) the entire repository – TODO - document all the params available from this command ++.
-
#initialize(conf = nil, checkout = false, force = false) ⇒ RepoAccess
constructor
initialization three optional parameters 1.
-
#list(wc_path = self.svn_repo_working_copy, rev = 'head', verbose = nil, depth = 'infinity') ⇒ Object
(also: #ls)
list (ls).
-
#list_entries(dir = self.svn_repo_working_copy, file = nil, verbose = false) ⇒ Object
Get list of all entries at (passed) dir level in repo use repo root if nothing passed .
-
#method_missing(sym, *args, &block) ⇒ Object
‘expose the abstraction’ introduce Delegation, if we don’t define the method pass it on to the ruby bindings.
-
#propset(type, files, dir_path = self.svn_repo_working_copy) ⇒ Object
currently supports type=‘ignore’ only – TODO support other propset’s ; also propget ++.
-
#revert(file_path = '') ⇒ Object
discard working copy changes, get current repository entry.
-
#set_conf(conf) ⇒ Object
set config file with abs path.
-
#setup_auth_baton(auth_baton) ⇒ Object
:nodoc:.
-
#status(path = '') ⇒ Object
(also: #stat)
get status on dir/file path.
-
#svn_session(commit_msg = String.new) ⇒ Object
svn session set up – from svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/test/util.rb ++.
-
#update(paths = []) ⇒ Object
(also: #up)
update local working copy with most recent (remote) repo version (does not resolve conflict - or alert or anything at the moment).
Constructor Details
#initialize(conf = nil, checkout = false, force = false) ⇒ RepoAccess
initialization three optional parameters
-
Path to yaml conf file (default used, if none specified)
-
Do a checkout from remote svn repo (usually, necessary with first time set up only)
-
Force. Overwrite anything that may be preventing a checkout
144 145 146 147 148 149 150 |
# File 'lib/svn_wc.rb', line 144 def initialize(conf=nil, checkout=false, force=false) set_conf(conf) if conf do_checkout(force) if checkout == true # instance var of out open repo session @ctx = svn_session end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object
‘expose the abstraction’ introduce Delegation, if we don’t define the method pass it on to the ruby bindings.
– (yup, this is probably asking for trouble) ++
161 162 163 |
# File 'lib/svn_wc.rb', line 161 def method_missing(sym, *args, &block) @ctx.send sym, *args, &block end |
Instance Attribute Details
#ctx ⇒ Object (readonly)
Returns the value of attribute ctx.
172 173 174 |
# File 'lib/svn_wc.rb', line 172 def ctx @ctx end |
#cur_file ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def cur_file @cur_file end |
#force_checkout ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def force_checkout @force_checkout end |
#repos ⇒ Object (readonly)
Returns the value of attribute repos.
172 173 174 |
# File 'lib/svn_wc.rb', line 172 def repos @repos end |
#svn_pass ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def svn_pass @svn_pass end |
#svn_repo_config_file ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def svn_repo_config_file @svn_repo_config_file end |
#svn_repo_config_path ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def svn_repo_config_path @svn_repo_config_path end |
#svn_repo_master ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def svn_repo_master @svn_repo_master end |
#svn_repo_working_copy ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def svn_repo_working_copy @svn_repo_working_copy end |
#svn_user ⇒ Object
– TODO revist these ++
168 169 170 |
# File 'lib/svn_wc.rb', line 168 def svn_user @svn_user end |
Instance Method Details
#add(files = [], recurse = true, force = false, no_ignore = false) ⇒ Object
add entities to the repo
pass a single entry or list of file(s) with fully qualified path, which must exist,
raises RepoAccessError if something goes wrong
– “svn/client.rb” Svn::Client
def add(path, recurse=true, force=false, no_ignore=false)
Client.add3(path, recurse, force, no_ignore, self)
end
++
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/svn_wc.rb', line 284 def add(files=[], recurse=true, force=false, no_ignore=false) # TODO make sure args are what is expected for all methods raise ArgumentError, 'files is empty' unless files svn_session() do |svn| begin files.each do |ef| svn.add(ef, recurse, force, no_ignore) end #rescue Svn::Error::ENTRY_EXISTS, # Svn::Error::AuthnNoProvider, # #Svn::Error::WcNotDirectory, # Svn::Error::SvnError => e rescue Exception => excp raise RepoAccessError, "Add Failed: #{excp.}" end end end |
#checkout ⇒ Object Also known as: co
checkout
create a local working copy of a remote svn repo (creates dir if not exist) raises RepoAccessError if something goes wrong
229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/svn_wc.rb', line 229 def checkout begin svn_session() do |ctx| ctx.checkout(@svn_repo_master, @svn_repo_working_copy) end #rescue Svn::Error::RaLocalReposOpenFailed, # Svn::Error::FsAlreadyExists, #rescue Errno::EACCES => e rescue Exception => err raise RepoAccessError, err. end end |
#commit(files = [], msg = '') ⇒ Object Also known as: ci
commit entities to the repository
params single or list of files (full relative path (to repo root) needed)
optional message
raises RepoAccessError if something goes wrong returns the revision of the commmit
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/svn_wc.rb', line 340 def commit(files=[], msg='') if files and files.empty? or files.nil? then files = self.svn_repo_working_copy end rev = '' svn_session(msg) do |svn| begin rev = svn.commit(files).revision #rescue Svn::Error::AuthnNoProvider, # #Svn::Error::WcNotDirectory, # Svn::Error::IllegalTarget, # #Svn::Error::EntryNotFound => e # Exception => e rescue Exception => err raise RepoAccessError, "Commit Failed: #{err.}" end end rev end |
#delete(files = [], recurs = false) ⇒ Object Also known as: rm
delete entities from the repository
pass single entity or list of files with fully qualified path, which must exist,
raises RepoAccessError if something goes wrong
313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/svn_wc.rb', line 313 def delete(files=[], recurs=false) svn_session() do |svn| begin svn.delete(files) #rescue Svn::Error::AuthnNoProvider, # #Svn::Error::WcNotDirectory, # Svn::Error::ClientModified, # Svn::Error::SvnError => e rescue Exception => err raise RepoAccessError, "Delete Failed: #{err.}" end end end |
#diff(file = '', rev1 = '', rev2 = '') ⇒ Object
By Default compares current working directory file with ‘HEAD’ in repository (NOTE: does not yet support diff to previous revisions) – TODO support diffing previous revisions ++
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
# File 'lib/svn_wc.rb', line 831 def diff(file='', rev1='', rev2='') raise ArgumentError, 'file list empty or nil' unless file and file.size raise RepoAccessError, "Diff requires an absolute path to a file" \ unless File.exists? file # can also use new (updated) svn.status(f)[0][:repo_rev] rev = info(file)[:rev] out_file = Tempfile.new("svn_diff") err_file = Tempfile.new("svn_diff") svn_session() do |svn| begin svn.diff([], file, rev, file, "WORKING", out_file.path, err_file.path) rescue Exception => e #Svn::Error::EntryNotFound => e raise RepoAccessError, "Diff Failed: #{e.}" end end out_file.readlines end |
#do_checkout(force = false) ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/svn_wc.rb', line 193 def do_checkout(force=false) if @svn_repo_working_copy.nil? raise RepoAccessError, 'conf file not loaded! - Fatal Error' end ## do checkout if not exists at specified local path if force or @force_checkout begin FileUtils.rm_rf @svn_repo_working_copy FileUtils.mkdir_p @svn_repo_working_copy rescue Errno::EACCES => err raise RepoAccessError, err. end else if File.directory? @svn_repo_working_copy raise RepoAccessError, 'target local directory ' << \ "[#{@svn_repo_working_copy}] exists, please remove" << \ 'or specify another directory' end begin FileUtils.mkdir_p @svn_repo_working_copy rescue Errno::EACCES => err raise RepoAccessError, err. end end checkout end |
#info(file = nil) ⇒ Object
get detailed repository info about a specific file or (by default) the entire repository – TODO - document all the params available from this command ++
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 |
# File 'lib/svn_wc.rb', line 750 def info(file=nil) wc_path = self.svn_repo_working_copy wc_path = file if file and file.class == String r_info = Hash.new type_info = %w( last_changed_author last_changed_rev last_changed_date conflict_old repos_root_url repos_root_URL copyfrom_rev copyfrom_url conflict_wrk conflict_new has_wc_info repos_UUID checksum prop_time text_time prejfile schedule taguri lock rev dup url URL ) # changelist depth size tree_conflict working_size begin @ctx.info(wc_path) do |path, type| type_info.each do |t_info| r_info[:"#{t_info}"] = type.method(:"#{t_info}").call end end #rescue Svn::Error::WcNotDirectory => e # #Svn::Error::RaIllegalUrl, # #Svn::Error::EntryNotFound, # #Svn::Error::RaIllegalUrl, # #Svn::Error::WC_NOT_DIRECTORY # #Svn::Error::WcNotDirectory => e rescue Exception => e raise RepoAccessError, "cant get info: #{e.}" end r_info end |
#list(wc_path = self.svn_repo_working_copy, rev = 'head', verbose = nil, depth = 'infinity') ⇒ Object Also known as: ls
list (ls)
list all entries at (passed) dir level in repo use repo root if not specified
no repo/file info is returned, just a list of files, with abs_path
optional
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'lib/svn_wc.rb', line 591 def list(wc_path=self.svn_repo_working_copy, rev='head', verbose=nil, depth='infinity') paths = [] svn_session() do |svn| begin svn.list(wc_path, rev, verbose, depth) do |path, dirent, lock, abs_path| #paths.push(path.empty? ? abs_path : File.join(abs_path, path)) f_rec = Hash.new f_rec[:entry] = path f_rec[:last_changed_rev] = dirent.created_rev paths.push f_rec end #rescue Svn::Error::AuthnNoProvider, # #Svn::Error::WcNotDirectory, # Svn::Error::FS_NO_SUCH_REVISION, # #Svn::Error::EntryNotFound => e # Exception => e rescue Exception => e raise RepoAccessError, "List Failed: #{e.}" end end paths end |
#list_entries(dir = self.svn_repo_working_copy, file = nil, verbose = false) ⇒ Object
Get list of all entries at (passed) dir level in repo use repo root if nothing passed
params [String, String, String] optional params, defaults to repo root
if file passed, get specifics on file, else get
into on all in dir path passed
3rd arg is verbose flag, if set to true, lot's
more info is returned about the object
returns [Array] list of entries in svn repository
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 |
# File 'lib/svn_wc.rb', line 643 def list_entries(dir=self.svn_repo_working_copy, file=nil, verbose=false) @entry_list, @show, @verbose = [], true, verbose Svn::Wc::AdmAccess.open(nil, dir, false, 5) do |adm| @adm = adm if file.nil? #also see walk_entries (in svn bindings) has callback adm.read_entries.keys.sort.each { |ef| next unless ef.length >= 1 svn_entry = File.join(dir, ef) _collect_get_entry_info svn_entry } else _collect_get_entry_info(file) end end #XXX do we want nil or empty on no entries, choosing empty for now #@entry_list unless @entry_list.empty? @entry_list end |
#propset(type, files, dir_path = self.svn_repo_working_copy) ⇒ Object
currently supports type=‘ignore’ only – TODO support other propset’s ; also propget ++
856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
# File 'lib/svn_wc.rb', line 856 def propset(type, files, dir_path=self.svn_repo_working_copy) raise RepoAccessError, 'currently, "ignore" is the only supported propset' \ unless type == 'ignore' svn_session() do |svn| files.each do |ef| begin svn.propset(Svn::Core::PROP_IGNORE, ef, dir_path) rescue Exception => e #Svn::Error::EntryNotFound => e raise RepoAccessError, "Propset (Ignore) Failed: #{e.}" end end end end |
#revert(file_path = '') ⇒ Object
discard working copy changes, get current repository entry
821 822 823 824 |
# File 'lib/svn_wc.rb', line 821 def revert(file_path='') if file_path.empty? then file_path = self.svn_repo_working_copy end svn_session() { |svn| svn.revert(file_path) } end |
#set_conf(conf) ⇒ Object
set config file with abs path
177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/svn_wc.rb', line 177 def set_conf(conf) begin conf = load_conf(conf) @svn_user = conf['svn_user'] @svn_pass = conf['svn_pass'] @force_checkout = conf['force_checkout'] @svn_repo_master = conf['svn_repo_master'] @svn_repo_working_copy = conf['svn_repo_working_copy'] @svn_repo_config_path = conf['svn_repo_config_path'] Svn::Core::Config.ensure(@svn_repo_config_path) rescue Exception => e raise RepoAccessError, 'errors loading conf file' end end |
#setup_auth_baton(auth_baton) ⇒ Object
:nodoc:
907 908 909 910 |
# File 'lib/svn_wc.rb', line 907 def setup_auth_baton(auth_baton) # :nodoc: auth_baton[Svn::Core::AUTH_PARAM_CONFIG_DIR] = @svn_repo_config_path auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = @svn_user end |
#status(path = '') ⇒ Object Also known as: stat
get status on dir/file path.
if nothing passed, does repo root
– TODO/XXX add optional param to return results as a data structure (current behavior) or as a puts ‘M’ File (like the CLI version, have the latter as the default, this avoids the awkward s.status(file)[:status] notation one could just say: s.status file and get the list displayed on stdout ++
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
# File 'lib/svn_wc.rb', line 480 def status(path='') raise ArgumentError, 'path not a String' if ! (path or path.class == String) if path and path.empty? then path = self.svn_repo_working_copy end status_info = Hash.new if File.file?(path) # is single file path file = path status_info = do_status(File.dirname(path), file) elsif File.directory?(path) status_info = do_status(path) else raise RepoAccessError, "Arg is not a file or directory" end status_info end |
#svn_session(commit_msg = String.new) ⇒ Object
svn session set up – from svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/test/util.rb ++
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 |
# File 'lib/svn_wc.rb', line 876 def svn_session(commit_msg = String.new) # :nodoc: ctx = Svn::Client::Context.new # Function for commit messages ctx.set_log_msg_func do |items| [true, commit_msg] end # don't fail on non CA signed ssl server ctx.add_ssl_server_trust_file_provider setup_auth_baton(ctx.auth_baton) ctx.add_username_provider # username and password ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save| cred.username = @svn_user cred.password = @svn_pass cred.may_save = false end return ctx unless block_given? begin yield ctx #ensure # warning!? # ctx.destroy end end |
#update(paths = []) ⇒ Object Also known as: up
update local working copy with most recent (remote) repo version (does not resolve conflict - or alert or anything at the moment)
if nothing passed, does repo root
params optional: single or list of files (full relative path (to repo root) needed)
raises RepoAccessError if something goes wrong
alias up
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/svn_wc.rb', line 372 def update(paths=[]) if paths.empty? paths = self.svn_repo_working_copy else @limit_to_dir_path = paths end #XXX update is a bummer, just returns the rev num, not affected files #(svn command line up, also returns altered/new files - mimic that) # hence our inplace hack (_pre/_post update_entries) # # unfortunetly, we cant use 'Repos', only works on local filesystem repo # (NOT remote) #p Svn::Repos.open(@svn_repo_master) # Svn::Repos.open('/tmp/svnrepo') _pre_update_entries rev = String.new svn_session() do |svn| begin #p svn.status paths rev = svn.update(paths, nil, 'infinity') #rescue Svn::Error::AuthnNoProvider, # #Svn::Error::FS_NO_SUCH_REVISION, # #Svn::Error::WcNotDirectory, # #Svn::Error::EntryNotFound => e rescue Exception => err raise RepoAccessError, "Update Failed: #{err.}" end end _post_update_entries return rev, @modified_entries end |