dandelion 0.3.15 → 0.4.0.beta2
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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +11 -0
- data/LICENSE +1 -1
- data/README.md +15 -26
- data/Rakefile +4 -8
- data/bin/dandelion +4 -3
- data/dandelion.gemspec +23 -20
- data/lib/dandelion.rb +26 -10
- data/lib/dandelion/adapter.rb +45 -0
- data/lib/dandelion/{backend → adapter}/ftp.rb +22 -17
- data/lib/dandelion/adapter/noop.rb +14 -0
- data/lib/dandelion/{backend → adapter}/s3.rb +14 -15
- data/lib/dandelion/{backend → adapter}/sftp.rb +29 -16
- data/lib/dandelion/change.rb +11 -0
- data/lib/dandelion/changeset.rb +49 -0
- data/lib/dandelion/cli.rb +127 -0
- data/lib/dandelion/command.rb +26 -92
- data/lib/dandelion/command/deploy.rb +54 -41
- data/lib/dandelion/command/status.rb +14 -13
- data/lib/dandelion/config.rb +36 -0
- data/lib/dandelion/deployer.rb +53 -0
- data/lib/dandelion/diff.rb +62 -0
- data/lib/dandelion/tree.rb +22 -0
- data/lib/dandelion/utils.rb +13 -0
- data/lib/dandelion/version.rb +2 -2
- data/lib/dandelion/workspace.rb +71 -0
- data/spec/dandelion/adapter_spec.rb +42 -0
- data/spec/dandelion/change_spec.rb +17 -0
- data/spec/dandelion/changeset_spec.rb +73 -0
- data/spec/dandelion/command/deploy_spec.rb +111 -0
- data/spec/dandelion/command/status_spec.rb +4 -0
- data/spec/dandelion/command_spec.rb +70 -0
- data/spec/dandelion/config_spec.rb +15 -0
- data/spec/dandelion/deployer_spec.rb +65 -0
- data/spec/dandelion/diff_spec.rb +54 -0
- data/spec/dandelion/tree_spec.rb +15 -0
- data/spec/dandelion/workspace_spec.rb +77 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/HEAD +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/config +1 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/description +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/applypatch-msg.sample +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/commit-msg.sample +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/post-update.sample +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/pre-applypatch.sample +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/pre-commit.sample +6 -2
- data/spec/fixtures/repo.git/hooks/pre-push.sample +53 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/pre-rebase.sample +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/prepare-commit-msg.sample +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/hooks/update.sample +1 -1
- data/{test/test_git.git → spec/fixtures/repo.git}/info/exclude +0 -0
- data/spec/fixtures/repo.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 +0 -0
- data/spec/fixtures/repo.git/objects/34/e64fe350f3ea80c989cdac7a99c2adb8574fca +0 -0
- data/spec/fixtures/repo.git/objects/3d/9b743acb4a84dd99002d2c6f3fcf1a47e9f06b +0 -0
- data/spec/fixtures/repo.git/objects/4e/44973d41d33bf5342037f56497efe0a9604d25 +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6 +0 -0
- data/spec/fixtures/repo.git/objects/6c/a0f54491390579ce9438ec89c64c6b3499683a +0 -0
- data/spec/fixtures/repo.git/objects/8a/e33865a630c5d141c8a498f0c0166ff240b433 +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/objects/90/2dce0535b19f0c15ac8407fc4468256ad672d7 +0 -0
- data/spec/fixtures/repo.git/objects/c3/9af82404cc4267b1ba5f4b4437a511e0776abb +0 -0
- data/spec/fixtures/repo.git/objects/c8/85b3f693ed6e2926971ef75680f41b318072ae +0 -0
- data/spec/fixtures/repo.git/objects/d8/7cbcba0e2ede0752bdafc5938da35546803ba5 +0 -0
- data/spec/fixtures/repo.git/objects/e2/89ff1e2729839759dbd6fe99b6e35880910c7c +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
- data/{test/test_git.git → spec/fixtures/repo.git}/objects/ea/41dba10b54a794284e0be009a11f0ff3716a28 +0 -0
- data/spec/fixtures/repo.git/objects/ee/314a31b622b027c10981acaed7903a3607dbd4 +0 -0
- data/spec/fixtures/repo.git/objects/f6/66b137794d56880bab05e8fd256713a8fccf92 +0 -0
- data/spec/fixtures/repo.git/refs/heads/master +1 -0
- data/spec/spec_helper.rb +28 -0
- metadata +119 -127
- data/lib/dandelion/application.rb +0 -73
- data/lib/dandelion/backend.rb +0 -54
- data/lib/dandelion/deployment.rb +0 -173
- data/lib/dandelion/git.rb +0 -123
- data/test/fixtures/diff +0 -3
- data/test/fixtures/ls_tree +0 -5
- data/test/test_diff_deployment.rb +0 -122
- data/test/test_ftp.rb +0 -49
- data/test/test_git.git/hooks/post-commit.sample +0 -8
- data/test/test_git.git/hooks/post-receive.sample +0 -15
- data/test/test_git.git/objects/0c/a605e9f0f1d42ce8193ac36db11ec3cc9efc08 +0 -0
- data/test/test_git.git/objects/11/bada4e36fd065c8d1d3ca97b8dffa496c8e021 +0 -0
- data/test/test_git.git/objects/88/d4480861346093048e08ce8dcc577d8aa69379 +0 -1
- data/test/test_git.git/objects/a6/394b3e8a82b76b0dd5b6b317f489dfe22426a6 +0 -0
- data/test/test_git.git/objects/a6/5140d5ec9f47064f614ecf8e43776baa5c0c11 +0 -0
- data/test/test_git.git/objects/f5/5f3c44c89e5d215fbaaef9d33563117fe0b61b +0 -1
- data/test/test_git.git/objects/ff/1f1d4bd0c99e1c9cca047c46b2194accf89504 +0 -4
- data/test/test_git.git/refs/heads/master +0 -1
- data/test/test_git.rb +0 -50
- data/test/test_sftp.rb +0 -54
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
require 'dandelion/backend'
|
|
2
1
|
require 'pathname'
|
|
2
|
+
require 'dandelion/utils'
|
|
3
3
|
|
|
4
4
|
module Dandelion
|
|
5
|
-
module
|
|
6
|
-
class SFTP <
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
module Adapter
|
|
6
|
+
class SFTP < Adapter::Base
|
|
7
|
+
include ::Dandelion::Utils
|
|
8
|
+
|
|
9
|
+
adapter 'sftp'
|
|
10
|
+
requires_gems 'net-sftp'
|
|
9
11
|
|
|
10
12
|
def initialize(config)
|
|
11
13
|
require 'net/sftp'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@sftp = Net::SFTP.start(@config['host'], @config['username'], options)
|
|
14
|
+
|
|
15
|
+
@config = config
|
|
16
|
+
@config.defaults(preserve_permissions: true)
|
|
17
|
+
|
|
18
|
+
@sftp = sftp_client
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def read(file)
|
|
@@ -24,7 +25,7 @@ module Dandelion
|
|
|
24
25
|
end
|
|
25
26
|
rescue Net::SFTP::StatusException => e
|
|
26
27
|
raise unless e.code == 2
|
|
27
|
-
|
|
28
|
+
nil
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
@@ -38,9 +39,10 @@ module Dandelion
|
|
|
38
39
|
@sftp.upload!(temp, path(file))
|
|
39
40
|
end
|
|
40
41
|
end
|
|
41
|
-
|
|
42
|
+
|
|
43
|
+
if @config[:preserve_permissions]
|
|
42
44
|
mode = get_mode(file)
|
|
43
|
-
@sftp.setstat!(path(file), :
|
|
45
|
+
@sftp.setstat!(path(file), permissions: mode) if mode
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
|
|
@@ -59,6 +61,15 @@ module Dandelion
|
|
|
59
61
|
|
|
60
62
|
private
|
|
61
63
|
|
|
64
|
+
def sftp_client
|
|
65
|
+
options = {
|
|
66
|
+
password: @config['password'],
|
|
67
|
+
port: @config['port'] || Net::SSH::Transport::Session::DEFAULT_PORT,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Net::SFTP.start(@config['host'], @config['username'], options)
|
|
71
|
+
end
|
|
72
|
+
|
|
62
73
|
def get_mode(file)
|
|
63
74
|
stat = File.stat(file) if File.exists?(file)
|
|
64
75
|
stat.mode if stat
|
|
@@ -78,7 +89,9 @@ module Dandelion
|
|
|
78
89
|
end
|
|
79
90
|
|
|
80
91
|
def empty?(dir)
|
|
81
|
-
@sftp.dir.entries(dir).delete_if
|
|
92
|
+
@sftp.dir.entries(dir).delete_if do |file|
|
|
93
|
+
file.name == '.' or file.name == '..'
|
|
94
|
+
end.empty?
|
|
82
95
|
end
|
|
83
96
|
|
|
84
97
|
def mkdir_p(dir)
|
|
@@ -100,4 +113,4 @@ module Dandelion
|
|
|
100
113
|
end
|
|
101
114
|
end
|
|
102
115
|
end
|
|
103
|
-
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Dandelion
|
|
2
|
+
class Changeset
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
def initialize(tree, commit, options = {})
|
|
6
|
+
@tree = tree
|
|
7
|
+
@commit = commit
|
|
8
|
+
@options = options
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def diff
|
|
12
|
+
Diff.new(@commit, @tree.commit)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def empty?
|
|
16
|
+
diff.empty?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def each
|
|
20
|
+
diff.each do |change|
|
|
21
|
+
if applicable?(change.path)
|
|
22
|
+
path = transform_path(change.path)
|
|
23
|
+
|
|
24
|
+
if change.type == :delete
|
|
25
|
+
yield Change.new(path, change.type)
|
|
26
|
+
else
|
|
27
|
+
yield Change.new(path, change.type, @tree.data(change.path))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def local_path
|
|
36
|
+
@options[:local_path] || ''
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def applicable?(path)
|
|
40
|
+
path.start_with?(local_path)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def transform_path(path)
|
|
44
|
+
trimmed = path[local_path.length..-1]
|
|
45
|
+
trimmed = trimmed[1..-1] if trimmed[0] == File::SEPARATOR
|
|
46
|
+
trimmed
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
|
|
3
|
+
module Dandelion
|
|
4
|
+
class CLI
|
|
5
|
+
def initialize(args)
|
|
6
|
+
@args = args
|
|
7
|
+
@options = {}
|
|
8
|
+
@parser = Command::Base.parser(@options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def config
|
|
12
|
+
@config ||= Config.new(path: config_path).tap do |config|
|
|
13
|
+
config[:adapter] ||= config[:scheme] # backward compat
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def adapter
|
|
18
|
+
@adapter ||= Adapter::Base.create_adapter(config[:adapter], config)
|
|
19
|
+
rescue Adapter::InvalidAdapterError => e
|
|
20
|
+
log.fatal("Unsupported adapter: #{config[:adapter]}")
|
|
21
|
+
exit 1
|
|
22
|
+
rescue Adapter::MissingDependencyError => e
|
|
23
|
+
log.fatal("The #{config[:adapter]} adapter requires additional gems:")
|
|
24
|
+
log.fatal(e.gems.map { |name| " #{name}"}.join("\n"))
|
|
25
|
+
log.fatal("Please install the gems first: gem install #{e.gems.join(' ')}")
|
|
26
|
+
exit 1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def repo
|
|
30
|
+
@repo ||= Rugged::Repository.new(repo_path)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def workspace
|
|
34
|
+
@workspace ||= Workspace.new(repo, adapter, config)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def command_class
|
|
38
|
+
@command_class ||= Command::Base.lookup(@args.shift.to_sym)
|
|
39
|
+
rescue Command::InvalidCommandError => e
|
|
40
|
+
log.fatal("Invalid command: #{e}")
|
|
41
|
+
display_help
|
|
42
|
+
exit 1
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def execute!
|
|
46
|
+
parse!(@parser)
|
|
47
|
+
|
|
48
|
+
if @options[:help]
|
|
49
|
+
display_help
|
|
50
|
+
exit
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if @options[:version]
|
|
54
|
+
log.info("Dandelion #{Dandelion::VERSION}")
|
|
55
|
+
exit
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
validate!
|
|
59
|
+
|
|
60
|
+
parse!(command_class.parser(@options))
|
|
61
|
+
|
|
62
|
+
command = command_class.new(workspace, config, @options)
|
|
63
|
+
command.setup(@args)
|
|
64
|
+
|
|
65
|
+
begin
|
|
66
|
+
command.execute!
|
|
67
|
+
rescue RevisionError => e
|
|
68
|
+
log.fatal("Invalid revision: #{e}")
|
|
69
|
+
exit 1
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def config_path
|
|
76
|
+
@options[:config] || File.join(repo_path, 'dandelion.yml')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def repo_path
|
|
80
|
+
if @options[:repo]
|
|
81
|
+
File.expand_path(@options[:repo])
|
|
82
|
+
else
|
|
83
|
+
closest_repo(File.expand_path('.'))
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def validate!
|
|
88
|
+
unless File.exists?(File.join(repo_path, '.git'))
|
|
89
|
+
log.fatal("Not a git repository: #{repo_path}")
|
|
90
|
+
exit 1
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
unless File.exists?(config_path)
|
|
94
|
+
log.fatal("Missing config file: #{config_path}")
|
|
95
|
+
exit 1
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def parse!(parser)
|
|
100
|
+
begin
|
|
101
|
+
parser.order!(@args)
|
|
102
|
+
rescue OptionParser::InvalidOption => e
|
|
103
|
+
log.fatal(e.to_s.capitalize)
|
|
104
|
+
display_help
|
|
105
|
+
exit 1
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def closest_repo(dir)
|
|
110
|
+
if File.exists?(File.join(dir, '.git'))
|
|
111
|
+
dir
|
|
112
|
+
else
|
|
113
|
+
File.dirname(dir) != dir && closest_repo(File.dirname(dir)) || File.expand_path('.')
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def display_help
|
|
118
|
+
log.info(@parser.help)
|
|
119
|
+
log.info("Available commands:")
|
|
120
|
+
log.info(Command::Base.commands.map { |c| " #{c}"}.join("\n"))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def log
|
|
124
|
+
Dandelion.logger
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/dandelion/command.rb
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
require 'dandelion'
|
|
2
|
-
require 'dandelion/backend'
|
|
3
|
-
require 'dandelion/deployment'
|
|
4
|
-
require 'dandelion/git'
|
|
5
|
-
require 'dandelion/version'
|
|
6
1
|
require 'optparse'
|
|
7
|
-
require 'yaml'
|
|
8
2
|
|
|
9
3
|
module Dandelion
|
|
10
4
|
module Command
|
|
@@ -18,123 +12,63 @@ module Dandelion
|
|
|
18
12
|
@@commands[name] = self
|
|
19
13
|
end
|
|
20
14
|
|
|
21
|
-
def create(name)
|
|
22
|
-
require_commands
|
|
23
|
-
raise InvalidCommandError unless @@commands.include?(name)
|
|
24
|
-
@@commands[name]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
15
|
def commands
|
|
28
16
|
@@commands.keys
|
|
29
17
|
end
|
|
30
18
|
|
|
31
|
-
def
|
|
32
|
-
|
|
19
|
+
def lookup(name)
|
|
20
|
+
raise InvalidCommandError.new(name) unless @@commands[name]
|
|
21
|
+
@@commands[name]
|
|
33
22
|
end
|
|
34
23
|
|
|
35
24
|
def parser(options)
|
|
36
25
|
OptionParser.new do |opts|
|
|
37
26
|
opts.banner = 'Usage: dandelion [options] <command> [<args>]'
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
options[:version] = false
|
|
29
|
+
opts.on('-v', '--version', 'Dispay the current version') do
|
|
30
|
+
options[:version] = true
|
|
42
31
|
end
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
puts "\nAvailable commands:"
|
|
48
|
-
puts commands.map { |name| " #{name}" }.join("\n")
|
|
49
|
-
exit
|
|
33
|
+
options[:help] = false
|
|
34
|
+
opts.on('-h', '--help', 'Display this help info') do
|
|
35
|
+
options[:help] = true
|
|
50
36
|
end
|
|
51
37
|
|
|
52
|
-
|
|
53
|
-
levels = {
|
|
54
|
-
:fatal => Logger::FATAL,
|
|
55
|
-
:error => Logger::ERROR,
|
|
56
|
-
:warn => Logger::WARN,
|
|
57
|
-
:info => Logger::INFO,
|
|
58
|
-
:debug => Logger::DEBUG
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
Dandelion.logger.level = levels[level.to_sym]
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
options[:repo] = closest_repo(File.expand_path('.'))
|
|
38
|
+
options[:repo] = nil
|
|
65
39
|
opts.on('--repo=[REPO]', 'Use the given repository') do |repo|
|
|
66
|
-
options[:repo] =
|
|
40
|
+
options[:repo] = repo
|
|
67
41
|
end
|
|
68
42
|
|
|
69
43
|
options[:config] = nil
|
|
70
|
-
opts.on('--config=[CONFIG]', 'Use the given
|
|
71
|
-
options[:config] =
|
|
44
|
+
opts.on('--config=[CONFIG]', 'Use the given config file') do |config|
|
|
45
|
+
options[:config] = config
|
|
72
46
|
end
|
|
73
47
|
end
|
|
74
48
|
end
|
|
75
|
-
|
|
76
|
-
private
|
|
77
|
-
|
|
78
|
-
def closest_repo(dir)
|
|
79
|
-
if File.exists?(File.join(dir, '.git'))
|
|
80
|
-
dir
|
|
81
|
-
else
|
|
82
|
-
File.dirname(dir) != dir && closest_repo(File.dirname(dir)) || File.expand_path('.')
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
49
|
end
|
|
86
50
|
|
|
87
|
-
|
|
88
|
-
@options = options
|
|
89
|
-
@config = YAML.load_file(@options[:config])
|
|
90
|
-
@repo = Git::Repo.new(@options[:repo])
|
|
51
|
+
attr_reader :workspace, :config, :options
|
|
91
52
|
|
|
92
|
-
|
|
53
|
+
def initialize(workspace, config, options = {})
|
|
54
|
+
@workspace = workspace
|
|
55
|
+
@config = config
|
|
56
|
+
@options = options
|
|
93
57
|
end
|
|
94
58
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def log
|
|
98
|
-
Dandelion.logger
|
|
59
|
+
def setup(args)
|
|
99
60
|
end
|
|
100
61
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
backend = Backend::Base.create(@config)
|
|
104
|
-
log.info("Connecting to #{backend}")
|
|
105
|
-
backend
|
|
106
|
-
rescue Backend::MissingDependencyError => e
|
|
107
|
-
log.fatal("The '#{@config['scheme']}' scheme requires additional gems:")
|
|
108
|
-
log.fatal(e.gems.map { |name| " #{name}" }.join("\n"))
|
|
109
|
-
log.fatal("Please install the gems: gem install #{e.gems.join(' ')}")
|
|
110
|
-
exit 1
|
|
111
|
-
rescue Backend::UnsupportedSchemeError
|
|
112
|
-
log.fatal("Unsupported scheme: #{@config['scheme']}")
|
|
113
|
-
exit 1
|
|
114
|
-
end
|
|
62
|
+
def adapter
|
|
63
|
+
workspace.adapter
|
|
115
64
|
end
|
|
116
65
|
|
|
117
|
-
def
|
|
118
|
-
|
|
119
|
-
backend ||= backend()
|
|
120
|
-
revision_file = @config['revision_file'].nil? ? '.revision' : @config['revision_file']
|
|
121
|
-
local_path = @config['local_path'].nil? ? '' : @config['local_path']
|
|
122
|
-
options = {
|
|
123
|
-
:dry => @options[:dry],
|
|
124
|
-
:exclude => @config['exclude'],
|
|
125
|
-
:additional => @config['additional'],
|
|
126
|
-
:revision => revision,
|
|
127
|
-
:revision_file => revision_file,
|
|
128
|
-
:local_path => local_path
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
Deployment::Deployment.create(@repo, backend, options)
|
|
132
|
-
rescue Git::DiffError
|
|
133
|
-
log.fatal('Error: could not generate diff')
|
|
134
|
-
log.fatal('Try merging remote changes before running dandelion again')
|
|
135
|
-
exit 1
|
|
136
|
-
end
|
|
66
|
+
def log
|
|
67
|
+
Dandelion.logger
|
|
137
68
|
end
|
|
138
69
|
end
|
|
139
70
|
end
|
|
140
71
|
end
|
|
72
|
+
|
|
73
|
+
require 'dandelion/command/deploy'
|
|
74
|
+
require 'dandelion/command/status'
|
|
@@ -1,54 +1,67 @@
|
|
|
1
1
|
module Dandelion
|
|
2
2
|
module Command
|
|
3
3
|
class Deploy < Command::Base
|
|
4
|
-
command
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
options[:force] = true
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
options[:dry] = false
|
|
17
|
-
opts.on('--dry-run', 'Show what would have been deployed') do
|
|
18
|
-
options[:dry] = true
|
|
19
|
-
end
|
|
4
|
+
command :deploy
|
|
5
|
+
|
|
6
|
+
def self.parser(options)
|
|
7
|
+
OptionParser.new do |opts|
|
|
8
|
+
opts.banner = 'Usage: dandelion deploy [options] [<revision>]'
|
|
9
|
+
|
|
10
|
+
options[:dry] = false
|
|
11
|
+
opts.on('--dry-run', 'Show what would have been deployed') do
|
|
12
|
+
options[:dry] = true
|
|
20
13
|
end
|
|
21
14
|
end
|
|
22
15
|
end
|
|
23
|
-
|
|
16
|
+
|
|
24
17
|
def setup(args)
|
|
25
|
-
|
|
18
|
+
config[:revision] = args.shift || nil
|
|
26
19
|
end
|
|
27
|
-
|
|
28
|
-
def execute
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
exit 1
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
log.info("Remote revision: #{@deployment.remote_revision || '---'}")
|
|
37
|
-
log.info("Deploying revision: #{@deployment.local_revision}")
|
|
20
|
+
|
|
21
|
+
def execute!
|
|
22
|
+
log.info("Connecting to #{adapter.to_s}")
|
|
23
|
+
|
|
24
|
+
local_commit = workspace.local_commit
|
|
25
|
+
remote_commit = workspace.remote_commit
|
|
38
26
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
27
|
+
log.info("Remote revision: #{remote_commit ? remote_commit.oid : '---'}")
|
|
28
|
+
log.info("Deploying revision: #{local_commit.oid}")
|
|
29
|
+
|
|
30
|
+
deploy_changeset!
|
|
31
|
+
deploy_additional_files!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def deployer_adapter
|
|
35
|
+
if options[:dry]
|
|
36
|
+
Adapter::NoOpAdapter.new(config)
|
|
37
|
+
else
|
|
38
|
+
adapter
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def deployer
|
|
43
|
+
@deployer ||= Deployer.new(deployer_adapter, config)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def deploy_changeset!
|
|
49
|
+
changeset = workspace.changeset
|
|
50
|
+
|
|
51
|
+
if changeset.empty?
|
|
52
|
+
log.info("No changes to deploy")
|
|
53
|
+
else
|
|
54
|
+
log.info("Deploying changes...")
|
|
55
|
+
deployer.deploy_changeset!(workspace.changeset)
|
|
56
|
+
workspace.remote_commit = workspace.local_commit unless options[:dry]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def deploy_additional_files!
|
|
61
|
+
if config[:additional] && config[:additional].length > 0
|
|
62
|
+
log.info("Deploying additional files...")
|
|
63
|
+
deployer.deploy_files!(config[:additional])
|
|
48
64
|
end
|
|
49
|
-
|
|
50
|
-
@deployment.deploy
|
|
51
|
-
log.info("Deployment complete")
|
|
52
65
|
end
|
|
53
66
|
end
|
|
54
67
|
end
|