darcs-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/gempackagetask'
7
+
8
+ PRG_VERSION = '0.0.1'
9
+ PRG_TEST_FILES = FileList['test/**/*_test.rb']
10
+
11
+ task :default => :test
12
+
13
+ Rake::TestTask.new do |t|
14
+ t.libs << 'lib'
15
+ t.libs << 'test'
16
+ t.test_files = PRG_TEST_FILES
17
+ t.verbose = true
18
+ end
19
+
20
+ Rake::RDocTask.new do |rdoc|
21
+ rdoc.rdoc_dir = 'doc'
22
+ rdoc.title = "Ruby Darcs -- Ruby interface to Darcs change control"
23
+ rdoc.options << '--line-numbers --inline-source'
24
+ rdoc.rdoc_files.include("lib/**/*.rb")
25
+ end
26
+
27
+ gem_spec = Gem::Specification.new do |s|
28
+ s.platform = Gem::Platform::RUBY
29
+ s.name = 'darcs-ruby'
30
+ s.summary = "Interface to Darcs change control system"
31
+ s.version = PRG_VERSION
32
+ s.author = "Jason M. Felice"
33
+ s.email = "jfelice@cronosys.com"
34
+ s.homepage = "http://eraserhead.net/darcs/darcs-ruby/doc/"
35
+ s.has_rdoc = true
36
+ s.files = FileList["lib/**/*", "test/**/*", "Rakefile", "bin/*"]
37
+ s.test_files = PRG_TEST_FILES
38
+ s.bindir = 'bin'
39
+ s.executables = [ 'darcs-import' ]
40
+ end
41
+
42
+ Rake::GemPackageTask.new(gem_spec) do |p|
43
+ p.need_tar = true
44
+ p.need_zip = true
45
+ end
46
+
47
+ task :install => :package do
48
+ sh 'gem install ./pkg/darcs-ruby-0.0.1.gem'
49
+ end
50
+
51
+ # vi:set sts=2 sw=2 ai et:
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # = darcs-import
4
+ #
5
+ # Script to start a large repository from a source tree. This script takes
6
+ # shortcuts because darcs' apparent run time for recording patches is O(n^2)
7
+ #
8
+
9
+ # Enable us to run from the source tree
10
+ $:.push(File.join(File.dirname(File.dirname(__FILE__)),'lib'))
11
+
12
+ require 'rubygems'
13
+ require 'darcs/repository'
14
+ require 'darcs/patchinfo'
15
+ require 'darcs/patchwriter'
16
+ require 'find'
17
+
18
+ include Darcs
19
+
20
+ repo = Repository.find
21
+ if repo.nil?
22
+ system 'darcs initialize'
23
+ repo = Repository.find
24
+ elsif repo.patches.count > 0
25
+ raise "Must be used on an empty repository!"
26
+ end
27
+
28
+ raise "Set $EMAIL first!" if !ENV['EMAIL']
29
+ patch_info = PatchInfo.new(Time.now, 'Initial import', ENV['EMAIL'])
30
+ repo.write_patch(patch_info) do |writer|
31
+ Find.find('.') do |entry|
32
+ next if entry == '.'
33
+ next if repo.boring?(entry)
34
+ Find.prune if !FileTest.directory?(entry)
35
+ writer << Chunk::AddDirectory.new(entry)
36
+ dstdir = File.join(repo.path,'_darcs','current',entry)
37
+ Dir.mkdir(dstdir)
38
+ end
39
+ Find.find('.') do |entry|
40
+ next if repo.boring?(entry)
41
+ if !FileTest.directory?(entry)
42
+ writer << Chunk::AddFile.new(entry)
43
+ dstfile = File.join(repo.path,'_darcs','current',entry)
44
+ File.open(entry, 'r') do |f|
45
+ File.open(dstfile,'w') do |d|
46
+ if repo.binary?(entry)
47
+ f.binmode
48
+ contents = f.read
49
+ writer << Chunk::Binary.new(entry, '', contents)
50
+ d.write(contents)
51
+ else
52
+ data = f.read
53
+ d.write(data)
54
+ if data == "\n"
55
+ hunk = "+\n"
56
+ elsif data.size > 0 && data[-1..-1] != "\n"
57
+ hunk = "-\n" + data.split("\n",-1).map{|line| '+' + line}.join("\n") + "\n"
58
+ else
59
+ hunk = data[0..-2].split("\n",-1).map{|line| '+' + line}.join("\n") + "\n"
60
+ end
61
+ writer << Chunk::Hunk.new(entry, 1, hunk)
62
+ end
63
+ end
64
+ end
65
+ File.utime(0, File.mtime(entry), dstfile)
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ system "cp _darcs/patches/#{patch_info.filename} /tmp/foo.gz"
72
+
@@ -0,0 +1,78 @@
1
+
2
+ require 'sha1'
3
+
4
+ module Darcs
5
+
6
+ # This class holds the patch's name, log, author, date, and other
7
+ # meta-info.
8
+ class PatchInfo
9
+ def initialize(date, name, author, log = nil, inverted = false)
10
+ if date.kind_of?(String)
11
+ @date = parse_date(date)
12
+ else
13
+ @date = date
14
+ end
15
+ @name = name
16
+ @author = author
17
+ @log = log
18
+ @inverted = inverted
19
+ end
20
+
21
+ attr_reader :date, :name, :author, :log
22
+ def inverted?
23
+ @inverted
24
+ end
25
+
26
+ # Reads a patch from a stream using the inventory format
27
+ def self.read(f)
28
+ line = f.gets
29
+ return nil if line.nil?
30
+ if line[0..0] != '['
31
+ raise "Invalid inventory entry (starts with \"#{line[0..-2]}\")"
32
+ end
33
+
34
+ name = line[1..-2]
35
+ line = f.readline
36
+ raise "Invalid inventory entry" if !line[/^(.*)\*\*([0-9]{14})\]?\s*$/]
37
+ author = $1
38
+ date = $2
39
+ log = nil
40
+ if !line[/\]\s*$/]
41
+ log = ""
42
+ log += line[1..-1] while !((line = f.readline) =~ /^\]/)
43
+ end
44
+
45
+ return self.new(date, name, author, log)
46
+ end
47
+
48
+ # Retrieve the patch's date in string timestamp format
49
+ def timestamp
50
+ date.strftime("%Y%m%d%H%M%S")
51
+ end
52
+
53
+ # Retrieve the patch's name
54
+ def filename
55
+ author_hash = SHA1.new(author).to_s[0..4]
56
+ hash = SHA1.new(name + author + timestamp +
57
+ (log.nil? ? '' : log.gsub(/\n/, '')) +
58
+ (inverted? ? 't' : 'f'))
59
+ "#{timestamp}-#{author_hash}-#{hash}.gz"
60
+ end
61
+
62
+ def to_s
63
+ if log
64
+ the_log = log.gsub(/[\n\s]+$/, '').gsub(/\n/, "\n ")
65
+ end
66
+ "[#{name}\n#{author}**#{timestamp}" +
67
+ (log.nil? ? '' : "\n " + the_log + "\n") + "]"
68
+ end
69
+
70
+ protected
71
+ def parse_date(str)
72
+ # Format is YYYYMMDDHHMMSS
73
+ Time.gm(str[0..3].to_i, str[4..5].to_i, str[6..7].to_i, str[8..9].to_i,
74
+ str[10..11].to_i, str[12..13].to_i)
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,138 @@
1
+
2
+ require 'zlib'
3
+
4
+ module Darcs
5
+
6
+ # A PatchWriter is used to write PatchChunks into a patch.
7
+ class PatchWriter
8
+
9
+ # Create a new PatchWriter for writing the patch file associated with the
10
+ # given patch object
11
+ def initialize(patch)
12
+ @patch = patch
13
+ @file = File.open(patch.filename, 'w')
14
+ @gz = Zlib::GzipWriter.new(@file)
15
+ @gz.write(patch.info.to_s + " {\n")
16
+ end
17
+
18
+ attr_reader :patch
19
+
20
+ # Finishes writing the patch and close files
21
+ def finish
22
+ @gz.write("}\n")
23
+ @gz.close
24
+ end
25
+
26
+ # Closes files and deletes the patch file
27
+ def abort
28
+ begin
29
+ @gz.close
30
+ rescue
31
+ end
32
+ begin
33
+ File.delete(patch.filename)
34
+ rescue
35
+ end
36
+ end
37
+
38
+ # Writes a patch chunk to the file
39
+ def << (chunk)
40
+ chunk.write(@gz, patch)
41
+ end
42
+
43
+ end
44
+
45
+ module Chunk
46
+
47
+ # Base class for other chunks
48
+ class Base
49
+ end
50
+
51
+ # Chunk representing the addition of a directory to a repository
52
+ class AddDirectory <Base
53
+ def initialize(path)
54
+ @path = path
55
+ end
56
+
57
+ attr_reader :path
58
+
59
+ def write(io, patch)
60
+ io.write("adddir #{path}\n")
61
+ end
62
+ end
63
+
64
+ # Chunk which adds record of a file to the repository. The file contents
65
+ # are not a part of this; those must be added separately with Chunk::Hunk
66
+ # or Chunk::Binary.
67
+ class AddFile <Base
68
+ def initialize(path)
69
+ @path = path
70
+ end
71
+
72
+ attr_reader :path
73
+
74
+ def write(io, patch)
75
+ io.write("addfile #{path}\n")
76
+ end
77
+ end
78
+
79
+ # Chunk which makes a modification to a text file. If the file is binary,
80
+ # you will need to use Darcs::Chunk::Binary instead
81
+ #
82
+ # FIXME: We should create aggregate chunks to do a lot of the foot work
83
+ # for diffing, what not. An AddFileWithData chunk, A DiffFile chunk,
84
+ # whatnot. Or maybe a different method will present itself?
85
+ #
86
+ class Hunk <Base
87
+ # Creates a new hunk chunk for the specified file and line.
88
+ def initialize(path, line, data)
89
+ @path = path
90
+ @line = line
91
+ @data = data
92
+ end
93
+
94
+ attr_reader :path, :line, :data
95
+
96
+ def write(io, patch)
97
+ io.write("hunk #{path} #{line}\n#{data}")
98
+ end
99
+ end
100
+
101
+ # Chunk which replaces a binary file's contents
102
+ class Binary <Base
103
+
104
+ ENCODED_LINE_LENGTH = 78
105
+
106
+ # Creates a new Binary chunk. Old and new data are in their binary
107
+ # (non-encoded) form.
108
+ def initialize(path, old, new)
109
+ @path = path
110
+ @old = old
111
+ @new = new
112
+ end
113
+
114
+ attr_reader :path, :old, :new
115
+
116
+ def write(io, patch)
117
+ io.write("binary #{path}\noldhex\n#{hex_encode old}newhex\n#{hex_encode new}")
118
+ end
119
+
120
+ private
121
+ def chunk(data, size)
122
+ block_max = (data.size - 1) / size
123
+ (0..block_max).map do |chunk_number|
124
+ data[(chunk_number * size)...((chunk_number + 1) * size)]
125
+ end
126
+ end
127
+
128
+ def hex_encode(data)
129
+ return '' if data.size == 0
130
+ chunk(data, ENCODED_LINE_LENGTH / 2).map do |this_chunk|
131
+ '*' + this_chunk.unpack('H*').first + "\n"
132
+ end.join
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,129 @@
1
+
2
+ require 'darcs/patchwriter'
3
+
4
+ module Darcs
5
+
6
+ class Repository
7
+
8
+ attr_reader :path
9
+
10
+ def initialize(path)
11
+ @path = path
12
+ @prefs_regexps = {}
13
+ end
14
+
15
+ # Finds the repository we are in. Returns nil if we are not in a
16
+ # repository
17
+ def self.find
18
+ path = Dir.getwd
19
+ while !repository?(path)
20
+ return nil if File.dirname(path) == path
21
+ path = File.dirname(path)
22
+ end
23
+ self.new(path)
24
+ end
25
+
26
+ # Determines whether the specified path is a repository
27
+ def self.repository?(path)
28
+ FileTest.directory?(File.join(path, '_darcs', 'patches')) &&
29
+ FileTest.exists?(File.join(path, '_darcs', 'inventory'))
30
+ end
31
+
32
+ def patches
33
+ if @patches.nil?
34
+ @patches = []
35
+ pi = nil
36
+ File.open(inventory_file, 'r') do |f|
37
+ @patches << Patch.new(self, pi) while pi = PatchInfo.read(f)
38
+ end
39
+ end
40
+ @patches
41
+ end
42
+
43
+ def inventory_file
44
+ File.join(path, '_darcs', 'inventory')
45
+ end
46
+
47
+ # Determines whether this file a binary file according to the patterns
48
+ # found in _darcs/prefs/binaries.
49
+ def binary?(name)
50
+ prefs_regexp_file_matches(name, 'binaries')
51
+ end
52
+
53
+ # Determines whether this file a boring file according to the patterns
54
+ # found in _darcs/prefs/boring.
55
+ def boring?(name)
56
+ prefs_regexp_file_matches(name, 'boring')
57
+ end
58
+
59
+ def write_patch(patch_info)
60
+ patch = Patch.new(self, patch_info)
61
+ patch.write do |writer|
62
+ yield writer
63
+ end
64
+ end
65
+
66
+ protected
67
+ def prefs_regexp_file_matches(str, filename)
68
+ prefs_regexp(filename).match(str)
69
+ end
70
+
71
+ # Constructs a compound regular expression from the lines of a file in
72
+ # the 'prefs' directory which contains one expression per line, except
73
+ # for comment lines which start with '#'. The regular expression is
74
+ # cached so it is not recomputed every time.
75
+ def prefs_regexp(filename)
76
+ if @prefs_regexps[filename].nil?
77
+ fpath = File.join(path, '_darcs', 'prefs', filename)
78
+ @prefs_regexps[filename] = Regexp.new('(' +
79
+ IO.readlines(fpath).delete_if {|l|
80
+ l[0..0] == '#'
81
+ }.map {|l|
82
+ (l[-1..-1] == "\n") ? l[0..-2] : l
83
+ }.join('|') + ')'
84
+ )
85
+ end
86
+ @prefs_regexps[filename]
87
+ end
88
+
89
+ end
90
+
91
+ # A Patch is the full representation of a patch file in a repository
92
+ # (PatchInfo is simply the inventory information).
93
+ #
94
+ # Patch acts as an aggregate of PatchInfo
95
+ class Patch
96
+
97
+ attr_accessor :repository, :info
98
+
99
+ def initialize(repository, info)
100
+ @repository = repository
101
+ @info = info
102
+ end
103
+
104
+ def method_missing(*args)
105
+ info.send(*args)
106
+ end
107
+
108
+ # Retrieves the full path to the patch file
109
+ def filename
110
+ File.join(repository.path,'_darcs','patches',info.filename)
111
+ end
112
+
113
+ def write
114
+ patch_writer = PatchWriter.new(self)
115
+ begin
116
+ yield patch_writer
117
+ patch_writer.finish
118
+ File.open(repository.inventory_file, 'a') do |inv|
119
+ inv.write(info.to_s + "\n")
120
+ end
121
+ rescue
122
+ patch_writer.abort
123
+ raise $!
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ end
@@ -0,0 +1,39 @@
1
+
2
+ require 'test/unit'
3
+ require 'test_helper'
4
+
5
+ class DarcsImportTestCase < Test::Unit::TestCase
6
+
7
+ include TestHelper
8
+
9
+ def test_import
10
+ exe = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),
11
+ 'bin', 'darcs-import')
12
+
13
+ TestDir.with do |td|
14
+ td.play <<EOF
15
+ echo "Hello, World" >test.gif
16
+ mkdir foo
17
+ printf 'no newline' >foo/bar.txt
18
+ printf 'two newlines at end\\n\\n' >foo/bar2.txt
19
+ printf '\\n' >foo/bar3.txt
20
+ mkdir foo/bar
21
+ mkdir baz
22
+ echo "File 2">baz/slime.txt
23
+ EMAIL='Joe Fabetes <joe@example.com>' ruby #{exe} 2>&1
24
+ darcs check
25
+ EOF
26
+ assert(/No changes/.match(`darcs whatsnew -s`),
27
+ "Changes found!")
28
+ output = `darcs changes -s`
29
+ assert(/A \.\/test\.gif/.match(output))
30
+ assert(/A \.\/foo\//.match(output))
31
+ assert(/A \.\/foo\/bar\.txt/.match(output))
32
+ assert(/A \.\/foo\/bar\//.match(output))
33
+ assert(/A \.\/baz\//.match(output))
34
+ assert(/A \.\/baz\/slime\.txt/.match(output))
35
+ end
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,53 @@
1
+
2
+ require 'darcs/patchinfo'
3
+ require 'test/unit'
4
+
5
+ class PatchInfoTestCase < Test::Unit::TestCase
6
+
7
+ def test_initialize
8
+ pi = Darcs::PatchInfo.new('20051220115522', 'Test patch',
9
+ 'Joe Fabetes <joe@example.com>')
10
+
11
+ assert_kind_of Darcs::PatchInfo, pi
12
+ assert_equal 'Test patch', pi.name
13
+ assert_equal 'Joe Fabetes <joe@example.com>', pi.author
14
+ assert !pi.inverted?
15
+
16
+ assert_kind_of Time, pi.date
17
+ assert_equal 2005, pi.date.year
18
+ assert_equal 12, pi.date.month
19
+ assert_equal 20, pi.date.day
20
+ assert_equal 11, pi.date.hour
21
+ assert_equal 55, pi.date.min
22
+ assert_equal 22, pi.date.sec
23
+ end
24
+
25
+ def test_filename
26
+ pi = Darcs::PatchInfo.new('20051220170424', 'Rakefile, directories',
27
+ 'Jason M. Felice <jfelice@cronosys.com>')
28
+ assert_equal '20051220170424-e0cd7-00d5859bbcf77c9b726e7c4fd6fb8a536cd3cfcd.gz', pi.filename
29
+ end
30
+
31
+ def test_to_s
32
+ pi = Darcs::PatchInfo.new('20051220170424', 'Rakefile, directories',
33
+ 'Jason M. Felice <jfelice@cronosys.com>')
34
+ assert_equal "[Rakefile, directories\nJason M. Felice <jfelice@cronosys.com>**20051220170424]", pi.to_s
35
+
36
+ pi = Darcs::PatchInfo.new('20051220170424', 'Rakefile, directories',
37
+ 'Jason M. Felice <jfelice@cronosys.com>',
38
+ "And here is
39
+ a test log
40
+ message."
41
+ )
42
+
43
+ expect = "[Rakefile, directories
44
+ Jason M. Felice <jfelice@cronosys.com>**20051220170424
45
+ And here is
46
+ a test log
47
+ message.
48
+ ]"
49
+ assert_equal expect, pi.to_s
50
+ end
51
+
52
+ end
53
+
@@ -0,0 +1,86 @@
1
+
2
+ require 'darcs/patchinfo'
3
+ require 'darcs/repository'
4
+ require 'darcs/patchwriter'
5
+ require 'test/unit'
6
+ require 'test_helper'
7
+
8
+ # Make some things accessible so we can unit test them
9
+ module Darcs
10
+ module Chunk
11
+ class Binary
12
+ def public_chunk(*args); chunk(*args); end
13
+ def public_hex_encode(*args); hex_encode(*args); end
14
+ end
15
+ end
16
+ end
17
+
18
+ class PatchWriterTestCase < Test::Unit::TestCase
19
+
20
+ include TestHelper
21
+
22
+ def test_new
23
+ TestDir.with do |td|
24
+ td.play <<EOF
25
+ darcs initialize
26
+ mkdir foo_dir
27
+ echo "Hello, World!"> foo_file
28
+ echo "Hello, World!"> bar_file
29
+ EOF
30
+
31
+ repo = Darcs::Repository.new(td.path)
32
+ patch_info = Darcs::PatchInfo.new(Time.now, 'Test Patch',
33
+ 'joe@example.com')
34
+ repo.write_patch(patch_info) do |writer|
35
+
36
+ assert_kind_of Darcs::PatchWriter, writer
37
+ assert_kind_of Darcs::Patch, writer.patch
38
+ assert_equal patch_info, writer.patch.info
39
+
40
+ writer << Darcs::Chunk::AddDirectory.new('./foo_dir')
41
+ writer << Darcs::Chunk::AddFile.new('./foo_file')
42
+ writer << Darcs::Chunk::Hunk.new('./foo_file', 1, "+Hello, World!\n")
43
+ writer << Darcs::Chunk::AddFile.new('./bar_file')
44
+ writer << Darcs::Chunk::Binary.new('./bar_file', "", "Hello, World!\n")
45
+ end
46
+
47
+ # We just recorded a patch, we didn't apply it, so...
48
+ td.play <<EOF
49
+ mkdir _darcs/current/foo_dir
50
+ echo 'Hello, World!'> _darcs/current/foo_file
51
+ echo 'Hello, World!'> _darcs/current/bar_file
52
+ EOF
53
+
54
+ plist = repo.patches
55
+ assert_equal 1, plist.size
56
+ assert_equal 'Test Patch', plist[0].name
57
+ assert_equal 'joe@example.com', plist[0].author
58
+ assert FileTest.exists?(plist[0].filename)
59
+
60
+ # Check repo consistency
61
+ td.play "darcs check"
62
+
63
+ # Verify that darcs can read it
64
+ output = `darcs changes -s`
65
+ assert(/ joe@example.com\n \* Test Patch\n$/.match(output))
66
+ assert(/A \.\/foo_dir\//.match(output))
67
+ assert(/A \.\/foo_file/.match(output))
68
+ assert(/A \.\/bar_file/.match(output))
69
+
70
+ output = `darcs whatsnew`
71
+ assert(/No changes/.match(output),
72
+ "darcs is seeing changes!:\n#{output}")
73
+ end
74
+ end
75
+
76
+ def test_binary_hex_encode
77
+ binary_chunk = Darcs::Chunk::Binary.new('foo', '', 'baz')
78
+
79
+ assert_equal [ '1234567890', '12345' ],
80
+ binary_chunk.public_chunk('123456789012345', 10)
81
+
82
+ assert_equal "*313233343536373839\n",
83
+ binary_chunk.public_hex_encode('123456789')
84
+ end
85
+
86
+ end
@@ -0,0 +1,96 @@
1
+
2
+ require 'test/unit'
3
+ require 'darcs/repository'
4
+ require 'darcs/patchinfo'
5
+ require 'find'
6
+ require 'test_helper'
7
+ require 'tempfile'
8
+
9
+ class RepostioryTestCase < Test::Unit::TestCase
10
+
11
+ include TestHelper
12
+
13
+ def test_create
14
+ repo = Darcs::Repository.new('/tmp')
15
+ assert_kind_of Darcs::Repository, repo
16
+ assert_equal '/tmp', repo.path
17
+ end
18
+
19
+ def test_patches
20
+ TestDir.with do |td|
21
+ tf = Tempfile.new('test')
22
+ File.open(tf.path, 'w') do |f|
23
+ f.write("Test patch 3\nHere is log line 1\nHere is log line 2\nend\n")
24
+ end
25
+ td.play <<EOF
26
+ darcs initialize
27
+ echo 'this is foo' >> foo.txt
28
+ darcs add foo.txt
29
+ darcs record -a -A 'Joe Fabetes <joe@example.com>' -m 'Test patch 1'
30
+ echo 'hi' >> bar.txt
31
+ darcs add bar.txt
32
+ darcs record -a -A 'Joe Fabetes <joe@example.com>' -m 'Test patch 2'
33
+ echo 'bazfile' >> baz.txt
34
+ darcs add baz.txt
35
+ darcs record -a -A 'Joe Fabetes <joe@example.com>' --logfile #{tf.path}
36
+ EOF
37
+ repo = Darcs::Repository.new(td.path)
38
+ patches = repo.patches
39
+
40
+ assert_equal 3, patches.size
41
+ patches.each do |patch|
42
+ assert_kind_of Darcs::Patch, patch
43
+ assert_equal 'Joe Fabetes <joe@example.com>', patch.author
44
+ assert FileTest.exists?(patch.filename),
45
+ "patch.filename isn't valid."
46
+ end
47
+ assert_equal "Test patch 3", patches[2].name
48
+ end
49
+ end
50
+
51
+ def test_repository?
52
+ TestDir.with do |td|
53
+ td.play "darcs initialize"
54
+
55
+ assert Darcs::Repository.repository?(td.path)
56
+ assert !Darcs::Repository.repository?('/tmp')
57
+ end
58
+ end
59
+
60
+ def test_find
61
+ TestDir.with do |td|
62
+ td.play "darcs initialize"
63
+
64
+ repo = Darcs::Repository.find
65
+ assert_kind_of Darcs::Repository, repo
66
+ assert_equal td.path, repo.path
67
+
68
+ Dir.mkdir('foo')
69
+ td.play "darcs add foo"
70
+ Dir.chdir('foo')
71
+
72
+ repo = Darcs::Repository.find
73
+ assert_kind_of Darcs::Repository, repo
74
+ assert_equal td.path, repo.path
75
+
76
+ Dir.chdir('/tmp')
77
+ repo = Darcs::Repository.find
78
+ assert_equal nil, repo
79
+ end
80
+ end
81
+
82
+ def test_boring_and_binary
83
+ TestDir.with do |td|
84
+ td.play "darcs initialize"
85
+
86
+ repo = Darcs::Repository.find
87
+
88
+ assert repo.boring?('./foo/CVS/Shucks'), "CVS files are not boring!"
89
+ assert repo.binary?('./foo.jpg'), "JPEG files are not binary!"
90
+ assert !repo.boring?('./foo.c'), "C files are boring?!"
91
+ assert !repo.binary?('./foo.pl'), "Perl files are binary? (Well, close..)"
92
+
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,72 @@
1
+
2
+ module TestHelper
3
+
4
+ # Utility class for tests to work with a temporary directory, play commands
5
+ # in it, automatically clean up files, etc.
6
+ #
7
+ # Use like so:
8
+ #
9
+ # TestHelper::TestDir.with do |td|
10
+ # td.play <<EOF
11
+ # echo hi >>foo.txt
12
+ # touch bar.txt
13
+ # EOF
14
+ # end
15
+ #
16
+ class TestDir
17
+
18
+ def initialize
19
+ @path = "/tmp/rdarcs_#{$$}_#{rand(100000)}"
20
+ Dir.mkdir(@path)
21
+ end
22
+
23
+ attr_reader :path
24
+
25
+ def in
26
+ old_path = Dir.getwd
27
+ Dir.chdir(path)
28
+ begin
29
+ yield
30
+ ensure
31
+ Dir.chdir(old_path)
32
+ end
33
+ end
34
+
35
+ # Retrieves this temporary directory's path
36
+ def play (script)
37
+ script.split(/\n/).each do |cmd|
38
+ output = `#{cmd}`
39
+ raise "#{cmd} -> #{output} (error_code = #{$?})" if $? != 0
40
+ end
41
+ end
42
+
43
+ # Removes the directory and all files and sub-directories in it
44
+ def delete
45
+ directories = []
46
+ Find.find(path) do |ent|
47
+ if FileTest.directory?(ent)
48
+ directories << ent
49
+ else
50
+ File.unlink(ent)
51
+ end
52
+ end
53
+ directories.sort{|a, b| b.size <=> a.size}.each do |dir|
54
+ Dir.rmdir(dir)
55
+ end
56
+ end
57
+
58
+ # Creates a new temporary directory, runs a block of code in it, and
59
+ # cleans up afterward.
60
+ def self.with
61
+ repo = self.new
62
+ begin
63
+ repo.in do
64
+ yield repo
65
+ end
66
+ ensure
67
+ repo.delete
68
+ end
69
+ end
70
+ end
71
+
72
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: darcs-ruby
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2005-12-22 00:00:00 -05:00
8
+ summary: Interface to Darcs change control system
9
+ require_paths:
10
+ - lib
11
+ email: jfelice@cronosys.com
12
+ homepage: http://eraserhead.net/darcs/darcs-ruby/doc/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - Jason M. Felice
31
+ files:
32
+ - lib/darcs
33
+ - lib/darcs/repository.rb
34
+ - lib/darcs/patchinfo.rb
35
+ - lib/darcs/patchwriter.rb
36
+ - test/test_helper.rb
37
+ - test/patchwriter_test.rb
38
+ - test/repository_test.rb
39
+ - test/patchinfo_test.rb
40
+ - test/darcs-import_test.rb
41
+ - Rakefile
42
+ - bin/darcs-import
43
+ test_files:
44
+ - test/patchwriter_test.rb
45
+ - test/repository_test.rb
46
+ - test/patchinfo_test.rb
47
+ - test/darcs-import_test.rb
48
+ rdoc_options: []
49
+ extra_rdoc_files: []
50
+ executables:
51
+ - darcs-import
52
+ extensions: []
53
+ requirements: []
54
+ dependencies: []