deep_thought 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +184 -0
- data/Rakefile +50 -0
- data/config.ru +5 -0
- data/db/migrate/20130414012805_create_projects.rb +15 -0
- data/db/migrate/20130426165010_create_states.rb +14 -0
- data/db/migrate/20130501003758_create_users.rb +14 -0
- data/db/migrate/20130508001711_add_api_key_to_users.rb +9 -0
- data/db/migrate/20130509014935_create_deploys.rb +27 -0
- data/db/migrate/20130514062148_create_delayed_jobs.rb +21 -0
- data/db/migrate/20130516042149_change_delayed_job_last_error_to_text.rb +9 -0
- data/db/migrate/20130517010210_add_ci_to_projects.rb +9 -0
- data/db/migrate/20130525001332_add_notification_url_to_users.rb +9 -0
- data/db/migrate/20131127022704_remove_deploy_type_and_ci_from_projects.rb +11 -0
- data/db/schema.rb +72 -0
- data/deep_thought.gemspec +45 -0
- data/lib/deep_thought.rb +62 -0
- data/lib/deep_thought/api.rb +156 -0
- data/lib/deep_thought/app.rb +342 -0
- data/lib/deep_thought/ci_service.rb +39 -0
- data/lib/deep_thought/ci_service/janky.rb +34 -0
- data/lib/deep_thought/deployer.rb +180 -0
- data/lib/deep_thought/deployer/deployer.rb +17 -0
- data/lib/deep_thought/deployer/shell.rb +45 -0
- data/lib/deep_thought/git.rb +76 -0
- data/lib/deep_thought/models/deploy.rb +27 -0
- data/lib/deep_thought/models/project.rb +32 -0
- data/lib/deep_thought/models/state.rb +6 -0
- data/lib/deep_thought/models/user.rb +45 -0
- data/lib/deep_thought/notifier.rb +13 -0
- data/lib/deep_thought/public/assets/javascripts/jquery.min.js +6 -0
- data/lib/deep_thought/public/assets/javascripts/main.js +36 -0
- data/lib/deep_thought/public/assets/stylesheets/main.css +438 -0
- data/lib/deep_thought/public/robots.txt +2 -0
- data/lib/deep_thought/scaler.rb +35 -0
- data/lib/deep_thought/tasks.rb +65 -0
- data/lib/deep_thought/version.rb +3 -0
- data/lib/deep_thought/views/history/index.haml +4 -0
- data/lib/deep_thought/views/history/show.haml +68 -0
- data/lib/deep_thought/views/layouts/layout.haml +32 -0
- data/lib/deep_thought/views/projects/edit.haml +15 -0
- data/lib/deep_thought/views/projects/index.haml +7 -0
- data/lib/deep_thought/views/projects/new.haml +8 -0
- data/lib/deep_thought/views/projects/show.haml +25 -0
- data/lib/deep_thought/views/sessions/login.haml +8 -0
- data/lib/deep_thought/views/users/index.haml +7 -0
- data/lib/deep_thought/views/users/new.haml +12 -0
- data/lib/deep_thought/views/users/show.haml +38 -0
- data/script/bootstrap +3 -0
- data/script/console +7 -0
- data/script/server +7 -0
- data/script/test +3 -0
- data/test/deep_thought_api_test.rb +114 -0
- data/test/deep_thought_app_test.rb +315 -0
- data/test/deep_thought_ci_service_test.rb +44 -0
- data/test/deep_thought_deployer_test.rb +72 -0
- data/test/deep_thought_git_test.rb +62 -0
- data/test/deep_thought_janky_test.rb +42 -0
- data/test/deep_thought_notifier_test.rb +35 -0
- data/test/deep_thought_project_test.rb +34 -0
- data/test/deep_thought_shell_test.rb +38 -0
- data/test/fixtures/project-test/HEAD +1 -0
- data/test/fixtures/project-test/config +8 -0
- data/test/fixtures/project-test/description +1 -0
- data/test/fixtures/project-test/hooks/applypatch-msg.sample +15 -0
- data/test/fixtures/project-test/hooks/commit-msg.sample +24 -0
- data/test/fixtures/project-test/hooks/post-update.sample +8 -0
- data/test/fixtures/project-test/hooks/pre-applypatch.sample +14 -0
- data/test/fixtures/project-test/hooks/pre-commit.sample +49 -0
- data/test/fixtures/project-test/hooks/pre-push.sample +54 -0
- data/test/fixtures/project-test/hooks/pre-rebase.sample +169 -0
- data/test/fixtures/project-test/hooks/prepare-commit-msg.sample +36 -0
- data/test/fixtures/project-test/hooks/update.sample +128 -0
- data/test/fixtures/project-test/info/exclude +6 -0
- data/test/fixtures/project-test/objects/13/8b8baba400e64fc384d468e80f10cf707e38d7 +1 -0
- data/test/fixtures/project-test/objects/6b/8fb16e1675767742afc70ac2ce038da46461f8 +0 -0
- data/test/fixtures/project-test/objects/7f/fc496d150b8a0015e3a16be8bacd47daed1a1c +0 -0
- data/test/fixtures/project-test/objects/8f/8606174a2aa11545d119fe3c4d6840fe0c4825 +0 -0
- data/test/fixtures/project-test/objects/9c/362942288a8ff6dc1addf7c5199bd9837e09de +0 -0
- data/test/fixtures/project-test/objects/b5/f7341de6145d3f8b95877cd2675d798fd172f1 +0 -0
- data/test/fixtures/project-test/objects/d1/f1e8664b0326316fb18796ac4ae1171e239cb6 +1 -0
- data/test/fixtures/project-test/objects/e6/d7ad6d61242936a2cd2bb9ae236adf43e59718 +0 -0
- data/test/fixtures/project-test/objects/fa/4cf5ff52462d17b6378a06fae8771c13b654b0 +1 -0
- data/test/fixtures/project-test/objects/fa/dda6bc20afa5cf93196bfb08a4989ee3b75ed7 +0 -0
- data/test/fixtures/project-test/packed-refs +4 -0
- data/test/fixtures/project-test/refs/heads/.gitkeep +0 -0
- data/test/fixtures/project-test/refs/tags/.gitkeep +0 -0
- data/test/test_helper.rb +42 -0
- metadata +462 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
module DeepThought
|
2
|
+
module CIService
|
3
|
+
class CIServiceNotFoundError < StandardError; end
|
4
|
+
class CIBuildNotGreenError < StandardError; end
|
5
|
+
class CIProjectAccessError < StandardError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :adapters, :ci_service
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.adapters
|
12
|
+
@adapters ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.register_adapter(name, service)
|
16
|
+
self.adapters[name] = service
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.setup(settings)
|
20
|
+
if settings['CI_SERVICE']
|
21
|
+
if @adapters.keys.include?(settings['CI_SERVICE'])
|
22
|
+
klass = adapters[settings['CI_SERVICE']]
|
23
|
+
@ci_service = klass.new
|
24
|
+
@ci_service.setup(settings)
|
25
|
+
else
|
26
|
+
raise CIServiceNotFoundError, "I don't have a CI service called \"#{settings['CI_SERVICE']}\"."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.is_branch_green?(app, branch, hash)
|
32
|
+
begin
|
33
|
+
@ci_service.is_branch_green?(app, branch, hash)
|
34
|
+
rescue
|
35
|
+
raise CIProjectAccessError, "Something went wrong asking #{ENV['CI_SERVICE']} about commit #{hash} in #{app} on the #{branch} branch."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module DeepThought
|
4
|
+
module CIService
|
5
|
+
class Janky
|
6
|
+
attr_accessor :endpoint, :username, :password
|
7
|
+
|
8
|
+
def setup(settings)
|
9
|
+
@endpoint = settings['CI_SERVICE_ENDPOINT']
|
10
|
+
@username = settings['CI_SERVICE_USERNAME']
|
11
|
+
@password = settings['CI_SERVICE_PASSWORD']
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_branch_green?(app, branch, hash)
|
15
|
+
is_green = false
|
16
|
+
|
17
|
+
response = HTTParty.get("#{@endpoint}/_hubot/#{app}/#{branch}", {:basic_auth => {:username => @username, :password => @password}})
|
18
|
+
builds = JSON.parse(response.body)
|
19
|
+
|
20
|
+
builds.each do |build|
|
21
|
+
if build['sha1'].to_s == hash.to_s
|
22
|
+
if build['green']
|
23
|
+
is_green = true
|
24
|
+
end
|
25
|
+
|
26
|
+
break
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
is_green
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'deep_thought/git'
|
3
|
+
|
4
|
+
module DeepThought
|
5
|
+
module Deployer
|
6
|
+
class DeployerNotFoundError < StandardError; end
|
7
|
+
class DeploymentFailedError < StandardError; end
|
8
|
+
class DeploymentInProgressError < StandardError; end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :adapters
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.adapters
|
15
|
+
@adapters ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.register_adapter(name, service)
|
19
|
+
self.adapters[name] = service
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.create(project, user, via, options = {})
|
23
|
+
branch = options[:branch] || 'master'
|
24
|
+
actions = options[:actions] if options[:actions]
|
25
|
+
environment = options[:environment] if options[:environment]
|
26
|
+
box = options[:box] if options[:box]
|
27
|
+
variables = options[:variables] if options[:variables]
|
28
|
+
on_behalf_of = options[:on_behalf_of] if options[:on_behalf_of]
|
29
|
+
|
30
|
+
if is_deploying?
|
31
|
+
raise DeploymentInProgressError, "Sorry, but I'm currently in mid-deployment. Ask me again when I'm done."
|
32
|
+
end
|
33
|
+
|
34
|
+
project.setup
|
35
|
+
|
36
|
+
hash = Git.get_latest_commit_for_branch(project, branch)
|
37
|
+
|
38
|
+
project_config = YAML.load_file(".projects/#{project.name}/.deepthought.yml")
|
39
|
+
|
40
|
+
if project_config['ci']
|
41
|
+
uses_ci = project_config['ci']['enabled'] || false
|
42
|
+
else
|
43
|
+
uses_ci = false
|
44
|
+
end
|
45
|
+
|
46
|
+
if DeepThought::CIService.ci_service
|
47
|
+
if uses_ci
|
48
|
+
ci_project_name = project_config['ci']['name'] || project.name
|
49
|
+
if !DeepThought::CIService.is_branch_green?(ci_project_name, branch, hash)
|
50
|
+
raise DeepThought::CIService::CIBuildNotGreenError, "Commit #{hash} on project #{app} (in branch #{branch}) is not green. Fix it before deploying."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
deploy = DeepThought::Deploy.new
|
56
|
+
deploy.project_id = project.id
|
57
|
+
deploy.user_id = user.id
|
58
|
+
deploy.branch = branch
|
59
|
+
deploy.commit = hash.to_s
|
60
|
+
deploy.via = via
|
61
|
+
deploy.actions = actions.to_yaml if actions
|
62
|
+
deploy.environment = environment if environment
|
63
|
+
deploy.box = box if environment && box
|
64
|
+
deploy.variables = variables.to_yaml if variables
|
65
|
+
deploy.on_behalf_of = on_behalf_of if on_behalf_of
|
66
|
+
deploy.save!
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.execute(deploy)
|
70
|
+
if !is_deploying?
|
71
|
+
Git.switch_to_branch(deploy.project, deploy.branch)
|
72
|
+
|
73
|
+
deploy.project.setup
|
74
|
+
|
75
|
+
project_config = YAML.load_file(".projects/#{deploy.project.name}/.deepthought.yml") || {}
|
76
|
+
deploy_type = project_config['deploy_type'] || 'shell'
|
77
|
+
|
78
|
+
if @adapters.keys.include?(deploy_type)
|
79
|
+
lock_deployer
|
80
|
+
|
81
|
+
deploy.started_at = DateTime.now
|
82
|
+
deploy.in_progress = true
|
83
|
+
deploy.save!
|
84
|
+
|
85
|
+
klass = adapters[deploy_type]
|
86
|
+
deployer = klass.new
|
87
|
+
deployer.setup(deploy.project, project_config)
|
88
|
+
deploy_status = deployer.execute(deploy, project_config)
|
89
|
+
|
90
|
+
unlock_deployer
|
91
|
+
|
92
|
+
deploy.finished_at = DateTime.now
|
93
|
+
deploy.in_progress = false
|
94
|
+
|
95
|
+
deploy_summary = deploy.project.name
|
96
|
+
|
97
|
+
if deploy.actions
|
98
|
+
actions = YAML.load(deploy.actions)
|
99
|
+
actions.each do |action|
|
100
|
+
deploy_summary += "/#{action}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
deploy_summary += " #{deploy.branch}"
|
105
|
+
|
106
|
+
if deploy.environment
|
107
|
+
deploy_summary += " to #{deploy.environment}"
|
108
|
+
|
109
|
+
if deploy.box
|
110
|
+
deploy_summary += "/#{deploy.box}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if deploy.variables
|
115
|
+
variables = YAML.load(deploy.variables)
|
116
|
+
variables.each do |k, v|
|
117
|
+
deploy_summary += " #{k}=#{v}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
if deploy_status
|
122
|
+
deploy.was_successful = true
|
123
|
+
deploy.save!
|
124
|
+
|
125
|
+
DeepThought::Notifier.notify(deploy.user, "SUCCESS: #{deploy_summary}")
|
126
|
+
|
127
|
+
true
|
128
|
+
else
|
129
|
+
deploy.was_successful = false
|
130
|
+
deploy.save!
|
131
|
+
|
132
|
+
DeepThought::Notifier.notify(deploy.user, "FAILED: #{deploy_summary}")
|
133
|
+
|
134
|
+
raise DeploymentFailedError, "The deployment pondered its own short existence before hitting the ground with a sudden wet thud."
|
135
|
+
end
|
136
|
+
else
|
137
|
+
raise DeployerNotFoundError, "I don't have a deployer called \"#{deploy_type}\"."
|
138
|
+
end
|
139
|
+
else
|
140
|
+
raise DeploymentInProgressError, "Sorry, but I'm currently in mid-deployment. Ask me again when I'm done."
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.is_deploying?
|
145
|
+
deployer_state = get_or_create_deployer_state
|
146
|
+
|
147
|
+
if deployer_state.state == 'true'
|
148
|
+
true
|
149
|
+
else
|
150
|
+
false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.lock_deployer
|
155
|
+
deployer_state = get_or_create_deployer_state
|
156
|
+
|
157
|
+
deployer_state.state = 'true'
|
158
|
+
deployer_state.save
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.unlock_deployer
|
162
|
+
deployer_state = get_or_create_deployer_state
|
163
|
+
|
164
|
+
deployer_state.state = 'false'
|
165
|
+
deployer_state.save
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
def self.get_or_create_deployer_state
|
171
|
+
deployer_state = DeepThought::State.find_by_name('deployer')
|
172
|
+
|
173
|
+
if !deployer_state
|
174
|
+
deployer_state = DeepThought::State.create(:name => 'deployer', :state => 'false')
|
175
|
+
end
|
176
|
+
|
177
|
+
deployer_state
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DeepThought
|
2
|
+
module Deployer
|
3
|
+
class Deployer
|
4
|
+
def initialize
|
5
|
+
if self.class.name == 'DeepThought::Deployer::Deployer'
|
6
|
+
raise "#{self.class.name} is abstract, you cannot instantiate it directly."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def setup(project, config)
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute(deploy, config)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'deep_thought/deployer/deployer'
|
2
|
+
|
3
|
+
module DeepThought
|
4
|
+
module Deployer
|
5
|
+
class Shell < DeepThought::Deployer::Deployer
|
6
|
+
def execute(deploy, config)
|
7
|
+
environment = deploy.environment || "development"
|
8
|
+
|
9
|
+
root = config['root'] || "script/deploy"
|
10
|
+
|
11
|
+
command = "#{root} #{environment} deploy"
|
12
|
+
|
13
|
+
if deploy.actions
|
14
|
+
actions = YAML.load(deploy.actions)
|
15
|
+
actions.each do |action|
|
16
|
+
command += ":#{action}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
command += " branch=#{deploy.branch}"
|
21
|
+
command += " box=#{deploy.box}" if deploy.box
|
22
|
+
|
23
|
+
if deploy.variables
|
24
|
+
variables = YAML.load(deploy.variables)
|
25
|
+
variables.each do |k, v|
|
26
|
+
command += " #{k}=#{v}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
commands = []
|
31
|
+
|
32
|
+
commands << "cd ./.projects/#{deploy.project.name}"
|
33
|
+
commands << "#{command} 2>&1"
|
34
|
+
|
35
|
+
executable = commands.join(" && ")
|
36
|
+
|
37
|
+
log = `#{executable}`
|
38
|
+
|
39
|
+
deploy.log = log
|
40
|
+
|
41
|
+
$?.success?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rugged'
|
2
|
+
|
3
|
+
module DeepThought
|
4
|
+
module Git
|
5
|
+
class GitRepositoryNotFoundError < StandardError; end
|
6
|
+
class GitBranchNotFoundError < StandardError; end
|
7
|
+
|
8
|
+
def self.setup(project)
|
9
|
+
if !File.directory?(".projects/#{project.name}/.git")
|
10
|
+
exit_status = system "git clone #{project.repo_url} .projects/#{project.name} > /dev/null 2>&1"
|
11
|
+
|
12
|
+
if exit_status
|
13
|
+
if !File.directory?(".projects/#{project.name}/.git")
|
14
|
+
false
|
15
|
+
else
|
16
|
+
if Dir.entries(".projects/#{project.name}") == [".", "..", ".git"]
|
17
|
+
false
|
18
|
+
else
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
else
|
23
|
+
false
|
24
|
+
end
|
25
|
+
else
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get_list_of_branches(project)
|
31
|
+
self.clone_if_not_exists(project)
|
32
|
+
|
33
|
+
system "cd ./.projects/#{project.name} && git fetch -p > /dev/null 2>&1"
|
34
|
+
|
35
|
+
repo = Rugged::Repository.new(".projects/#{project.name}")
|
36
|
+
|
37
|
+
branches = Rugged::Branch.each_name(repo, :remote).sort
|
38
|
+
branches.map! { |x| x.sub!('origin/', '') }
|
39
|
+
branches.delete('HEAD')
|
40
|
+
|
41
|
+
branches
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.get_latest_commit_for_branch(project, branch)
|
45
|
+
self.clone_if_not_exists(project)
|
46
|
+
|
47
|
+
system "cd ./.projects/#{project.name} && git fetch -p > /dev/null 2>&1"
|
48
|
+
|
49
|
+
repo = Rugged::Repository.new(".projects/#{project.name}")
|
50
|
+
|
51
|
+
switch_to_branch(project, branch)
|
52
|
+
|
53
|
+
repo.head.target
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.switch_to_branch(project, branch)
|
57
|
+
self.clone_if_not_exists(project)
|
58
|
+
|
59
|
+
exit_status = system "cd ./.projects/#{project.name} && git fetch -p > /dev/null 2>&1 && git reset --hard origin/#{branch} > /dev/null 2>&1"
|
60
|
+
|
61
|
+
if exit_status
|
62
|
+
true
|
63
|
+
else
|
64
|
+
raise GitBranchNotFoundError, "#{project.name} doesn't appear to have a branch called #{branch}. Have you pushed it?"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def self.clone_if_not_exists(project)
|
71
|
+
if !self.setup(project)
|
72
|
+
raise DeepThought::Git::GitRepositoryNotFoundError, "I can't seem to access that repo. Are you sure the URL is correct and that I have access to it?"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module DeepThought
|
2
|
+
class Deploy < ActiveRecord::Base
|
3
|
+
belongs_to :project
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
after_create :queue
|
7
|
+
|
8
|
+
validates_presence_of :branch
|
9
|
+
validates_presence_of :commit
|
10
|
+
validates_presence_of :project
|
11
|
+
validates_presence_of :user
|
12
|
+
|
13
|
+
def queue
|
14
|
+
Delayed::Job.enqueue self
|
15
|
+
|
16
|
+
DeepThought::Scaler.scale
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform
|
20
|
+
DeepThought::Deployer.execute(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def max_attempts
|
24
|
+
return 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module DeepThought
|
4
|
+
class ProjectConfigNotFoundError < StandardError; end
|
5
|
+
|
6
|
+
class Project < ActiveRecord::Base
|
7
|
+
has_many :deploys
|
8
|
+
|
9
|
+
before_destroy :delete_repo
|
10
|
+
|
11
|
+
validates :name, presence: true, uniqueness: true
|
12
|
+
validates :repo_url, presence: true
|
13
|
+
|
14
|
+
def setup
|
15
|
+
if DeepThought::Git.setup(self)
|
16
|
+
if !File.exists?(".projects/#{self.name}/.deepthought.yml")
|
17
|
+
delete_repo
|
18
|
+
|
19
|
+
raise DeepThought::ProjectConfigNotFoundError, "#{self.name} does not appear to have a .deepthought.yml config file. Add one and try again."
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise DeepThought::Git::GitRepositoryNotFoundError, "I can't seem to access that repo. Are you sure the URL is correct and that I have access to it?"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete_repo
|
27
|
+
if File.directory?(".projects/#{self.name}")
|
28
|
+
FileUtils.rm_rf(".projects/#{self.name}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|