dreamcatch 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ integration
21
+ integration_test
22
+ integration_test/
23
+ integration_test/*
24
+ .document
25
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Fernando Barajas
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ = Dreamcatch
2
+
3
+ A Ruby Gem to create new git repositories on dreamhost using WebDav
4
+
5
+
6
+ Dreamcatch::Config.remote_url = "repo.example.com/git"
7
+ Dreamcatch::Config.username = "username"
8
+ Dreamcatch::Config.password = "password"
9
+
10
+
11
+ repo = Dreamcatch::Repo.new(
12
+ :dir => "~/some/dir",
13
+ :name => "repo.git"
14
+ )
15
+ repo.save # => returns true when save success
16
+
17
+
18
+ repo = Dreamcatch::Repo.new(
19
+ :dir => "~/some/dir",
20
+ :name => "repo.git"
21
+ )
22
+ repo.delete # => returns true when delete is success
23
+
24
+
25
+ repo = Dreamcatch::Repo.new(
26
+ :dir => "~/some/dir",
27
+ :name => "repo.git"
28
+ )
29
+ repo.rename("new-name.git") # => returns true when rename was success
30
+
31
+
32
+ repo = Dreamcatch::Repo.new(
33
+ :dir => "~/some/dir",
34
+ :name => "repo.git"
35
+ )
36
+ repo.delete_local # => returns true when rename was success
37
+
38
+
39
+ repo = Dreamcatch::Repo.new(
40
+ :dir => "~/some/dir",
41
+ :name => "repo.git"
42
+ )
43
+ repo.errors # => returns an array of errors if any where found after delete, delete_local, rename or save
44
+
45
+
46
+ == Gem Dependencies
47
+
48
+ * *grit* must also be available
49
+
50
+ sudo gem install grit
51
+
52
+
53
+ == Note on Patches/Pull Requests
54
+
55
+ * Fork the project.
56
+ * Make your feature addition or bug fix.
57
+ * Add tests for it. This is important so I don't break it in a
58
+ future version unintentionally.
59
+ * Commit, do not mess with rakefile, version, or history.
60
+ * Send me a pull request.
61
+
62
+ == Copyright
63
+
64
+ Copyright (c) 2009 Fernando Barajas. See LICENSE for details.
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "dreamcatch"
8
+ gem.summary = %Q{Git on Dreamhost WebDAV}
9
+ gem.description = %Q{A simple way to add and remove git repos on dreamhost webdav}
10
+ gem.email = "fernyb@fernyb.net"
11
+ gem.homepage = "http://github.com/fernyb/dreamcatch"
12
+ gem.authors = ["Fernando Barajas"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "grit"
15
+
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ spec.rcov_opts = ['--exclude', "/Library/Ruby/Gems,_spec.rb,spec_helper.rb"]
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "dreamcatch #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,75 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{dreamcatch}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Fernando Barajas"]
12
+ s.date = %q{2009-11-27}
13
+ s.description = %q{A simple way to add and remove git repos on dreamhost webdav}
14
+ s.email = %q{fernyb@fernyb.net}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "dreamcatch.gemspec",
26
+ "lib/dreamcatch.rb",
27
+ "lib/dreamcatch/config.rb",
28
+ "lib/dreamcatch/dav.rb",
29
+ "lib/dreamcatch/dav_response.rb",
30
+ "lib/dreamcatch/error.rb",
31
+ "lib/dreamcatch/repo.rb",
32
+ "lib/dreamcatch/web_dav.rb",
33
+ "spec/dreamcatch/config_spec.rb",
34
+ "spec/dreamcatch/dav_response_spec.rb",
35
+ "spec/dreamcatch/dav_spec.rb",
36
+ "spec/dreamcatch/error_spec.rb",
37
+ "spec/dreamcatch/repo_spec.rb",
38
+ "spec/fixtures/response/404_not_found.txt",
39
+ "spec/fixtures/response/put.txt",
40
+ "spec/fixtures/response/put_no_body.txt",
41
+ "spec/fixtures/response/put_two.txt",
42
+ "spec/spec.opts",
43
+ "spec/spec_helper.rb"
44
+ ]
45
+ s.homepage = %q{http://github.com/fernyb/dreamcatch}
46
+ s.rdoc_options = ["--charset=UTF-8"]
47
+ s.require_paths = ["lib"]
48
+ s.rubygems_version = %q{1.3.5}
49
+ s.summary = %q{Git on Dreamhost WebDAV}
50
+ s.test_files = [
51
+ "spec/dreamcatch/config_spec.rb",
52
+ "spec/dreamcatch/dav_response_spec.rb",
53
+ "spec/dreamcatch/dav_spec.rb",
54
+ "spec/dreamcatch/error_spec.rb",
55
+ "spec/dreamcatch/repo_spec.rb",
56
+ "spec/spec_helper.rb"
57
+ ]
58
+
59
+ if s.respond_to? :specification_version then
60
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
+ s.specification_version = 3
62
+
63
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
65
+ s.add_runtime_dependency(%q<grit>, [">= 0"])
66
+ else
67
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
68
+ s.add_dependency(%q<grit>, [">= 0"])
69
+ end
70
+ else
71
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
72
+ s.add_dependency(%q<grit>, [">= 0"])
73
+ end
74
+ end
75
+
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + "/dreamcatch/config"
2
+ require File.dirname(__FILE__) + "/dreamcatch/dav"
3
+ require File.dirname(__FILE__) + "/dreamcatch/dav_response"
4
+ require File.dirname(__FILE__) + "/dreamcatch/web_dav"
5
+ require File.dirname(__FILE__) + "/dreamcatch/repo"
6
+ require File.dirname(__FILE__) + "/dreamcatch/error"
7
+
8
+ require "rubygems"
9
+ require "grit"
10
+ require "open3"
11
+ require "base64"
@@ -0,0 +1,17 @@
1
+ module Dreamcatch
2
+ class Config
3
+ class << self
4
+ attr_accessor :remote_url
5
+ attr_accessor :username
6
+ attr_accessor :password
7
+
8
+ def remote_url
9
+ "http://#{@remote_url}"
10
+ end
11
+
12
+ def credentials
13
+ Base64.encode64("#{@username}:#{@password}").gsub(/\n+/, "")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,126 @@
1
+ #
2
+ # This class should replace fernyb_davclient which is a total mess
3
+ #
4
+ module Dreamcatch
5
+ class DAV
6
+ attr_accessor :notifier
7
+
8
+ def exists?(remote_file_name)
9
+ resp = run("#{remote_file_name}")
10
+ puts "* Exists : #{resp.status_code} #{resp.status}\n" if $DEBUG
11
+ if resp.status_code == 404
12
+ false
13
+ elsif resp.status_code == 200
14
+ true
15
+ else
16
+ nil
17
+ end
18
+ end
19
+
20
+ def delete(remote_file)
21
+ command = []
22
+ command << "--request DELETE"
23
+ command << %Q{--header 'Content-Type: text/xml; charset="utf-8"'}
24
+ command << remote_file
25
+ curl_command = command.join(" ")
26
+ resp = run(curl_command)
27
+
28
+ puts "* DELETE: #{resp.status_code} #{resp.status}" if $DEBUG
29
+
30
+ if resp.status_code == 401
31
+ @notifier.add_error Dreamcatch::Error.new("#{resp.status_code} #{resp.status}")
32
+ false
33
+ elsif resp.status_code == 204
34
+ resp
35
+ else
36
+ @notifier.add_error Dreamcatch::Error.new("#{resp.status_code} #{resp.status}")
37
+ false
38
+ end
39
+ end
40
+
41
+ def rename(current_name, new_name)
42
+ command = []
43
+ command << "--request MOVE"
44
+ command << %Q{--header 'Content-Type: text/xml; charset="utf-8"'}
45
+ command << %Q{--header 'Destination: #{new_name}'}
46
+ curl_command = command.join(" ") + " " + current_name
47
+ resp = run(curl_command)
48
+ puts "* MOVE: #{resp.status_code} #{resp.status}" if $DEBUG
49
+
50
+ if resp.status_code == 201
51
+ resp
52
+ else
53
+ @notifier.add_error Dreamcatch::Error.new("#{resp.status_code} #{resp.status}")
54
+ false
55
+ end
56
+ end
57
+
58
+ def put(remote_file_name, local_file_name)
59
+ command = []
60
+ command << "--upload-file #{local_file_name} #{remote_file_name}"
61
+ curl_command = command.join(" ")
62
+ resp = run(curl_command)
63
+ puts "* PUT: #{resp.status_code} #{resp.status}" if $DEBUG
64
+ if resp.status_code == 201
65
+ resp
66
+ else
67
+ @notifier.add_error Dreamcatch::Error.new("#{resp.status_code} #{resp.status}")
68
+ false
69
+ end
70
+ end
71
+
72
+ def mkcol(remote_url)
73
+ curl_command = []
74
+ curl_command << "--request MKCOL"
75
+ curl_command << %Q{--header 'Content-Type: text/xml; charset="utf-8"'}
76
+ curl_command = curl_command.join(" ") + " " + remote_url
77
+ resp = run(curl_command)
78
+ puts "* MKCOL #{resp.status_code} #{resp.status}" if $DEBUG
79
+ if resp.status_code == 201
80
+ resp
81
+ else
82
+ @notifier.add_error Dreamcatch::Error.new("#{resp.status_code} #{resp.status}")
83
+ false
84
+ end
85
+ end
86
+
87
+ def run(command)
88
+ options = []
89
+ options << "--include"
90
+ options << "--location"
91
+ options << %Q{--header 'Authorization: Basic #{Dreamcatch::Config.credentials}'}
92
+ options = options.join(" ")
93
+ response = nil
94
+
95
+ curl_command = "curl #{options} #{command}"
96
+ puts "\n*** #{curl_command}\n" if $DEBUG
97
+
98
+ stdin, stdout, stderr = Open3.popen3(curl_command)
99
+ response = stdout.readlines.join("")
100
+
101
+ response = headers_and_response_from_response(response)
102
+ end
103
+
104
+ def headers_and_response_from_response(response)
105
+ head = response.to_s.scan(/HTTP\/(\d+.\d+) (\d+) (.*)\r/)
106
+ resp = Dreamcatch::DAVResponse.new
107
+ if head.size == 1
108
+ resp.status = head.first[2]
109
+ resp.status_code = head.first[1].to_i
110
+ elsif head.size >= 2
111
+ resp.status = head.last[2]
112
+ resp.status_code = head.last[1].to_i
113
+ end
114
+
115
+ body = response.to_s.split("\r\n\r\n")
116
+ if body.last.to_s.match(/^HTTP\/(\d+).(\d+)/)
117
+ resp.head = body.last
118
+ resp.body = nil
119
+ else
120
+ resp.head = body[(body.size - 2)]
121
+ resp.body = body.last
122
+ end
123
+ resp
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,8 @@
1
+ module Dreamcatch
2
+ class DAVResponse
3
+ attr_accessor :status
4
+ attr_accessor :status_code
5
+ attr_accessor :head
6
+ attr_accessor :body
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Dreamcatch
2
+ class Error
3
+ attr_accessor :description
4
+
5
+ def initialize(msg)
6
+ @description = msg
7
+ end
8
+
9
+ def to_s
10
+ @description
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,89 @@
1
+ module Dreamcatch
2
+ class Invalid < StandardError; end
3
+
4
+ class Repo
5
+ attr_reader :webdav
6
+ attr_reader :errors
7
+
8
+ def initialize(opts={})
9
+ @errors ||= []
10
+ @name = opts[:name]
11
+ @dir = opts[:dir]
12
+ raise Dreamcatch::Invalid.new("Repo must have name") if @name.nil?
13
+ raise Dreamcatch::Invalid.new("Repo must have dir") if @dir.nil?
14
+ @webdav = Dreamcatch::WebDav.new(Dreamcatch::Config.remote_url, self)
15
+ end
16
+
17
+ def delete
18
+ if webdav.exists?("#{@name}")
19
+ webdav.delete("#{@name}")
20
+ else
21
+ self.add_error Dreamcatch::Error.new(%Q{#{@name} does not exists})
22
+ nil
23
+ end
24
+ end
25
+
26
+ def delete_local
27
+ if local_repo_exists?
28
+ if FileUtils.remove_dir(local_repo) == 0
29
+ true
30
+ else
31
+ self.add_error(Dreamcatch::Error.new(%Q{#{local_repo} could not be removed}))
32
+ nil
33
+ end
34
+ else
35
+ self.add_error Dreamcatch::Error.new(%Q{#{local_repo} does not exist locally})
36
+ nil
37
+ end
38
+ end
39
+
40
+ def rename(new_name)
41
+ if webdav.exists?("#{@name}")
42
+ if !webdav.exists?("#{new_name}")
43
+ webdav.rename(@name, new_name)
44
+ else
45
+ self.add_error Dreamcatch::Error.new(%Q{#{new_name} already exists})
46
+ nil
47
+ end
48
+ else
49
+ self.add_error Dreamcatch::Error.new(%Q{#{@name} does not exist})
50
+ nil
51
+ end
52
+ end
53
+
54
+ def save
55
+ if local_repo_exists?
56
+ upload_to_webdav(@dir, @name)
57
+ elsif init_bare(local_repo)
58
+ upload_to_webdav(@dir, @name)
59
+ end
60
+ end
61
+
62
+ def local_repo
63
+ "#{@dir}/#{@name}"
64
+ end
65
+
66
+ def local_repo_exists?
67
+ File.exists? local_repo
68
+ end
69
+
70
+ def upload_to_webdav(local_dir, repo_name)
71
+ webdav.put(local_dir, repo_name)
72
+ end
73
+
74
+ def init_bare(local_repo_path)
75
+ Grit::Repo.init_bare(local_repo_path)
76
+ end
77
+
78
+ def errors
79
+ @errors
80
+ end
81
+
82
+ def errors=(message)
83
+ @errors ||= []
84
+ @errors << message if message.kind_of?(Dreamcatch::Error)
85
+ end
86
+ alias_method :add_error, :errors=
87
+ end
88
+
89
+ end
@@ -0,0 +1,57 @@
1
+ module Dreamcatch
2
+ class WebDav
3
+ attr_reader :remote_url
4
+ attr_accessor :notifier
5
+ attr_accessor :webdav
6
+
7
+ def initialize(url, notify=nil)
8
+ @remote_url = url
9
+ @webdav ||= Dreamcatch::DAV.new
10
+ @webdav.notifier = notify
11
+ @notifier = notify
12
+ end
13
+
14
+ def exists?(save_name)
15
+ save_name << "/" if save_name.match(/\.git$/)
16
+ webdav.exists?("#{remote_url}/#{save_name}")
17
+ end
18
+
19
+ def delete(repo_name)
20
+ webdav.delete("#{remote_url}/#{repo_name}/")
21
+ end
22
+
23
+ def rename(name, new_name)
24
+ unless webdav.exists?("#{remote_url}/#{new_name}")
25
+ webdav.rename("#{remote_url}/#{name}", "#{remote_url}/#{new_name}")
26
+ else
27
+ @notifier.add_error Dreamcatch::Error.new(%Q{#{new_name} does not exists})
28
+ end
29
+ end
30
+
31
+ def put(local_dir, save_name)
32
+ if exists?("#{save_name}")
33
+ @notifier.add_error Dreamcatch::Error.new(%Q{#{save_name} already exists})
34
+ return nil
35
+ elsif File.directory?("#{local_dir}/#{save_name}")
36
+ recursive_put(local_dir, save_name)
37
+ elsif !File.directory?("#{local_dir}/#{save_name}")
38
+ webdav.put("#{remote_url}/#{save_name}", "#{local_dir}/#{save_name}")
39
+ end
40
+ end
41
+
42
+ def recursive_put(local_dir, save_name)
43
+ if webdav.mkcol("#{remote_url}/#{save_name}")
44
+ results = Dir["#{local_dir}/#{save_name}/**/*"].collect do |local_file|
45
+ base_file_name = local_file.split("#{local_dir}")
46
+ if File.directory?(local_file)
47
+ webdav.mkcol("#{remote_url}#{base_file_name}")
48
+ else
49
+ webdav.put("#{remote_url}#{base_file_name}", "#{local_dir}#{base_file_name}")
50
+ end
51
+ end.select {|status| status == false || status.nil? }
52
+ results.include?(false) == false
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dreamcatch::Config do
4
+ describe :accessors do
5
+ it "has username accessor" do
6
+ Dreamcatch::Config.should respond_to(:username)
7
+ end
8
+
9
+ it "has password accessor" do
10
+ Dreamcatch::Config.should respond_to(:password)
11
+ end
12
+
13
+ it "has remote_url accessor" do
14
+ Dreamcatch::Config.should respond_to(:remote_url)
15
+ end
16
+ end
17
+
18
+ describe :remote_url do
19
+ it "returns url with http prefix" do
20
+ Dreamcatch::Config.username = nil
21
+ Dreamcatch::Config.password = nil
22
+ Dreamcatch::Config.remote_url = "repo.example.com/git"
23
+ Dreamcatch::Config.remote_url.should == "http://repo.example.com/git"
24
+ end
25
+ end
26
+
27
+ describe :credentials do
28
+ it "returns credentials base64 encoded" do
29
+ Dreamcatch::Config.username = "username"
30
+ Dreamcatch::Config.password = "password"
31
+ Dreamcatch::Config.credentials.should == "dXNlcm5hbWU6cGFzc3dvcmQ="
32
+ end
33
+
34
+ it "credentials should not be username:password" do
35
+ Dreamcatch::Config.username = "john"
36
+ Dreamcatch::Config.password = "doe"
37
+ Dreamcatch::Config.credentials.should_not == "dXNlcm5hbWU6cGFzc3dvcmQ="
38
+ end
39
+
40
+ it "should base64 encode username and password" do
41
+ Dreamcatch::Config.username = "username"
42
+ Dreamcatch::Config.password = "password"
43
+
44
+ Base64.should_receive(:encode64).with("username:password").and_return "username:password"
45
+ Dreamcatch::Config.credentials
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dreamcatch::DAVResponse do
4
+ before :each do
5
+ @response = Dreamcatch::DAVResponse.new
6
+ end
7
+
8
+ it "has status attribute" do
9
+ @response.should respond_to(:status)
10
+ end
11
+
12
+ it "has status_code attribute" do
13
+ @response.should respond_to(:status_code)
14
+ end
15
+
16
+ it "has head attribute" do
17
+ @response.should respond_to(:head)
18
+ end
19
+
20
+ it "has body attribute" do
21
+ @response.should respond_to(:body)
22
+ end
23
+ end
@@ -0,0 +1,202 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dreamcatch::DAV" do
4
+ before :each do
5
+ @dav = Dreamcatch::DAV.new
6
+ @dav.notifier = mock("Notifier", :errors => [], :add_error => nil)
7
+ end
8
+
9
+ describe :headers_and_response_from_response do
10
+ describe :put do
11
+ before :each do
12
+ dav = Dreamcatch::DAV.new
13
+ @resp = dav.send(:headers_and_response_from_response, response_for("put"))
14
+ @resp_two = dav.send(:headers_and_response_from_response, response_for("put_two"))
15
+ @resp_three = dav.send(:headers_and_response_from_response, response_for("put_no_body"))
16
+ end
17
+
18
+ it "should return Dreamcatch::Response" do
19
+ [@resp, @resp_two, @resp_three].each {|rp| rp.should be_kind_of(Dreamcatch::DAVResponse) }
20
+ end
21
+
22
+ it "should have status code 201 Created" do
23
+ [@resp, @resp_two, @resp_three].each {|rp| rp.status_code.should == 201 }
24
+ end
25
+
26
+ it "should have status" do
27
+ [@resp, @resp_two, @resp_three].each {|rp| rp.status.should == "Created" }
28
+ end
29
+
30
+ it "should have http headers" do
31
+ [@resp, @resp_two, @resp_three].each do |rp|
32
+ rp.head.should == "HTTP/1.1 201 Created\r\nDate: Sat, 21 Nov 2009 15:21:40 GMT\r\nServer: Apache\r\nLocation: http://example.com/git/test.txt\r\nVary: Accept-Encoding\r\nMS-Author-Via: DAV\r\nContent-Length: 185\r\nContent-Type: text/html; charset=ISO-8859-1"
33
+ end
34
+ end
35
+
36
+ it "should have body" do
37
+ [@resp, @resp_two].each do |rp|
38
+ rp.body.should == "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head>\r\n<title>201 Created</title>\r\n</head><body>\r\n<h1>Created</h1>\r\n<p>Resource /git/test.txt has been created.</p>\r\n</body></html>\r\n"
39
+ end
40
+ end
41
+
42
+ it "body should be nil" do
43
+ @resp_three.body.should be_nil
44
+ end
45
+ end # => end put
46
+ end
47
+
48
+ describe :mkcol do
49
+ it "should execute correct command" do
50
+ response = mock("Response", :status_code => 201)
51
+ @dav.should_receive(:run).with(%Q{--request MKCOL --header 'Content-Type: text/xml; charset="utf-8"' http://example.com/git/repo.git}).and_return(response)
52
+ @dav.mkcol("http://example.com/git/repo.git")
53
+ end
54
+
55
+ it "should return response when status_code is 201" do
56
+ response = mock("Response", :status_code => 201)
57
+ @dav.stub!(:run).and_return(response)
58
+ @dav.mkcol("http://example.com/git/repo.git").should == response
59
+ end
60
+
61
+ it "should return false when status_code is not 201" do
62
+ response = mock("Response", :status_code => 500, :status => "Failure")
63
+ @dav.stub!(:run).and_return(response)
64
+ @dav.mkcol("http://example.com/git/repo.git").should be_false
65
+ end
66
+ end
67
+
68
+ describe :put do
69
+ it "should execute correct command" do
70
+ response = mock("Response", :status_code => 201)
71
+ @dav.should_receive(:run).with("--upload-file /Users/fernyb/rails/local_file.txt http://example.com/git/file.txt").and_return(response)
72
+ @dav.put("http://example.com/git/file.txt", "/Users/fernyb/rails/local_file.txt")
73
+ end
74
+
75
+ it "should return response object when status code is 201" do
76
+ response = mock("Response", :status_code => 201)
77
+ @dav.stub!(:run).and_return(response)
78
+ @dav.put("http://example.com/git/file.txt", "/Users/fernyb/rails/local_file.txt").should == response
79
+ end
80
+
81
+ it "should return response object when status code is 201" do
82
+ response = mock("Response", :status_code => 500, :status => "Failure")
83
+ @dav.stub!(:run).and_return(response)
84
+ @dav.put("http://example.com/git/file.txt", "/Users/fernyb/rails/local_file.txt").should be_false
85
+ end
86
+ end
87
+
88
+ describe :exists? do
89
+ it "should execute correct command" do
90
+ response = mock("Response", :status_code => 200)
91
+ dav = Dreamcatch::DAV.new
92
+ dav.should_receive(:run).with("http://example.com/git/file.txt").and_return(response)
93
+ dav.exists?("http://example.com/git/file.txt")
94
+ end
95
+
96
+ it "returns false when status_code is 404" do
97
+ response = mock("Response", :status_code => 404)
98
+ dav = Dreamcatch::DAV.new
99
+ dav.stub!(:run).and_return(response)
100
+ dav.exists?("http://example.com/git/file.txt").should be_false
101
+ end
102
+
103
+ it "returns true when status_code is 200" do
104
+ response = mock("Response", :status_code => 200)
105
+ dav = Dreamcatch::DAV.new
106
+ dav.stub!(:run).and_return(response)
107
+ dav.exists?("http://example.com/git/file.txt").should be_true
108
+ end
109
+
110
+ it "returns nil when status_code is not 200 or 404" do
111
+ response = mock("Response", :status_code => 500)
112
+ dav = Dreamcatch::DAV.new
113
+ dav.stub!(:run).and_return(response)
114
+ dav.exists?("http://example.com/git/file.txt").should be_nil
115
+ end
116
+ end
117
+
118
+ describe :run do
119
+ it "should execute curl command" do
120
+ stdin, stdout, stderr = mock("StdIn"), mock("StdOut"), mock("StdErr")
121
+ stdout = response_for_into_array("put")
122
+
123
+ Open3.should_receive(:popen3).with("curl --include --location --header 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' http://example.com/git/file.txt").and_return([stdin, stdout, stderr])
124
+ @dav.send(:run, "http://example.com/git/file.txt")
125
+ end
126
+
127
+ it "should return Dreamcatch::DAVResponse object" do
128
+ stdin, stdout, stderr = mock("StdIn"), mock("StdOut"), mock("StdErr")
129
+ stdout = response_for_into_array("put")
130
+
131
+ Open3.should_receive(:popen3).with("curl --include --location --header 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' --request MKCOL http://example.com/git/collection").and_return([stdin, stdout, stderr])
132
+ @dav.send(:run, "--request MKCOL http://example.com/git/collection").should be_kind_of(Dreamcatch::DAVResponse)
133
+ end
134
+
135
+ it "should parse the http response" do
136
+ stdin, stdout, stderr = mock("StdIn"), mock("StdOut"), mock("StdErr")
137
+ stdout = response_for_into_array("put")
138
+ response = stdout.readlines.join("")
139
+ stdout.rewind
140
+
141
+ Open3.stub!(:popen3).and_return([stdin, stdout, stderr])
142
+ @dav.should_receive(:headers_and_response_from_response).with(response)
143
+ @dav.send(:run, "--request MKCOL http://example.com/git/collection")
144
+ end
145
+ end
146
+
147
+ describe :delete do
148
+ it "should execute correct command" do
149
+ resp = mock("Response", :status_code => 204)
150
+ @dav.should_receive(:run).with(%Q{--request DELETE --header 'Content-Type: text/xml; charset="utf-8"' http://example.com/git/file.txt}).and_return(resp)
151
+ @dav.delete("http://example.com/git/file.txt")
152
+ end
153
+
154
+ it "should return Response when status_code is 204" do
155
+ resp = mock("Response", :status_code => 204)
156
+ @dav.stub!(:run).and_return resp
157
+ @dav.delete("http://example.com/git/file.txt").should == resp
158
+ end
159
+
160
+ it "should not return Response when status code is not 201" do
161
+ resp = mock("Response", :status_code => 500, :status => "Failure")
162
+ @dav.stub!(:run).and_return resp
163
+ @dav.delete("http://example.com/git/file.txt").should_not == resp
164
+ end
165
+
166
+ it "should return false when status_code is not 201" do
167
+ resp = mock("Response", :status_code => 500, :status => "Failure")
168
+ @dav.stub!(:run).and_return resp
169
+ @dav.delete("http://example.com/git/file.txt").should be_false
170
+ end
171
+
172
+ it "should return false when status_code is 401" do
173
+ resp = mock("Response", :status_code => 401, :status => "Four Oh Four")
174
+ @dav.stub!(:run).and_return resp
175
+ @dav.delete("http://example.com/git/file.txt").should be_false
176
+ end
177
+ end
178
+
179
+ describe :rename do
180
+ before :each do
181
+ Dreamcatch::Config.stub!(:credentials).and_return "username:password"
182
+ end
183
+
184
+ it "should execute correct command" do
185
+ resp = mock("Response", :status_code => 201)
186
+ @dav.should_receive(:run).with(%Q{--request MOVE --header 'Content-Type: text/xml; charset=\"utf-8\"' --header 'Destination: http://example.com/git/new_name.git' http://example.com/git/name.git}).and_return(resp)
187
+ @dav.rename("http://example.com/git/name.git", "http://example.com/git/new_name.git")
188
+ end
189
+
190
+ it "should return response object when status code is 201" do
191
+ resp = mock("Response", :status_code => 201)
192
+ @dav.stub!(:run).and_return(resp)
193
+ @dav.rename("http://example.com/git/name.git", "http://example.com/git/new_name.git").should == resp
194
+ end
195
+
196
+ it "should return false when status is not 201" do
197
+ resp = mock("Response", :status_code => 500, :status => "Five hundred")
198
+ @dav.stub!(:run).and_return resp
199
+ @dav.rename("http://example.com/git/name.git", "http://example.com/git/new_name.git").should be_false
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dreamcatch::Error do
4
+ it "should have a message" do
5
+ msg = Dreamcatch::Error.new("Failure Message")
6
+ msg.to_s.should == "Failure Message"
7
+ end
8
+
9
+ it "should respond to description" do
10
+ msg = Dreamcatch::Error.new("Failure Message")
11
+ msg.should respond_to(:description)
12
+ end
13
+ end
@@ -0,0 +1,176 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dreamcatch::Repo" do
4
+ before :all do
5
+ @repo = Dreamcatch::Repo.new({
6
+ :dir => "/tmp",
7
+ :name => "test.git"
8
+ })
9
+ end
10
+
11
+ it "must provide name for repo name" do
12
+ @repo.instance_variable_get(:@name).should == "test.git"
13
+ @repo.instance_variable_get(:@dir).should == "/tmp"
14
+ end
15
+
16
+ it "throws exception when initialize without repo name" do
17
+ lambda {
18
+ Dreamcatch::Repo.new
19
+ }.should raise_error Dreamcatch::Invalid
20
+ end
21
+
22
+ describe :local_repo do
23
+ it "returns the path to local repo" do
24
+ @repo.local_repo.should == "/tmp/test.git"
25
+ end
26
+ end
27
+
28
+ describe :local_repo_exists? do
29
+ it "returns true when local repo exists" do
30
+ repo_name = "/tmp/test.git"
31
+
32
+ `mkdir #{repo_name}`
33
+ @repo.local_repo_exists?.should be_true
34
+ `rm -rf #{repo_name}`
35
+ end
36
+ end
37
+
38
+ describe :init_bare do
39
+ it "creates a bare git repository" do
40
+ Grit::Repo.should_receive(:init_bare).with("test.git").and_return true
41
+ @repo.init_bare("test.git").should be_true
42
+ end
43
+ end
44
+
45
+ describe :errors do
46
+ it "should return an array" do
47
+ @repo.errors.should be_kind_of(Array)
48
+ end
49
+
50
+ it "should have errors" do
51
+ @repo.webdav.stub!(:exists?).and_return false
52
+ @repo.rename("new_name.git")
53
+ @repo.errors.size.should == 1
54
+ end
55
+
56
+ it "should have errors when trying to delete" do
57
+ @repo.instance_variable_set(:@errors, [])
58
+ @repo.stub!(:exists?).and_return false
59
+ @repo.delete
60
+ @repo.errors.size.should == 1
61
+ end
62
+ end
63
+
64
+ describe :upload_to_webdav do
65
+ it "should execute put from webdav" do
66
+ local_dir, repo_name = "/Users/fernyb", "file.txt"
67
+ @repo.webdav.should_receive(:put).with(local_dir, repo_name)
68
+ @repo.upload_to_webdav(local_dir, repo_name)
69
+ end
70
+ end
71
+
72
+ describe :rename do
73
+ it "should execute webdav.rename when exists and new_name does not" do
74
+ @repo.webdav.should_receive(:exists?).with("test.git").and_return true
75
+ @repo.webdav.should_receive(:exists?).with("new_name.git").and_return false
76
+
77
+ @repo.webdav.should_receive(:rename).with("test.git", "new_name.git").and_return true
78
+ @repo.rename("new_name.git").should be_true
79
+ end
80
+
81
+ it "should not execute webdav.rename when exists and new_name already exists" do
82
+ @repo.webdav.should_receive(:exists?).with("test.git").and_return true
83
+ @repo.webdav.should_receive(:exists?).with("new_name.git").and_return true
84
+
85
+ @repo.webdav.should_not_receive(:rename)
86
+ @repo.rename("new_name.git").should be_nil
87
+ end
88
+
89
+ it "should not execute webdav.rename when not exists" do
90
+ @repo.webdav.should_receive(:exists?).with("test.git").and_return false
91
+ @repo.webdav.should_not_receive(:rename).with("test.git", "new_name")
92
+ @repo.rename("new_name").should be_nil
93
+ end
94
+ end
95
+
96
+ describe :delete_local do
97
+ it "should execute remove_dir from FileUtils and be true" do
98
+ @repo.stub!(:local_repo_exists?).and_return true
99
+ @repo.stub!(:local_repo).and_return "repo.git"
100
+ FileUtils.should_receive(:remove_dir).with("repo.git").and_return(0)
101
+ @repo.delete_local.should be_true
102
+ end
103
+
104
+ it "should execute remove_dir from FileUtils and be nil" do
105
+ @repo.stub!(:local_repo_exists?).and_return true
106
+ @repo.stub!(:local_repo).and_return "repo.git"
107
+ FileUtils.should_receive(:remove_dir).with("repo.git").and_return(1)
108
+ @repo.delete_local.should be_nil
109
+ end
110
+
111
+
112
+ it "should be nil when local repo does not exists" do
113
+ @repo.stub!(:local_repo_exists?).and_return false
114
+ FileUtils.should_not_receive(:remove_dir)
115
+ @repo.delete_local.should be_nil
116
+ end
117
+ end
118
+
119
+ describe :save do
120
+ before :each do
121
+ @repo.stub!(:local_repo_exists?).and_return true
122
+ @repo.stub!(:init_bare).and_return false
123
+ end
124
+
125
+ it "should upload_to_webdav when local repo exists" do
126
+ @repo.should_receive(:upload_to_webdav).with(@repo.instance_variable_get(:@dir), @repo.instance_variable_get(:@name))
127
+ @repo.save
128
+ end
129
+
130
+ it "should init bare local repo and upload to webdav" do
131
+ @repo.stub!(:local_repo_exists?).and_return false
132
+ @repo.should_receive(:init_bare).with(@repo.local_repo).and_return true
133
+ @repo.should_receive(:upload_to_webdav).with(@repo.instance_variable_get(:@dir), @repo.instance_variable_get(:@name))
134
+ @repo.save
135
+ end
136
+ end
137
+
138
+ describe :delete do
139
+ it "should delete repo when it does exists" do
140
+ @repo.webdav.stub!(:exists?).and_return true
141
+ @repo.webdav.should_receive(:delete).with(@repo.instance_variable_get(:@name)).and_return true
142
+ @repo.stub!(:local_repo_exists?).and_return false
143
+
144
+ @repo.delete.should be_true
145
+ end
146
+
147
+ it "should not delete repo when it does not exists" do
148
+ @repo.webdav.stub!(:exists?).and_return false
149
+ @repo.stub!(:local_repo_exists?).and_return false
150
+
151
+ @repo.delete.should be_nil
152
+ end
153
+
154
+ it "should not remote directory when local repo does not exists" do
155
+ @repo.webdav.stub!(:exists?).and_return false
156
+ @repo.stub!(:local_repo_exists?).and_return false
157
+ FileUtils.should_not_receive(:remove_dir).with(@repo.local_repo).and_return false
158
+
159
+ @repo.delete.should be_nil
160
+ end
161
+
162
+ it "should return true when remote file is deleted" do
163
+ @repo.webdav.stub!(:exists?).and_return true
164
+ @repo.webdav.should_receive(:delete).and_return true
165
+
166
+ @repo.delete.should be_true
167
+ end
168
+
169
+ it "should return false when remote file is deleted and fails" do
170
+ @repo.webdav.stub!(:exists?).and_return true
171
+ @repo.webdav.should_receive(:delete).and_return false
172
+
173
+ @repo.delete.should be_false
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,16 @@
1
+ HTTP/1.1 404 Not Found
2
+ Date: Sat, 21 Nov 2009 15:20:06 GMT
3
+ Server: Apache
4
+ Vary: Accept-Encoding
5
+ Content-Length: 329
6
+ Content-Type: text/html; charset=iso-8859-1
7
+
8
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
9
+ <html><head>
10
+ <title>404 Not Found</title>
11
+ </head><body>
12
+ <h1>Not Found</h1>
13
+ <p>The requested URL /git/test.txt was not found on this server.</p>
14
+ <p>Additionally, a 404 Not Found
15
+ error was encountered while trying to use an ErrorDocument to handle the request.</p>
16
+ </body></html>
@@ -0,0 +1,18 @@
1
+ HTTP/1.1 100 Continue
2
+
3
+ HTTP/1.1 201 Created
4
+ Date: Sat, 21 Nov 2009 15:21:40 GMT
5
+ Server: Apache
6
+ Location: http://example.com/git/test.txt
7
+ Vary: Accept-Encoding
8
+ MS-Author-Via: DAV
9
+ Content-Length: 185
10
+ Content-Type: text/html; charset=ISO-8859-1
11
+
12
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
13
+ <html><head>
14
+ <title>201 Created</title>
15
+ </head><body>
16
+ <h1>Created</h1>
17
+ <p>Resource /git/test.txt has been created.</p>
18
+ </body></html>
@@ -0,0 +1,8 @@
1
+ HTTP/1.1 201 Created
2
+ Date: Sat, 21 Nov 2009 15:21:40 GMT
3
+ Server: Apache
4
+ Location: http://example.com/git/test.txt
5
+ Vary: Accept-Encoding
6
+ MS-Author-Via: DAV
7
+ Content-Length: 185
8
+ Content-Type: text/html; charset=ISO-8859-1
@@ -0,0 +1,16 @@
1
+ HTTP/1.1 201 Created
2
+ Date: Sat, 21 Nov 2009 15:21:40 GMT
3
+ Server: Apache
4
+ Location: http://example.com/git/test.txt
5
+ Vary: Accept-Encoding
6
+ MS-Author-Via: DAV
7
+ Content-Length: 185
8
+ Content-Type: text/html; charset=ISO-8859-1
9
+
10
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
11
+ <html><head>
12
+ <title>201 Created</title>
13
+ </head><body>
14
+ <h1>Created</h1>
15
+ <p>Resource /git/test.txt has been created.</p>
16
+ </body></html>
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'dreamcatch'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
11
+
12
+ def response_for(name)
13
+ File.open(File.dirname(__FILE__) + "/fixtures/response/#{name}.txt") {|f| f.read }
14
+ end
15
+
16
+
17
+ def response_for_into_array(name)
18
+ f = File.new(File.dirname(__FILE__) + "/fixtures/response/#{name}.txt")
19
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dreamcatch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Fernando Barajas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-27 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: grit
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: A simple way to add and remove git repos on dreamhost webdav
36
+ email: fernyb@fernyb.net
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .gitignore
46
+ - LICENSE
47
+ - README.rdoc
48
+ - Rakefile
49
+ - VERSION
50
+ - dreamcatch.gemspec
51
+ - lib/dreamcatch.rb
52
+ - lib/dreamcatch/config.rb
53
+ - lib/dreamcatch/dav.rb
54
+ - lib/dreamcatch/dav_response.rb
55
+ - lib/dreamcatch/error.rb
56
+ - lib/dreamcatch/repo.rb
57
+ - lib/dreamcatch/web_dav.rb
58
+ - spec/dreamcatch/config_spec.rb
59
+ - spec/dreamcatch/dav_response_spec.rb
60
+ - spec/dreamcatch/dav_spec.rb
61
+ - spec/dreamcatch/error_spec.rb
62
+ - spec/dreamcatch/repo_spec.rb
63
+ - spec/fixtures/response/404_not_found.txt
64
+ - spec/fixtures/response/put.txt
65
+ - spec/fixtures/response/put_no_body.txt
66
+ - spec/fixtures/response/put_two.txt
67
+ - spec/spec.opts
68
+ - spec/spec_helper.rb
69
+ has_rdoc: true
70
+ homepage: http://github.com/fernyb/dreamcatch
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options:
75
+ - --charset=UTF-8
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.3.5
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Git on Dreamhost WebDAV
97
+ test_files:
98
+ - spec/dreamcatch/config_spec.rb
99
+ - spec/dreamcatch/dav_response_spec.rb
100
+ - spec/dreamcatch/dav_spec.rb
101
+ - spec/dreamcatch/error_spec.rb
102
+ - spec/dreamcatch/repo_spec.rb
103
+ - spec/spec_helper.rb