diff --git a/.gitignore b/.gitignore index d411dd7f..13456823 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.pyc pkg/ *.cache +TAGS diff --git a/lib/scm.rb b/lib/scm.rb index 60b014c8..5252dcef 100644 --- a/lib/scm.rb +++ b/lib/scm.rb @@ -19,6 +19,7 @@ module Scm require 'lib/scm/adapters/hglib_adapter' require 'lib/scm/adapters/bzr_adapter' require 'lib/scm/adapters/bzrlib_adapter' +require 'lib/scm/adapters/darcs_adapter' require 'lib/scm/adapters/factory' require 'lib/scm/parsers/parser' @@ -32,6 +33,7 @@ module Scm require 'lib/scm/parsers/hg_styled_parser' require 'lib/scm/parsers/bzr_xml_parser' require 'lib/scm/parsers/bzr_parser' +require 'lib/scm/parsers/darcs_parser' require 'lib/scm/parsers/array_writer' require 'lib/scm/parsers/xml_writer' diff --git a/lib/scm/adapters/darcs/cat_file.rb b/lib/scm/adapters/darcs/cat_file.rb new file mode 100644 index 00000000..6157ad8a --- /dev/null +++ b/lib/scm/adapters/darcs/cat_file.rb @@ -0,0 +1,28 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + def cat_file(commit, diff) + cat(commit.token, diff.path) + end + + def cat_file_parent(commit, diff) + p = parent_tokens(commit) + cat(p.first, diff.path) if p.first + end + + def cat(revision, path) + out, err = run_with_err("cd '#{url}' && darcs show contents -p '#{revision}' #{escape(path)}") + # show contents gives no error for non-existent paths + #return nil if err =~ /No such file in rev/ + raise RuntimeError.new(err) unless err.to_s == '' + return nil if out == '' + out + end + + # Escape bash-significant characters in the filename + # Example: + # "Foo Bar & Baz" => "Foo\ Bar\ \&\ Baz" + def escape(path) + path.gsub(/[ '"&()<>|]/) { |c| '\\' + c } + end + end +end diff --git a/lib/scm/adapters/darcs/commits.rb b/lib/scm/adapters/darcs/commits.rb new file mode 100644 index 00000000..306cb31e --- /dev/null +++ b/lib/scm/adapters/darcs/commits.rb @@ -0,0 +1,87 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + + # Return the number of commits in the repository following +since+. + def commit_count(since=nil) + commit_tokens(since).size + end + + # Return the list of commit tokens following +since+. + def commit_tokens(since=nil, up_to=nil) + from = since ? " --from-patch #{since}" : "" + to = up_to ? " --to-patch #{up_to}" : "" + tokens = string_to_patch_names(run("cd '#{self.url}' && darcs changes#{from}#{to}")).reverse + + # Darcs returns everything after *and including* since. + # We want to exclude it. + if tokens.any? && tokens.first == since + tokens[1..-1] + else + tokens + end + end + + # Returns a list of shallow commits (i.e., the diffs are not populated). + # Not including the diffs is meant to be a memory savings when we encounter massive repositories. + # If you need all commits including diffs, you should use the each_commit() iterator, which only holds one commit + # in memory at a time. + def commits(since=nil) + from = since ? " --from-patch #{since}" : "" + log = run("cd '#{self.url}' && darcs changes#{from} --reverse") + a = Scm::Parsers::DarcsParser.parse(log) + if a.any? && a.first.token == since + a[1..-1] + else + a + end + end + + # Returns a single commit, including its diffs + def verbose_commit(token) + log = run("cd '#{self.url}' && darcs changes -v -p '#{token}'") + Scm::Parsers::DarcsParser.parse(log).first + end + + # Yields each commit after +since+, including its diffs. + # The log is stored in a temporary file. + # This is designed to prevent excessive RAM usage when we encounter a massive repository. + # Only a single commit is ever held in memory at once. + def each_commit(since=nil) + open_log_file(since) do |io| + Scm::Parsers::DarcsParser.parse(io) do |commit| + yield commit if block_given? && commit.token != since + end + end + end + + # Not used by Ohloh proper, but handy for debugging and testing + def log(since=nil) + from = since ? " --from-patch #{since}" : "" + run "cd '#{url}' && darcs changes -s#{from}" + end + + # Returns a file handle to the log. + # In our standard, the log should include everything AFTER +since+. However, darcs doesn't work that way; + # it returns everything after and INCLUDING +since+. Therefore, consumers of this file should check for + # and reject the duplicate commit. + def open_log_file(since=nil) + begin + if since == head_token # There are no new commits + # As a time optimization, just create an empty file rather than fetch a log we know will be empty. + File.open(log_filename, 'w') { } + else + from = since ? " --from-patch #{since}" : "" + run "cd '#{url}' && darcs changes --reverse -v#{from} > #{log_filename}" + end + File.open(log_filename, 'r') { |io| yield io } + ensure + File.delete(log_filename) if FileTest.exist?(log_filename) + end + end + + def log_filename + File.join('/tmp', (self.url).gsub(/\W/,'') + '.log') + end + + end +end diff --git a/lib/scm/adapters/darcs/head.rb b/lib/scm/adapters/darcs/head.rb new file mode 100644 index 00000000..5ef26701 --- /dev/null +++ b/lib/scm/adapters/darcs/head.rb @@ -0,0 +1,23 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + def head_token + string_to_patch_names(run("cd '#{url}' && darcs changes --last 1"))[0] + end + + def head + verbose_commit(head_token) + end + + def parent_tokens(commit) + string_to_patch_names(run("cd '#{url}' && darcs changes --to-patch #{commit.token}"))[1..-1] + end + + def parents(commit) + parent_tokens(commit).map {|token| verbose_commit(token)} + end + + def string_to_patch_names(s) + s.split(/\n/).select {|s| s =~ /^ \* /}.map {|s| s.sub(/^ \* /,'')} + end + end +end diff --git a/lib/scm/adapters/darcs/misc.rb b/lib/scm/adapters/darcs/misc.rb new file mode 100644 index 00000000..aaabb31d --- /dev/null +++ b/lib/scm/adapters/darcs/misc.rb @@ -0,0 +1,21 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + def exist? + begin + !!(head_token) + rescue + logger.debug { $! } + false + end + end + + def ls_tree(token) + run("cd '#{path}' && darcs show files -p '#{token}'").split("\n") + end + + def export(dest_dir, token=nil) + p = token ? " -p '#{token}'" : "" + run("cd '#{path}' && darcs dist#{p} && mv darcs.tar.gz '#{dest_dir}'") + end + end +end diff --git a/lib/scm/adapters/darcs/patch.rb b/lib/scm/adapters/darcs/patch.rb new file mode 100644 index 00000000..ec3a624e --- /dev/null +++ b/lib/scm/adapters/darcs/patch.rb @@ -0,0 +1,7 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + def patch_for_commit(commit) + run("cd '#{url}' && darcs changes -p'#{commit.token}' -v") + end + end +end diff --git a/lib/scm/adapters/darcs/pull.rb b/lib/scm/adapters/darcs/pull.rb new file mode 100644 index 00000000..299ebf23 --- /dev/null +++ b/lib/scm/adapters/darcs/pull.rb @@ -0,0 +1,23 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + + def pull(from, &block) + raise ArgumentError.new("Cannot pull from #{from.inspect}") unless from.is_a?(DarcsAdapter) + logger.info { "Pulling #{from.url}" } + + yield(0,1) if block_given? # Progress bar callback + + unless self.exist? + run "mkdir -p '#{self.url}'" + run "rm -rf '#{self.url}'" + run "darcs get '#{from.url}' '#{self.url}'" + else + # might also need to unpull for an exact copy + run "cd '#{self.url}' && darcs revert --all && darcs pull --dont-allow-conflicts -a '#{from.url}'" + end + + yield(1,1) if block_given? # Progress bar callback + end + + end +end diff --git a/lib/scm/adapters/darcs/push.rb b/lib/scm/adapters/darcs/push.rb new file mode 100644 index 00000000..1988a4d7 --- /dev/null +++ b/lib/scm/adapters/darcs/push.rb @@ -0,0 +1,50 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + + def push(to, &block) + raise ArgumentError.new("Cannot push to #{to.inspect}") unless to.is_a?(DarcsAdapter) + logger.info { "Pushing to #{to.url}" } + + yield(0,1) if block_given? # Progress bar callback + + unless to.exist? + if to.local? + # Create a new repo on the same local machine. Just use existing pull code in reverse. + to.pull(self) + else + run "cd '#{self.url}' && darcs put #{to.hostname}:#{to.path}" + end + else + run "cd '#{self.url}' && darcs push -a '#{to.url}'" + end + + yield(1,1) if block_given? # Progress bar callback + end + + def local? + return true if hostname == Socket.gethostname + return true if url =~ /^file:\/\// + return true if url !~ /:/ + false + end + + def hostname + $1 if url =~ /^ssh:\/\/([^\/]+)/ + end + + def path + case url + when /^file:\/\/(.+)$/ + $1 + when /^ssh:\/\/[^\/]+(\/.+)$/ + $1 + when /^[^:]*$/ + url + end + end + + def darcs_path + path && File.join(path, '.darcs') + end + end +end diff --git a/lib/scm/adapters/darcs/validation.rb b/lib/scm/adapters/darcs/validation.rb new file mode 100644 index 00000000..e265f6ef --- /dev/null +++ b/lib/scm/adapters/darcs/validation.rb @@ -0,0 +1,26 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + def self.url_regex + /^((http|https|ssh|file):\/\/((\w+@)?[A-Za-z0-9_\-\.]+(:\d+)?\/)?)?[A-Za-z0-9_\-\.\/\~\+]*$/ + end + + def self.public_url_regex + /^(http|https):\/\/(\w+@)?[A-Za-z0-9_\-\.]+(:\d+)?\/[A-Za-z0-9_\-\.\/\~\+]*$/ + end + + def validate_server_connection + return unless valid? + @errors << [:failed, "The server did not respond to the 'darcs id' command. Is the URL correct?"] unless self.exist? + end + + def guess_forge + u = @url =~ /:\/\/(.*\.?darcs\.)?([^\/^:]+)(:\d+)?\// ? $2 : nil + case u + when /(sourceforge\.net$)/ + $1 + else + u + end + end + end +end diff --git a/lib/scm/adapters/darcs_adapter.rb b/lib/scm/adapters/darcs_adapter.rb new file mode 100644 index 00000000..58ab0aed --- /dev/null +++ b/lib/scm/adapters/darcs_adapter.rb @@ -0,0 +1,16 @@ +module Scm::Adapters + class DarcsAdapter < AbstractAdapter + def english_name + "Darcs" + end + end +end + +require 'lib/scm/adapters/darcs/validation' +require 'lib/scm/adapters/darcs/cat_file' +require 'lib/scm/adapters/darcs/commits' +require 'lib/scm/adapters/darcs/misc' +require 'lib/scm/adapters/darcs/pull' +require 'lib/scm/adapters/darcs/push' +require 'lib/scm/adapters/darcs/head' +require 'lib/scm/adapters/darcs/patch' diff --git a/lib/scm/adapters/factory.rb b/lib/scm/adapters/factory.rb index b9e1e661..6d8fa41c 100644 --- a/lib/scm/adapters/factory.rb +++ b/lib/scm/adapters/factory.rb @@ -11,6 +11,9 @@ def self.from_path(path) elsif FileTest.exist?(File.join(path, '.hg')) HgAdapter.new(:url => File.expand_path(path)).normalize + elsif FileTest.exist?(File.join(path, '_darcs')) + DarcsAdapter.new(:url => File.expand_path(path)).normalize + elsif FileTest.exist?(File.join(path, '.bzr')) BzrAdapter.new(:url => File.expand_path(path)).normalize diff --git a/lib/scm/commit.rb b/lib/scm/commit.rb index ddb9fa13..55a0a546 100644 --- a/lib/scm/commit.rb +++ b/lib/scm/commit.rb @@ -15,6 +15,8 @@ module Scm # the near future, it is the job of the adapter to make the Git commit chain # appear as much like a single array as possible. # + # For Darcs, it is assumed the repo's patch ordering is never changed. + # class Commit # This object supports the idea of distinct authors and committers, a la # Git. However, Ohloh will retain only one of them in its database. It @@ -32,6 +34,7 @@ class Commit # For Git, the token is the commit SHA1 hash. # For CVS, which does not support atomic commits with unique IDs, we use # the approximate timestamp of the change. + # For Darcs, the token is the patch name, and it may not be unique. XXX attr_accessor :token # A pointer back to the adapter that contains this commit. diff --git a/lib/scm/parsers/darcs_parser.rb b/lib/scm/parsers/darcs_parser.rb new file mode 100644 index 00000000..286dec88 --- /dev/null +++ b/lib/scm/parsers/darcs_parser.rb @@ -0,0 +1,80 @@ +module Scm::Parsers + # This parser can process the default darcs changes output #, with or without the --verbose flag. + class DarcsParser < Parser + def self.scm + 'darcs' + end + + def self.internal_parse(buffer, opts) + e = nil + state = :patch + + buffer.each_line do |l| + #print "\n#{state}" + next_state = state + if state == :patch + case l + when /^([^ ]...........................) (.*)$/ + yield e if e && block_given? + e = Scm::Commit.new + e.author_date = Time.parse($1).utc + nameemail = $2 + case nameemail + when /^([^<]*) <(.*)>$/ + e.author_name = $1 + e.author_email = $2 + when /^([^@]*)$/ + e.author_name = $1 + e.author_email = nil + else + e.author_name = nil + e.author_email = nameemail + end + e.diffs = [] + when /^ \* (.*)/ + e.token = ($1 || '') + next_state = :long_comment_or_prims + end + + elsif state == :long_comment_or_prims + case l + when /^ addfile\s+(.+)/ + e.diffs << Scm::Diff.new(:action => 'A', :path => $1) + next_state = :prims + when /^ rmfile\s+(.+)/ + e.diffs << Scm::Diff.new(:action => 'D', :path => $1) + next_state = :prims + when /^ hunk\s+(.+)\s+([0-9]+)$/ + e.diffs << Scm::Diff.new(:action => 'M', :path => $1) + # e.sha1, e.parent_sha1 = ... + next_state = :prims + when /^$/ + next_state = :patch + else + e.message ||= '' + e.message << l.sub(/^ /,'') + end + + elsif state == :prims + case l + when /^ addfile\s+(.+)/ + e.diffs << Scm::Diff.new(:action => 'A', :path => $1) + when /^ rmfile\s+(.+)/ + e.diffs << Scm::Diff.new(:action => 'D', :path => $1) + when /^ hunk\s+(.+)\s+([0-9]+)$/ + e.diffs << Scm::Diff.new(:action => 'M', :path => $1) + # e.sha1, e.parent_sha1 = ... + when /^$/ + next_state = :patch + else + # ignore hunk details + end + + end + state = next_state + end + yield e if e && block_given? + end + + end +end diff --git a/test/data/darcs_patch.diff b/test/data/darcs_patch.diff new file mode 100644 index 00000000..f5316e68 --- /dev/null +++ b/test/data/darcs_patch.diff @@ -0,0 +1,16 @@ +Wed Nov 3 15:49:53 PDT 2010 Simon Michael + * add helloworld.c + addfile ./helloworld.c + hunk ./helloworld.c 1 + +/* Hello, World! */ + + + +/* + + * This file is not covered by any license, especially not + + * the GNU General Public License (GPL). Have fun! + + */ + + + +#include + +main() + +{ + + printf("Hello, World!\\n"); + +} diff --git a/test/repositories/darcs/_darcs/.gitattributes b/test/repositories/darcs/_darcs/.gitattributes new file mode 100644 index 00000000..bd2de00c --- /dev/null +++ b/test/repositories/darcs/_darcs/.gitattributes @@ -0,0 +1 @@ +* -text -whitespace diff --git a/test/repositories/darcs/_darcs/format b/test/repositories/darcs/_darcs/format new file mode 100644 index 00000000..58f777b5 --- /dev/null +++ b/test/repositories/darcs/_darcs/format @@ -0,0 +1,2 @@ +hashed +darcs-2 diff --git a/test/repositories/darcs/_darcs/hashed_inventory b/test/repositories/darcs/_darcs/hashed_inventory new file mode 100644 index 00000000..42dfb941 --- /dev/null +++ b/test/repositories/darcs/_darcs/hashed_inventory @@ -0,0 +1,11 @@ +pristine:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +[add helloworld.c +Simon Michael **20101103224953 + Ignore-this: 3861470344267bb74c710a8dad01e92a +] +hash: 0000000370-0f1c03b7cad1276d35b5230fe1f1d19c1432b366cc35f7eb06cd311543b4798e +[remove helloworld.c +Simon Michael **20101103225525 + Ignore-this: c54c3cf6bebc6a9545effff28e1c785c +] +hash: 0000000372-afa148a0f1772c96e99321250914ee9ad12c03e18f7acc2e30a9de83fde76a1c diff --git a/test/repositories/darcs/_darcs/index b/test/repositories/darcs/_darcs/index new file mode 100644 index 00000000..f14d6e02 Binary files /dev/null and b/test/repositories/darcs/_darcs/index differ diff --git a/test/repositories/darcs/_darcs/index_invalid b/test/repositories/darcs/_darcs/index_invalid new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs/_darcs/inventories/0000000199-b4681395aad3d7e60338fc52abcb28d37dbbb1776305220bd2fc8ca1df5edea1 b/test/repositories/darcs/_darcs/inventories/0000000199-b4681395aad3d7e60338fc52abcb28d37dbbb1776305220bd2fc8ca1df5edea1 new file mode 100644 index 00000000..66334a7b Binary files /dev/null and b/test/repositories/darcs/_darcs/inventories/0000000199-b4681395aad3d7e60338fc52abcb28d37dbbb1776305220bd2fc8ca1df5edea1 differ diff --git a/test/repositories/darcs/_darcs/inventories/0000000401-3618104098a23625a0ec77c03cde5912cf131713f44fa36d870bd9880f70381c b/test/repositories/darcs/_darcs/inventories/0000000401-3618104098a23625a0ec77c03cde5912cf131713f44fa36d870bd9880f70381c new file mode 100644 index 00000000..f992b1b8 Binary files /dev/null and b/test/repositories/darcs/_darcs/inventories/0000000401-3618104098a23625a0ec77c03cde5912cf131713f44fa36d870bd9880f70381c differ diff --git a/test/repositories/darcs/_darcs/patches/0000000370-0f1c03b7cad1276d35b5230fe1f1d19c1432b366cc35f7eb06cd311543b4798e b/test/repositories/darcs/_darcs/patches/0000000370-0f1c03b7cad1276d35b5230fe1f1d19c1432b366cc35f7eb06cd311543b4798e new file mode 100644 index 00000000..6a9429af Binary files /dev/null and b/test/repositories/darcs/_darcs/patches/0000000370-0f1c03b7cad1276d35b5230fe1f1d19c1432b366cc35f7eb06cd311543b4798e differ diff --git a/test/repositories/darcs/_darcs/patches/0000000372-afa148a0f1772c96e99321250914ee9ad12c03e18f7acc2e30a9de83fde76a1c b/test/repositories/darcs/_darcs/patches/0000000372-afa148a0f1772c96e99321250914ee9ad12c03e18f7acc2e30a9de83fde76a1c new file mode 100644 index 00000000..b4a49fb7 Binary files /dev/null and b/test/repositories/darcs/_darcs/patches/0000000372-afa148a0f1772c96e99321250914ee9ad12c03e18f7acc2e30a9de83fde76a1c differ diff --git a/test/repositories/darcs/_darcs/patches/pending b/test/repositories/darcs/_darcs/patches/pending new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/test/repositories/darcs/_darcs/patches/pending @@ -0,0 +1,2 @@ +{ +} diff --git a/test/repositories/darcs/_darcs/patches/pending.tentative b/test/repositories/darcs/_darcs/patches/pending.tentative new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/test/repositories/darcs/_darcs/patches/pending.tentative @@ -0,0 +1,2 @@ +{ +} diff --git a/test/repositories/darcs/_darcs/prefs/binaries b/test/repositories/darcs/_darcs/prefs/binaries new file mode 100644 index 00000000..ac206487 --- /dev/null +++ b/test/repositories/darcs/_darcs/prefs/binaries @@ -0,0 +1,30 @@ +# This file contains a list of extended regular expressions, one per +# line. A file path matching any of these expressions is assumed to +# contain binary data (not text). The entries in ~/.darcs/binaries (if +# it exists) supplement those in this file. +# +# Blank lines, and lines beginning with an octothorpe (#) are ignored. +# See regex(7) for a description of extended regular expressions. +\.(a|A)$ +\.(bmp|BMP)$ +\.(bz2|BZ2)$ +\.(doc|DOC)$ +\.(elc|ELC)$ +\.(exe|EXE)$ +\.(gif|GIF)$ +\.(gz|GZ)$ +\.(iso|ISO)$ +\.(jar|JAR)$ +\.(jpe?g|JPE?G)$ +\.(mng|MNG)$ +\.(mpe?g|MPE?G)$ +\.(p[nbgp]m|P[NBGP]M)$ +\.(pdf|PDF)$ +\.(png|PNG)$ +\.(pyc|PYC)$ +\.(so|SO)$ +\.(tar|TAR)$ +\.(tgz|TGZ)$ +\.(tiff?|TIFF?)$ +\.(z|Z)$ +\.(zip|ZIP)$ diff --git a/test/repositories/darcs/_darcs/prefs/boring b/test/repositories/darcs/_darcs/prefs/boring new file mode 100644 index 00000000..5969e686 --- /dev/null +++ b/test/repositories/darcs/_darcs/prefs/boring @@ -0,0 +1,113 @@ +# Boring file regexps: + +### compiler and interpreter intermediate files +# haskell (ghc) interfaces +\.hi$ +\.hi-boot$ +\.o-boot$ +# object files +\.o$ +\.o\.cmd$ +# profiling haskell +\.p_hi$ +\.p_o$ +# haskell program coverage resp. profiling info +\.tix$ +\.prof$ +# fortran module files +\.mod$ +# linux kernel +\.ko\.cmd$ +\.mod\.c$ +(^|/)\.tmp_versions($|/) +# *.ko files aren't boring by default because they might +# be Korean translations rather than kernel modules +# \.ko$ +# python, emacs, java byte code +\.py[co]$ +\.elc$ +\.class$ +# objects and libraries; lo and la are libtool things +\.(obj|a|exe|so|lo|la)$ +# compiled zsh configuration files +\.zwc$ +# Common LISP output files for CLISP and CMUCL +\.(fas|fasl|sparcf|x86f)$ + +### build and packaging systems +# cabal intermediates +\.installed-pkg-config +\.setup-config +# standard cabal build dir, might not be boring for everybody +# ^dist(/|$) +# autotools +(^|/)autom4te\.cache($|/) +(^|/)config\.(log|status)$ +# microsoft web expression, visual studio metadata directories +\_vti_cnf$ +\_vti_pvt$ +# gentoo tools +\.revdep-rebuild.* +# generated dependencies +^\.depend$ + +### version control systems +# cvs +(^|/)CVS($|/) +\.cvsignore$ +# cvs, emacs locks +^\.# +# rcs +(^|/)RCS($|/) +,v$ +# subversion +(^|/)\.svn($|/) +# mercurial +(^|/)\.hg($|/) +# git +(^|/)\.git($|/) +# bzr +\.bzr$ +# sccs +(^|/)SCCS($|/) +# darcs +(^|/)_darcs($|/) +(^|/)\.darcsrepo($|/) +^\.darcs-temp-mail$ +-darcs-backup[[:digit:]]+$ +# gnu arch +(^|/)(\+|,) +(^|/)vssver\.scc$ +\.swp$ +(^|/)MT($|/) +(^|/)\{arch\}($|/) +(^|/).arch-ids($|/) +# bitkeeper +(^|/)BitKeeper($|/) +(^|/)ChangeSet($|/) + +### miscellaneous +# backup files +~$ +\.bak$ +\.BAK$ +# patch originals and rejects +\.orig$ +\.rej$ +# X server +\..serverauth.* +# image spam +\# +(^|/)Thumbs\.db$ +# vi, emacs tags +(^|/)(tags|TAGS)$ +#(^|/)\.[^/] +# core dumps +(^|/|\.)core$ +# partial broken files (KIO copy operations) +\.part$ +# waf files, see http://code.google.com/p/waf/ +(^|/)\.waf-[[:digit:].]+-[[:digit:]]+($|/) +(^|/)\.lock-wscript$ +# mac os finder +(^|/)\.DS_Store$ diff --git a/test/repositories/darcs/_darcs/prefs/motd b/test/repositories/darcs/_darcs/prefs/motd new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs/_darcs/pristine.hashed/47fa61da8145efedd19f2df53384c3fd72d5eb0f37c5a1588f151412b65a9552 b/test/repositories/darcs/_darcs/pristine.hashed/47fa61da8145efedd19f2df53384c3fd72d5eb0f37c5a1588f151412b65a9552 new file mode 100644 index 00000000..8f6bee49 Binary files /dev/null and b/test/repositories/darcs/_darcs/pristine.hashed/47fa61da8145efedd19f2df53384c3fd72d5eb0f37c5a1588f151412b65a9552 differ diff --git a/test/repositories/darcs/_darcs/pristine.hashed/4cc3cd16f13015913718f15ed2289ba958415616d46901035ce3a6809034167f b/test/repositories/darcs/_darcs/pristine.hashed/4cc3cd16f13015913718f15ed2289ba958415616d46901035ce3a6809034167f new file mode 100644 index 00000000..cf274f8a Binary files /dev/null and b/test/repositories/darcs/_darcs/pristine.hashed/4cc3cd16f13015913718f15ed2289ba958415616d46901035ce3a6809034167f differ diff --git a/test/repositories/darcs/_darcs/pristine.hashed/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 b/test/repositories/darcs/_darcs/pristine.hashed/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 new file mode 100644 index 00000000..229151a5 Binary files /dev/null and b/test/repositories/darcs/_darcs/pristine.hashed/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 differ diff --git a/test/repositories/darcs/_darcs/tentative_pristine b/test/repositories/darcs/_darcs/tentative_pristine new file mode 100644 index 00000000..a72624e3 --- /dev/null +++ b/test/repositories/darcs/_darcs/tentative_pristine @@ -0,0 +1 @@ +pristine:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/test/repositories/darcs_walk/A b/test/repositories/darcs_walk/A new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/B b/test/repositories/darcs_walk/B new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/C b/test/repositories/darcs_walk/C new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/D b/test/repositories/darcs_walk/D new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/E b/test/repositories/darcs_walk/E new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/_darcs/.gitattributes b/test/repositories/darcs_walk/_darcs/.gitattributes new file mode 100644 index 00000000..bd2de00c --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/.gitattributes @@ -0,0 +1 @@ +* -text -whitespace diff --git a/test/repositories/darcs_walk/_darcs/format b/test/repositories/darcs_walk/_darcs/format new file mode 100644 index 00000000..58f777b5 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/format @@ -0,0 +1,2 @@ +hashed +darcs-2 diff --git a/test/repositories/darcs_walk/_darcs/hashed_inventory b/test/repositories/darcs_walk/_darcs/hashed_inventory new file mode 100644 index 00000000..7f73a4b4 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/hashed_inventory @@ -0,0 +1,26 @@ +pristine:dfd28add8431fa83db5053f9dd26fcb11b14378071e255da2e62c043020d277b +[A +Simon Michael **20101105050558 + Ignore-this: 5bd1c52f9c7bd77d62ea0054db2d270a +] +hash: 0000000112-98b82f6897acae4e8769521a64605d9c72fdbef99dbeedb503c66548052692e0 +[B +Simon Michael **20101105050612 + Ignore-this: 3e8e6c2038387eb0dbabf3264560312f +] +hash: 0000000112-05450bae2857f79ad27b060839eb238e27372a3edd550e0097491168ab71442e +[C +Simon Michael **20101105050616 + Ignore-this: dbcc2fcc273925ffc86fe213e309a8f +] +hash: 0000000111-83b5986061a7166da12083d1fa8d1cb02877bd5d5e041f4cd1781704dabf00c1 +[D +Simon Michael **20101105050618 + Ignore-this: ab9f04d0e28d346d14ca5f5375da7e0b +] +hash: 0000000112-16163f0db6fb931e965e2e41d00b5d43da90be1d5d55540f61d22420172ea0fa +[E +Simon Michael **20101105050621 + Ignore-this: 12c991491d6b5693d3b90622958a985c +] +hash: 0000000112-70c0bf5995cfdf8fbb176f975d8f9b83e0ec3b12df56cdb93cf0bc130c58ce96 diff --git a/test/repositories/darcs_walk/_darcs/index b/test/repositories/darcs_walk/_darcs/index new file mode 100644 index 00000000..a14b0240 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/index differ diff --git a/test/repositories/darcs_walk/_darcs/index_invalid b/test/repositories/darcs_walk/_darcs/index_invalid new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/_darcs/inventories/0000000184-92eef20b519f4ccfe4990dddba010c991016fa3380d0849fb4927ce7d0c329c1 b/test/repositories/darcs_walk/_darcs/inventories/0000000184-92eef20b519f4ccfe4990dddba010c991016fa3380d0849fb4927ce7d0c329c1 new file mode 100644 index 00000000..084626c2 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/inventories/0000000184-92eef20b519f4ccfe4990dddba010c991016fa3380d0849fb4927ce7d0c329c1 differ diff --git a/test/repositories/darcs_walk/_darcs/inventories/0000000368-79230da93a2f69dadf7df4e422c39c3ea9b2a88a4f25efa7378704a9e4080b4c b/test/repositories/darcs_walk/_darcs/inventories/0000000368-79230da93a2f69dadf7df4e422c39c3ea9b2a88a4f25efa7378704a9e4080b4c new file mode 100644 index 00000000..eebb927f Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/inventories/0000000368-79230da93a2f69dadf7df4e422c39c3ea9b2a88a4f25efa7378704a9e4080b4c differ diff --git a/test/repositories/darcs_walk/_darcs/inventories/0000000551-cdd7b8961aeede9a40431b62809cfc1f579d4f0176f3cdc20ca3efc39006d766 b/test/repositories/darcs_walk/_darcs/inventories/0000000551-cdd7b8961aeede9a40431b62809cfc1f579d4f0176f3cdc20ca3efc39006d766 new file mode 100644 index 00000000..b25438ba Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/inventories/0000000551-cdd7b8961aeede9a40431b62809cfc1f579d4f0176f3cdc20ca3efc39006d766 differ diff --git a/test/repositories/darcs_walk/_darcs/inventories/0000000735-c231534c3e7fc9781e71a1a53dee4b0ca052c62ecc6a54a587c4fa15cf756e19 b/test/repositories/darcs_walk/_darcs/inventories/0000000735-c231534c3e7fc9781e71a1a53dee4b0ca052c62ecc6a54a587c4fa15cf756e19 new file mode 100644 index 00000000..7ff9ebc1 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/inventories/0000000735-c231534c3e7fc9781e71a1a53dee4b0ca052c62ecc6a54a587c4fa15cf756e19 differ diff --git a/test/repositories/darcs_walk/_darcs/inventories/0000000919-8b7174beef8c29ca14ae3bb7b68c41fe659b7aa8cebacce52507998aac85fdb2 b/test/repositories/darcs_walk/_darcs/inventories/0000000919-8b7174beef8c29ca14ae3bb7b68c41fe659b7aa8cebacce52507998aac85fdb2 new file mode 100644 index 00000000..76e9f812 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/inventories/0000000919-8b7174beef8c29ca14ae3bb7b68c41fe659b7aa8cebacce52507998aac85fdb2 differ diff --git a/test/repositories/darcs_walk/_darcs/patches/0000000111-83b5986061a7166da12083d1fa8d1cb02877bd5d5e041f4cd1781704dabf00c1 b/test/repositories/darcs_walk/_darcs/patches/0000000111-83b5986061a7166da12083d1fa8d1cb02877bd5d5e041f4cd1781704dabf00c1 new file mode 100644 index 00000000..31b4b2e9 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/patches/0000000111-83b5986061a7166da12083d1fa8d1cb02877bd5d5e041f4cd1781704dabf00c1 differ diff --git a/test/repositories/darcs_walk/_darcs/patches/0000000112-05450bae2857f79ad27b060839eb238e27372a3edd550e0097491168ab71442e b/test/repositories/darcs_walk/_darcs/patches/0000000112-05450bae2857f79ad27b060839eb238e27372a3edd550e0097491168ab71442e new file mode 100644 index 00000000..a9689852 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/patches/0000000112-05450bae2857f79ad27b060839eb238e27372a3edd550e0097491168ab71442e differ diff --git a/test/repositories/darcs_walk/_darcs/patches/0000000112-16163f0db6fb931e965e2e41d00b5d43da90be1d5d55540f61d22420172ea0fa b/test/repositories/darcs_walk/_darcs/patches/0000000112-16163f0db6fb931e965e2e41d00b5d43da90be1d5d55540f61d22420172ea0fa new file mode 100644 index 00000000..5191b93c Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/patches/0000000112-16163f0db6fb931e965e2e41d00b5d43da90be1d5d55540f61d22420172ea0fa differ diff --git a/test/repositories/darcs_walk/_darcs/patches/0000000112-70c0bf5995cfdf8fbb176f975d8f9b83e0ec3b12df56cdb93cf0bc130c58ce96 b/test/repositories/darcs_walk/_darcs/patches/0000000112-70c0bf5995cfdf8fbb176f975d8f9b83e0ec3b12df56cdb93cf0bc130c58ce96 new file mode 100644 index 00000000..18f1a93a Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/patches/0000000112-70c0bf5995cfdf8fbb176f975d8f9b83e0ec3b12df56cdb93cf0bc130c58ce96 differ diff --git a/test/repositories/darcs_walk/_darcs/patches/0000000112-98b82f6897acae4e8769521a64605d9c72fdbef99dbeedb503c66548052692e0 b/test/repositories/darcs_walk/_darcs/patches/0000000112-98b82f6897acae4e8769521a64605d9c72fdbef99dbeedb503c66548052692e0 new file mode 100644 index 00000000..fdb37828 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/patches/0000000112-98b82f6897acae4e8769521a64605d9c72fdbef99dbeedb503c66548052692e0 differ diff --git a/test/repositories/darcs_walk/_darcs/patches/pending b/test/repositories/darcs_walk/_darcs/patches/pending new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/patches/pending @@ -0,0 +1,2 @@ +{ +} diff --git a/test/repositories/darcs_walk/_darcs/patches/pending.tentative b/test/repositories/darcs_walk/_darcs/patches/pending.tentative new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/patches/pending.tentative @@ -0,0 +1,2 @@ +{ +} diff --git a/test/repositories/darcs_walk/_darcs/prefs/binaries b/test/repositories/darcs_walk/_darcs/prefs/binaries new file mode 100644 index 00000000..ac206487 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/prefs/binaries @@ -0,0 +1,30 @@ +# This file contains a list of extended regular expressions, one per +# line. A file path matching any of these expressions is assumed to +# contain binary data (not text). The entries in ~/.darcs/binaries (if +# it exists) supplement those in this file. +# +# Blank lines, and lines beginning with an octothorpe (#) are ignored. +# See regex(7) for a description of extended regular expressions. +\.(a|A)$ +\.(bmp|BMP)$ +\.(bz2|BZ2)$ +\.(doc|DOC)$ +\.(elc|ELC)$ +\.(exe|EXE)$ +\.(gif|GIF)$ +\.(gz|GZ)$ +\.(iso|ISO)$ +\.(jar|JAR)$ +\.(jpe?g|JPE?G)$ +\.(mng|MNG)$ +\.(mpe?g|MPE?G)$ +\.(p[nbgp]m|P[NBGP]M)$ +\.(pdf|PDF)$ +\.(png|PNG)$ +\.(pyc|PYC)$ +\.(so|SO)$ +\.(tar|TAR)$ +\.(tgz|TGZ)$ +\.(tiff?|TIFF?)$ +\.(z|Z)$ +\.(zip|ZIP)$ diff --git a/test/repositories/darcs_walk/_darcs/prefs/boring b/test/repositories/darcs_walk/_darcs/prefs/boring new file mode 100644 index 00000000..5969e686 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/prefs/boring @@ -0,0 +1,113 @@ +# Boring file regexps: + +### compiler and interpreter intermediate files +# haskell (ghc) interfaces +\.hi$ +\.hi-boot$ +\.o-boot$ +# object files +\.o$ +\.o\.cmd$ +# profiling haskell +\.p_hi$ +\.p_o$ +# haskell program coverage resp. profiling info +\.tix$ +\.prof$ +# fortran module files +\.mod$ +# linux kernel +\.ko\.cmd$ +\.mod\.c$ +(^|/)\.tmp_versions($|/) +# *.ko files aren't boring by default because they might +# be Korean translations rather than kernel modules +# \.ko$ +# python, emacs, java byte code +\.py[co]$ +\.elc$ +\.class$ +# objects and libraries; lo and la are libtool things +\.(obj|a|exe|so|lo|la)$ +# compiled zsh configuration files +\.zwc$ +# Common LISP output files for CLISP and CMUCL +\.(fas|fasl|sparcf|x86f)$ + +### build and packaging systems +# cabal intermediates +\.installed-pkg-config +\.setup-config +# standard cabal build dir, might not be boring for everybody +# ^dist(/|$) +# autotools +(^|/)autom4te\.cache($|/) +(^|/)config\.(log|status)$ +# microsoft web expression, visual studio metadata directories +\_vti_cnf$ +\_vti_pvt$ +# gentoo tools +\.revdep-rebuild.* +# generated dependencies +^\.depend$ + +### version control systems +# cvs +(^|/)CVS($|/) +\.cvsignore$ +# cvs, emacs locks +^\.# +# rcs +(^|/)RCS($|/) +,v$ +# subversion +(^|/)\.svn($|/) +# mercurial +(^|/)\.hg($|/) +# git +(^|/)\.git($|/) +# bzr +\.bzr$ +# sccs +(^|/)SCCS($|/) +# darcs +(^|/)_darcs($|/) +(^|/)\.darcsrepo($|/) +^\.darcs-temp-mail$ +-darcs-backup[[:digit:]]+$ +# gnu arch +(^|/)(\+|,) +(^|/)vssver\.scc$ +\.swp$ +(^|/)MT($|/) +(^|/)\{arch\}($|/) +(^|/).arch-ids($|/) +# bitkeeper +(^|/)BitKeeper($|/) +(^|/)ChangeSet($|/) + +### miscellaneous +# backup files +~$ +\.bak$ +\.BAK$ +# patch originals and rejects +\.orig$ +\.rej$ +# X server +\..serverauth.* +# image spam +\# +(^|/)Thumbs\.db$ +# vi, emacs tags +(^|/)(tags|TAGS)$ +#(^|/)\.[^/] +# core dumps +(^|/|\.)core$ +# partial broken files (KIO copy operations) +\.part$ +# waf files, see http://code.google.com/p/waf/ +(^|/)\.waf-[[:digit:].]+-[[:digit:]]+($|/) +(^|/)\.lock-wscript$ +# mac os finder +(^|/)\.DS_Store$ diff --git a/test/repositories/darcs_walk/_darcs/prefs/motd b/test/repositories/darcs_walk/_darcs/prefs/motd new file mode 100644 index 00000000..e69de29b diff --git a/test/repositories/darcs_walk/_darcs/pristine.hashed/33bbdb6496663754302d2c24df905a718c347fc55e0a9e3e84a4cd1cb90afc05 b/test/repositories/darcs_walk/_darcs/pristine.hashed/33bbdb6496663754302d2c24df905a718c347fc55e0a9e3e84a4cd1cb90afc05 new file mode 100644 index 00000000..705f1139 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/pristine.hashed/33bbdb6496663754302d2c24df905a718c347fc55e0a9e3e84a4cd1cb90afc05 differ diff --git a/test/repositories/darcs_walk/_darcs/pristine.hashed/c209c6bd4d6d35c742a5b30b3cc263477c4403af180d2113e0f954fd3869dbda b/test/repositories/darcs_walk/_darcs/pristine.hashed/c209c6bd4d6d35c742a5b30b3cc263477c4403af180d2113e0f954fd3869dbda new file mode 100644 index 00000000..0726896b Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/pristine.hashed/c209c6bd4d6d35c742a5b30b3cc263477c4403af180d2113e0f954fd3869dbda differ diff --git a/test/repositories/darcs_walk/_darcs/pristine.hashed/cb4d350f5064d16bff999069d9f5a8c015a94138d6bd0adb5effd1b6ba4b0ef8 b/test/repositories/darcs_walk/_darcs/pristine.hashed/cb4d350f5064d16bff999069d9f5a8c015a94138d6bd0adb5effd1b6ba4b0ef8 new file mode 100644 index 00000000..19c12c5e Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/pristine.hashed/cb4d350f5064d16bff999069d9f5a8c015a94138d6bd0adb5effd1b6ba4b0ef8 differ diff --git a/test/repositories/darcs_walk/_darcs/pristine.hashed/d35ab98b6586baf33a7ee0b09b85ddcd3543b649d016df0a7c2ca5d0b22fea7c b/test/repositories/darcs_walk/_darcs/pristine.hashed/d35ab98b6586baf33a7ee0b09b85ddcd3543b649d016df0a7c2ca5d0b22fea7c new file mode 100644 index 00000000..e5a5fa87 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/pristine.hashed/d35ab98b6586baf33a7ee0b09b85ddcd3543b649d016df0a7c2ca5d0b22fea7c differ diff --git a/test/repositories/darcs_walk/_darcs/pristine.hashed/dfd28add8431fa83db5053f9dd26fcb11b14378071e255da2e62c043020d277b b/test/repositories/darcs_walk/_darcs/pristine.hashed/dfd28add8431fa83db5053f9dd26fcb11b14378071e255da2e62c043020d277b new file mode 100644 index 00000000..53d9e6f8 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/pristine.hashed/dfd28add8431fa83db5053f9dd26fcb11b14378071e255da2e62c043020d277b differ diff --git a/test/repositories/darcs_walk/_darcs/pristine.hashed/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 b/test/repositories/darcs_walk/_darcs/pristine.hashed/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 new file mode 100644 index 00000000..229151a5 Binary files /dev/null and b/test/repositories/darcs_walk/_darcs/pristine.hashed/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 differ diff --git a/test/repositories/darcs_walk/_darcs/tentative_pristine b/test/repositories/darcs_walk/_darcs/tentative_pristine new file mode 100644 index 00000000..0411d1a5 --- /dev/null +++ b/test/repositories/darcs_walk/_darcs/tentative_pristine @@ -0,0 +1 @@ +pristine:dfd28add8431fa83db5053f9dd26fcb11b14378071e255da2e62c043020d277b diff --git a/test/test_helper.rb b/test/test_helper.rb index 797d2f69..6569ac5a 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -103,5 +103,8 @@ def with_bzr_repository(name) def with_bzrlib_repository(name) with_repository(Scm::Adapters::BzrlibAdapter, name) { |bzr| yield bzr } + + def with_darcs_repository(name) + with_repository(Scm::Adapters::DarcsAdapter, name) { |darcs| yield darcs } end end diff --git a/test/unit/adapter_factory_test.rb b/test/unit/adapter_factory_test.rb index 71e28622..a3f5b3cb 100644 --- a/test/unit/adapter_factory_test.rb +++ b/test/unit/adapter_factory_test.rb @@ -3,6 +3,15 @@ module Scm::Adapters class FactoryTest < Scm::Test + def test_factory_darcs + Scm::ScratchDir.new do |path| + `cd #{path} && darcs init` + darcs = Factory.from_path(path) + assert darcs.is_a?(DarcsAdapter) + assert_equal darcs.url, path + end + end + def test_factory_hg Scm::ScratchDir.new do |path| `cd #{path} && hg init` diff --git a/test/unit/darcs_cat_file_test.rb b/test/unit/darcs_cat_file_test.rb new file mode 100644 index 00000000..714f4beb --- /dev/null +++ b/test/unit/darcs_cat_file_test.rb @@ -0,0 +1,48 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsCatFileTest < Scm::Test + + def test_cat_file + with_darcs_repository('darcs') do |darcs| +expected = <<-EXPECTED +/* Hello, World! */ + +/* + * This file is not covered by any license, especially not + * the GNU General Public License (GPL). Have fun! + */ + +#include +main() +{ + printf("Hello, World!\\\\n"); +} +EXPECTED + + # The file was deleted by the "remove..." patch. Check that it does not exist now, but existed in parent. + assert_equal nil, darcs.cat_file(Scm::Commit.new(:token => 'remove helloworld.c'), Scm::Diff.new(:path => 'helloworld.c')) + assert_equal expected, darcs.cat_file_parent(Scm::Commit.new(:token => 'remove helloworld.c'), Scm::Diff.new(:path => 'helloworld.c')) + assert_equal expected, darcs.cat_file(Scm::Commit.new(:token => 'add helloworld.c'), Scm::Diff.new(:path => 'helloworld.c')) + end + end + + # Ensure that we escape bash-significant characters like ' and & when they appear in the filename + # NB only works with --reserved-ok, otherwise darcs rejects with "invalid under Windows" + def test_funny_file_name_chars + Scm::ScratchDir.new do |dir| + # Make a file with a problematic filename + funny_name = '|file_name (&\'")' + File.open(File.join(dir, funny_name), 'w') { |f| f.write "contents" } + + # Add it to a darcs repository + darcs = DarcsAdapter.new(:url => dir).normalize + darcs.run("cd #{dir} && darcs init && darcs add --reserved-ok * && darcs record -a -m test") + + # Confirm that we can read the file back + assert_equal "contents", darcs.cat_file(darcs.head, Scm::Diff.new(:path => funny_name)) + end + end + + end +end diff --git a/test/unit/darcs_commits_test.rb b/test/unit/darcs_commits_test.rb new file mode 100644 index 00000000..85b3e9c9 --- /dev/null +++ b/test/unit/darcs_commits_test.rb @@ -0,0 +1,45 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsCommitsTest < Scm::Test + + def test_commit + with_darcs_repository('darcs') do |darcs| + assert_equal 2, darcs.commit_count + assert_equal 1, darcs.commit_count('add helloworld.c') + assert_equal 0, darcs.commit_count('remove helloworld.c') + assert_equal ['add helloworld.c', 'remove helloworld.c'], darcs.commit_tokens + assert_equal ['remove helloworld.c'], darcs.commit_tokens('add helloworld.c') + assert_equal [], darcs.commit_tokens('remove helloworld.c') + assert_equal ['add helloworld.c', + 'remove helloworld.c'], darcs.commits.collect { |c| c.token } + assert_equal ['remove helloworld.c'], darcs.commits('add helloworld.c').collect { |c| c.token } + # Check that the diffs are not populated + assert_equal [], darcs.commits('add helloworld.c').first.diffs + assert_equal [], darcs.commits('remove helloworld.c') + end + end + + def test_each_commit + commits = [] + with_darcs_repository('darcs') do |darcs| + darcs.each_commit do |c| + assert c.author_name + assert c.author_date.is_a?(Time) + assert c.diffs.any? + # Check that the diffs are populated + c.diffs.each do |d| + assert d.action =~ /^[MAD]$/ + assert d.path.length > 0 + end + commits << c + end + assert !FileTest.exist?(darcs.log_filename) # Make sure we cleaned up after ourselves + + # Verify that we got the commits in forward chronological order + assert_equal ['add helloworld.c', + 'remove helloworld.c'], commits.map {|c| c.token} + end + end + end +end diff --git a/test/unit/darcs_head_test.rb b/test/unit/darcs_head_test.rb new file mode 100644 index 00000000..05891d48 --- /dev/null +++ b/test/unit/darcs_head_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsHeadTest < Scm::Test + + def test_head_and_parents + with_darcs_repository('darcs') do |darcs| + assert_equal 'remove helloworld.c', darcs.head_token + assert_equal 'remove helloworld.c', darcs.head.token + assert darcs.head.diffs.any? # diffs should be populated + + assert_equal 'add helloworld.c', darcs.parents(darcs.head).first.token + assert darcs.parents(darcs.head).first.diffs.any? + end + end + + end +end diff --git a/test/unit/darcs_misc_test.rb b/test/unit/darcs_misc_test.rb new file mode 100644 index 00000000..231b03a2 --- /dev/null +++ b/test/unit/darcs_misc_test.rb @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsMiscTest < Scm::Test + + def test_exist + save_darcs = nil + with_darcs_repository('darcs') do |darcs| + save_darcs = darcs + assert save_darcs.exist? + end + assert !save_darcs.exist? + end + + def test_ls_tree + with_darcs_repository('darcs') do |darcs| + assert_equal ['.','./helloworld.c'], darcs.ls_tree('add helloworld.c').sort + end + end + + def test_export + with_darcs_repository('darcs') do |darcs| + Scm::ScratchDir.new do |dir| + darcs.export(dir, 'add helloworld.c') + assert_equal ['.', '..', 'darcs.tar.gz'], Dir.entries(dir).sort + end + end + end + + end +end diff --git a/test/unit/darcs_parser_test.rb b/test/unit/darcs_parser_test.rb new file mode 100644 index 00000000..7d691831 --- /dev/null +++ b/test/unit/darcs_parser_test.rb @@ -0,0 +1,128 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Parsers + class DarcsParserTest < Scm::Test + + def test_empty_array + assert_equal([], DarcsParser.parse('')) + end + + def test_log_parser_default +sample_log = < + * remove helloworld.c + +Wed Nov 3 15:49:53 PDT 2010 Simon Michael + * add helloworld.c + +SAMPLE + + commits = DarcsParser.parse(sample_log) + + assert commits + assert_equal 2, commits.size + + assert_equal 'remove helloworld.c', commits[0].token + assert_equal 'Simon Michael', commits[0].author_name + assert_equal 'simon@joyful.com', commits[0].author_email + assert_equal nil, commits[0].message # Note \n at end of comment + assert_equal Time.utc(2010,11,3,22,55,25), commits[0].author_date + assert_equal 0, commits[0].diffs.size + + assert_equal 'add helloworld.c', commits[1].token + assert_equal 'Simon Michael', commits[1].author_name + assert_equal 'simon@joyful.com', commits[1].author_email + assert_equal nil, commits[1].message # Note \n at end of comment + assert_equal Time.utc(2010,11,3,22,49,53), commits[1].author_date + assert_equal 0, commits[1].diffs.size + end + + def test_log_parser_default_partial_user_name +sample_log = < + * remove helloworld.c + hunk ./helloworld.c 1 + -/* Hello, World! */ + - + -/* + - * This file is not covered by any license, especially not + - * the GNU General Public License (GPL). Have fun! + - */ + - + -#include + -main() + -{ + - printf("Hello, World!\\n"); + -} + rmfile ./helloworld.c + +Wed Nov 3 15:49:53 PDT 2010 Simon Michael + * add helloworld.c + addfile ./helloworld.c + hunk ./helloworld.c 1 + +/* Hello, World! */ + + + +/* + + * This file is not covered by any license, especially not + + * the GNU General Public License (GPL). Have fun! + + */ + + + +#include + +main() + +{ + + printf("Hello, World!\\n"); + +} +SAMPLE + + commits = DarcsParser.parse(sample_log) + + assert commits + assert_equal 2, commits.size + + assert_equal 'remove helloworld.c', commits[0].token + assert_equal 'Simon Michael', commits[0].author_name + assert_equal 'simon@joyful.com', commits[0].author_email + assert_equal nil, commits[0].message # Note \n at end of comment + assert_equal Time.utc(2010,11,3,22,55,25), commits[0].author_date + assert_equal 2, commits[0].diffs.size + assert_equal './helloworld.c', commits[0].diffs[0].path + assert_equal './helloworld.c', commits[0].diffs[1].path + + assert_equal 'add helloworld.c', commits[1].token + assert_equal 'Simon Michael', commits[1].author_name + assert_equal 'simon@joyful.com', commits[1].author_email + assert_equal nil, commits[1].message # Note \n at end of comment + assert_equal Time.utc(2010,11,3,22,49,53), commits[1].author_date + assert_equal 2, commits[0].diffs.size + assert_equal './helloworld.c', commits[0].diffs[0].path + assert_equal './helloworld.c', commits[0].diffs[1].path + end + + protected + + end +end diff --git a/test/unit/darcs_patch_test.rb b/test/unit/darcs_patch_test.rb new file mode 100644 index 00000000..578ed3fd --- /dev/null +++ b/test/unit/darcs_patch_test.rb @@ -0,0 +1,13 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsPatchTest < Scm::Test + def test_patch_for_commit + with_darcs_repository('darcs') do |repo| + commit = repo.verbose_commit('add helloworld.c') + data = File.read(File.join(DATA_DIR, 'darcs_patch.diff')) + assert_equal data, repo.patch_for_commit(commit) + end + end + end +end diff --git a/test/unit/darcs_pull_test.rb b/test/unit/darcs_pull_test.rb new file mode 100644 index 00000000..e34f5060 --- /dev/null +++ b/test/unit/darcs_pull_test.rb @@ -0,0 +1,29 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsPullTest < Scm::Test + + def test_pull + with_darcs_repository('darcs') do |src| + Scm::ScratchDir.new do |dest_dir| + + dest = DarcsAdapter.new(:url => dest_dir).normalize + assert !dest.exist? + + dest.pull(src) + assert dest.exist? + + assert_equal src.log, dest.log + + # Commit some new code on the original and pull again + src.run "cd '#{src.url}' && touch foo && darcs add foo && darcs record -a -m test" + assert_equal "test", src.commits.last.token + + dest.pull(src) + assert_equal src.log, dest.log + end + end + end + + end +end diff --git a/test/unit/darcs_push_test.rb b/test/unit/darcs_push_test.rb new file mode 100644 index 00000000..843c8c06 --- /dev/null +++ b/test/unit/darcs_push_test.rb @@ -0,0 +1,59 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsPushTest < Scm::Test + + def test_hostname + assert !DarcsAdapter.new.hostname + assert !DarcsAdapter.new(:url => "http://www.ohloh.net/test").hostname + assert !DarcsAdapter.new(:url => "/Users/robin/foo").hostname + assert_equal "foo", DarcsAdapter.new(:url => 'ssh://foo/bar').hostname + end + + def test_local + assert !DarcsAdapter.new(:url => "foo:/bar").local? # Assuming your machine is not named "foo" :-) + assert !DarcsAdapter.new(:url => "http://www.ohloh.net/foo").local? + assert !DarcsAdapter.new(:url => "ssh://host/Users/robin/src").local? + assert DarcsAdapter.new(:url => "src").local? + assert DarcsAdapter.new(:url => "/Users/robin/src").local? + assert DarcsAdapter.new(:url => "file:///Users/robin/src").local? + assert DarcsAdapter.new(:url => "ssh://#{Socket.gethostname}/Users/robin/src").local? + end + + def test_path + assert_equal nil, DarcsAdapter.new().path + assert_equal nil, DarcsAdapter.new(:url => "http://ohloh.net/foo").path + assert_equal nil, DarcsAdapter.new(:url => "https://ohloh.net/foo").path + assert_equal "/Users/robin/foo", DarcsAdapter.new(:url => "file:///Users/robin/foo").path + assert_equal "/Users/robin/foo", DarcsAdapter.new(:url => "ssh://localhost/Users/robin/foo").path + assert_equal "/Users/robin/foo", DarcsAdapter.new(:url => "/Users/robin/foo").path + end + + def test_darcs_path + assert_equal nil, DarcsAdapter.new().darcs_path + assert_equal "/Users/robin/src/.darcs", DarcsAdapter.new(:url => "/Users/robin/src").darcs_path + end + + def test_push + with_darcs_repository('darcs') do |src| + Scm::ScratchDir.new do |dest_dir| + + dest = DarcsAdapter.new(:url => dest_dir).normalize + assert !dest.exist? + + src.push(dest) + assert dest.exist? + assert_equal src.log, dest.log + + # Commit some new code on the original and pull again + src.run "cd '#{src.url}' && touch foo && darcs add foo && darcs record -a -m test" + assert_equal "test", src.commits.last.token + + src.push(dest) + assert_equal src.log, dest.log + end + end + end + + end +end diff --git a/test/unit/darcs_rev_list_test.rb b/test/unit/darcs_rev_list_test.rb new file mode 100644 index 00000000..849c42f3 --- /dev/null +++ b/test/unit/darcs_rev_list_test.rb @@ -0,0 +1,25 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + # Repository darcs_walk has the following structure: + # + # A -> B -> C -> D -> E + # + class DarcsRevListTest < Scm::Test + + def test_rev_list + with_darcs_repository('darcs_walk') do |darcs| + # Full history to a commit + assert_equal ["A"], darcs.commit_tokens(nil, "A") + assert_equal ["A","B"], darcs.commit_tokens(nil, "B") + assert_equal ["A","B","C","D","E"], darcs.commit_tokens(nil, "E") + assert_equal ["A","B","C","D","E"], darcs.commit_tokens(nil, nil) + + # # Limited history from one commit to another + assert_equal [], darcs.commit_tokens("A", "A") + assert_equal ["B"], darcs.commit_tokens("A", "B") + assert_equal ["B","C","D"], darcs.commit_tokens("A", "D") + end + end + end +end diff --git a/test/unit/darcs_validation_test.rb b/test/unit/darcs_validation_test.rb new file mode 100644 index 00000000..71a664f6 --- /dev/null +++ b/test/unit/darcs_validation_test.rb @@ -0,0 +1,60 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module Scm::Adapters + class DarcsValidationTest < Scm::Test + def test_rejected_urls + [ nil, "", "foo", "http:/", "http:://", "http://", "http://a", + "www.selenic.com/repo/hello", # missing a protool prefix + "http://www.selenic.com/repo/hello%20world", # no encoded strings allowed + "http://www.selenic.com/repo/hello world", # no spaces allowed + "git://www.selenic.com/repo/hello", # git protocol not allowed + "svn://www.selenic.com/repo/hello" # svn protocol not allowed + ].each do |url| + darcs = DarcsAdapter.new(:url => url, :public_urls_only => true) + assert darcs.validate_url.any? + end + end + + def test_accepted_urls + [ "http://www.selenic.com/repo/hello", + "http://www.selenic.com:80/repo/hello", + "https://www.selenic.com/repo/hello", + ].each do |url| + darcs = DarcsAdapter.new(:url => url, :public_urls_only => true) + assert !darcs.validate_url + end + end + + # These urls are not available to the public + def test_rejected_public_urls + [ "file:///home/robin/darcs", + "/home/robin/darcs", + "ssh://robin@localhost/home/robin/darcs", + "ssh://localhost/home/robin/darcs" + ].each do |url| + darcs = DarcsAdapter.new(:url => url, :public_urls_only => true) + assert darcs.validate_url + + darcs = DarcsAdapter.new(:url => url) + assert !darcs.validate_url + end + end + + def test_guess_forge + darcs = DarcsAdapter.new(:url => nil) + assert_equal nil, darcs.guess_forge + + darcs = DarcsAdapter.new(:url => "/home/robin/darcs") + assert_equal nil, darcs.guess_forge + + darcs = DarcsAdapter.new( :url => 'http://www.selenic.com/repo/hello') + assert_equal 'www.selenic.com', darcs.guess_forge + + darcs = DarcsAdapter.new( :url => 'http://algoc.darcs.sourceforge.net:8000/darcsroot/algoc') + assert_equal 'sourceforge.net', darcs.guess_forge + + darcs = DarcsAdapter.new( :url => 'http://poliqarp.sourceforge.net/darcs/poliqarp/') + assert_equal 'sourceforge.net', darcs.guess_forge + end + end +end diff --git a/test/unit/ohlog_command_line_test.rb b/test/unit/ohlog_command_line_test.rb index 2c630d0a..462d4d4f 100644 --- a/test/unit/ohlog_command_line_test.rb +++ b/test/unit/ohlog_command_line_test.rb @@ -27,6 +27,9 @@ def test_svn_xml_from_file def test_hg_from_file end + #def test_darcs_from_file + #end + def test_help result = `#{File.dirname(__FILE__) + '/../../bin/ohlog'} -?` assert_equal 0, $?