dply 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +54 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +2 -0
- data/bin/dplyr +76 -0
- data/bin/drake +84 -0
- data/code_dump/alt_remote_task.rb +119 -0
- data/code_dump/old_remote_task.rb +146 -0
- data/dply.gemspec +22 -0
- data/lib/dply.rb +5 -0
- data/lib/dply/cli/deploy.rb +69 -0
- data/lib/dply/config.rb +102 -0
- data/lib/dply/custom_logger.rb +29 -0
- data/lib/dply/deploy.rb +33 -0
- data/lib/dply/dplyr.rb +45 -0
- data/lib/dply/error.rb +4 -0
- data/lib/dply/ext/string.rb +33 -0
- data/lib/dply/git.rb +43 -0
- data/lib/dply/helper.rb +35 -0
- data/lib/dply/linker.rb +71 -0
- data/lib/dply/lock.rb +24 -0
- data/lib/dply/logger.rb +27 -0
- data/lib/dply/release.rb +34 -0
- data/lib/dply/remote_task.rb +139 -0
- data/lib/dply/repo.rb +31 -0
- data/lib/dply/report.rb +65 -0
- data/lib/dply/setup.rb +12 -0
- data/lib/dply/setup/default.rb +31 -0
- data/lib/dply/setup/git.rb +52 -0
- data/lib/dply/setup/release.rb +58 -0
- data/lib/dply/shared_dirs.rb +28 -0
- data/lib/dply/shell.rb +47 -0
- data/lib/dply/stages_config.rb +94 -0
- data/lib/dply/strategy.rb +12 -0
- data/lib/dply/strategy/default.rb +50 -0
- data/lib/dply/strategy/git.rb +85 -0
- data/lib/dply/tasks.rb +37 -0
- data/lib/dply/version.rb +3 -0
- metadata +112 -0
data/dply.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dply/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dply"
|
8
|
+
spec.version = Dply::VERSION
|
9
|
+
spec.authors = ["Neeraj"]
|
10
|
+
spec.summary = %q{rake based deploy tool}
|
11
|
+
spec.description = %q{rake based deploy tool}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
end
|
data/lib/dply.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'dply/deploy'
|
2
|
+
require 'dply/logger'
|
3
|
+
require 'dply/lock'
|
4
|
+
|
5
|
+
module Dply
|
6
|
+
module Cli
|
7
|
+
class Deploy
|
8
|
+
|
9
|
+
include Logger
|
10
|
+
|
11
|
+
attr_reader :deploy_dir, :argv
|
12
|
+
|
13
|
+
def initialize(deploy_dir, argv)
|
14
|
+
@deploy_dir = deploy_dir
|
15
|
+
@argv = argv
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
lock.acquire
|
20
|
+
opts.parse!(argv)
|
21
|
+
target = argv.shift
|
22
|
+
deploy.config.target = target if target
|
23
|
+
deploy.options = options
|
24
|
+
deploy.run
|
25
|
+
end
|
26
|
+
|
27
|
+
def deploy
|
28
|
+
@deploy ||= ::Dply::Deploy.new(deploy_dir)
|
29
|
+
end
|
30
|
+
|
31
|
+
def lock
|
32
|
+
@lock ||= ::Dply::Lock.new(deploy_dir)
|
33
|
+
end
|
34
|
+
|
35
|
+
def opts
|
36
|
+
OptionParser.new do |opts|
|
37
|
+
|
38
|
+
opts.banner = "Usage: dply deploy [options] [target]"
|
39
|
+
|
40
|
+
opts.on("-b", "--branch [BRANCH]" , "Specify git branch") do |b|
|
41
|
+
options[:branch] = b
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("--no-pull", "Enable/disable git pull") do |e|
|
45
|
+
options[:no_pull] = true
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("--skip-git", "Disable git") do |e|
|
49
|
+
options[:skip_git] = true
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("--skip-bundler", "Skip bundle install") do |e|
|
53
|
+
options[:skip_bundler] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("-h", "--help", "Help") do
|
57
|
+
puts opts
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def options
|
64
|
+
@options ||= {}
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/dply/config.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'dply/helper'
|
3
|
+
|
4
|
+
module Dply
|
5
|
+
class Config
|
6
|
+
|
7
|
+
include Helper
|
8
|
+
attr_reader :deploy_dir, :config_file_required
|
9
|
+
|
10
|
+
def initialize(deploy_dir, config_file_required: true)
|
11
|
+
@deploy_dir = deploy_dir
|
12
|
+
@config_file_required = config_file_required
|
13
|
+
end
|
14
|
+
|
15
|
+
def config
|
16
|
+
return @config if @config
|
17
|
+
@config = {
|
18
|
+
deploy_dir: deploy_dir,
|
19
|
+
target: :default,
|
20
|
+
branch: :master,
|
21
|
+
strategy: :default,
|
22
|
+
repo: nil,
|
23
|
+
env: {},
|
24
|
+
link_config: false,
|
25
|
+
config_map: nil,
|
26
|
+
dir_map: nil,
|
27
|
+
shared_dirs: []
|
28
|
+
}
|
29
|
+
read_from_file
|
30
|
+
return @config
|
31
|
+
end
|
32
|
+
|
33
|
+
def target(target)
|
34
|
+
set :target, target
|
35
|
+
end
|
36
|
+
|
37
|
+
def branch(branch)
|
38
|
+
set :branch, branch
|
39
|
+
end
|
40
|
+
|
41
|
+
def strategy(strategy)
|
42
|
+
set :strategy, strategy
|
43
|
+
end
|
44
|
+
|
45
|
+
def repo(repo)
|
46
|
+
set :repo, repo
|
47
|
+
end
|
48
|
+
|
49
|
+
def link_config(link_config)
|
50
|
+
set :link_config, link_config
|
51
|
+
end
|
52
|
+
|
53
|
+
def config_map(map)
|
54
|
+
set :link_config, true
|
55
|
+
set :config_map, map
|
56
|
+
end
|
57
|
+
|
58
|
+
def dir_map(map)
|
59
|
+
set :dir_map, map
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_env(key, value)
|
63
|
+
@config[:env].store key, value
|
64
|
+
end
|
65
|
+
|
66
|
+
def set(key, value)
|
67
|
+
@config.store key, value
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_struct
|
71
|
+
OpenStruct.new(config)
|
72
|
+
end
|
73
|
+
|
74
|
+
def env(h)
|
75
|
+
raise if not h.is_a? Hash
|
76
|
+
@config[:env] = h
|
77
|
+
@config[:env].each do |k,v|
|
78
|
+
ENV[k.to_s] = v.to_s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def config_file
|
83
|
+
@config_file ||= "#{deploy_dir}/dply.rb"
|
84
|
+
end
|
85
|
+
|
86
|
+
def shared_dirs(dirs)
|
87
|
+
raise if not dirs.is_a? Array
|
88
|
+
@config[:shared_dirs] = dirs
|
89
|
+
end
|
90
|
+
|
91
|
+
def read_from_file
|
92
|
+
if not File.readable? config_file
|
93
|
+
raise error "dply.rb not found in #{deploy_dir}" if config_file_required
|
94
|
+
return
|
95
|
+
end
|
96
|
+
instance_eval(File.read(config_file))
|
97
|
+
rescue NoMethodError => e
|
98
|
+
raise error "invalid option used in config: #{e.name}"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'dply/ext/string'
|
3
|
+
module Dply
|
4
|
+
class CustomLogger < ::Logger
|
5
|
+
|
6
|
+
def initialize(file)
|
7
|
+
super(file)
|
8
|
+
@level = ::Logger::INFO
|
9
|
+
end
|
10
|
+
|
11
|
+
def format_message(severity, timestamp, progname, msg)
|
12
|
+
case severity
|
13
|
+
when "INFO"
|
14
|
+
"#{msg}\n"
|
15
|
+
when "ERROR"
|
16
|
+
"#{severity.bold.red} #{msg}\n"
|
17
|
+
when "WARN"
|
18
|
+
"#{severity.downcase.bold.yellow} #{msg}\n"
|
19
|
+
else
|
20
|
+
"#{severity.downcase.bold.blue} #{msg}\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def bullet(msg)
|
25
|
+
puts "#{"\u2219".bold.blue} #{msg}"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/dply/deploy.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'dply/setup'
|
2
|
+
require 'dply/strategy'
|
3
|
+
require 'dply/config'
|
4
|
+
|
5
|
+
module Dply
|
6
|
+
class Deploy
|
7
|
+
|
8
|
+
attr_reader :deploy_dir
|
9
|
+
attr_writer :options
|
10
|
+
|
11
|
+
def initialize(deploy_dir)
|
12
|
+
@deploy_dir = deploy_dir
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
strategy.deploy
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
@config ||= Config.new(deploy_dir).to_struct
|
21
|
+
end
|
22
|
+
|
23
|
+
def strategy
|
24
|
+
@strategy ||= Strategy.load(config, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def options
|
28
|
+
@options ||= {}
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/dply/dplyr.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'dply/stages_config'
|
2
|
+
require 'dply/remote_task'
|
3
|
+
module Dply
|
4
|
+
class Dplyr
|
5
|
+
|
6
|
+
attr_reader :stage, :argv
|
7
|
+
def initialize(stage, argv)
|
8
|
+
@stage = stage
|
9
|
+
@argv = argv
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
case stage
|
14
|
+
when 'dev'
|
15
|
+
system "drake #{argv_str}"
|
16
|
+
when 'local'
|
17
|
+
system "drake #{argv_str}"
|
18
|
+
else
|
19
|
+
run_remote_task
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def stage_data
|
24
|
+
@stage_data ||= StagesConfig.new("stages.rb").get_stage(stage)
|
25
|
+
end
|
26
|
+
|
27
|
+
def hosts
|
28
|
+
stage_data[:hosts]
|
29
|
+
end
|
30
|
+
|
31
|
+
def parallel_jobs
|
32
|
+
stage_data[:parallel_runs]
|
33
|
+
end
|
34
|
+
|
35
|
+
def argv_str
|
36
|
+
@argv_str ||= argv.join(' ')
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_remote_task
|
40
|
+
remote_task = ::Dply::RemoteTask.new(hosts, argv_str, parallel_jobs: parallel_jobs)
|
41
|
+
remote_task.run
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
data/lib/dply/error.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
class String
|
2
|
+
def colorize(color_code)
|
3
|
+
"\e[#{color_code}m#{self}\e[0m"
|
4
|
+
end
|
5
|
+
|
6
|
+
def bold
|
7
|
+
"\e[1m#{self}\e[0m"
|
8
|
+
end
|
9
|
+
|
10
|
+
def white
|
11
|
+
colorize(37)
|
12
|
+
end
|
13
|
+
|
14
|
+
def green
|
15
|
+
colorize(32)
|
16
|
+
end
|
17
|
+
|
18
|
+
def yellow
|
19
|
+
colorize(33)
|
20
|
+
end
|
21
|
+
|
22
|
+
def red
|
23
|
+
colorize(31)
|
24
|
+
end
|
25
|
+
|
26
|
+
def blue
|
27
|
+
colorize(34)
|
28
|
+
end
|
29
|
+
|
30
|
+
def grey
|
31
|
+
colorize("90")
|
32
|
+
end
|
33
|
+
end
|
data/lib/dply/git.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'dply/shell'
|
2
|
+
module Dply
|
3
|
+
module Git
|
4
|
+
|
5
|
+
extend Shell
|
6
|
+
|
7
|
+
def self.pull(branch)
|
8
|
+
cmd "git fetch"
|
9
|
+
checkout(branch)
|
10
|
+
if tracking_branch = get_tracking_branch(branch)
|
11
|
+
cmd "git merge #{tracking_branch}"
|
12
|
+
else
|
13
|
+
cmd "git pull origin #{branch}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.checkout(branch)
|
18
|
+
current_branch = `git rev-parse --abbrev-ref HEAD `.chomp.to_sym
|
19
|
+
cmd "git checkout #{branch}" if branch != current_branch
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.clone(repo, dir, mirror: nil)
|
23
|
+
cmd "git clone #{repo} #{dir}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.get_tracking_branch(branch)
|
27
|
+
command = "git for-each-ref --format='%(upstream:short)' refs/heads/#{branch} --count=1"
|
28
|
+
tracking_branch = `#{command}`
|
29
|
+
if tracking_branch =~ /[a-zA-Z0-9_]/
|
30
|
+
return tracking_branch.chomp!
|
31
|
+
else
|
32
|
+
return nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.get_remote_url
|
37
|
+
remote_url = cmd "git config --get remote.origin.url", return_output: true, display: false
|
38
|
+
logger.debug remote_url.chomp
|
39
|
+
remote_url.chomp
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
data/lib/dply/helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'dply/tasks'
|
2
|
+
require 'dply/shell'
|
3
|
+
require 'dply/git'
|
4
|
+
require 'dply/error'
|
5
|
+
require 'dply/logger'
|
6
|
+
|
7
|
+
|
8
|
+
module Dply
|
9
|
+
module Helper
|
10
|
+
|
11
|
+
def self.git
|
12
|
+
Git
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.tasks
|
16
|
+
@tasks ||= Tasks.new
|
17
|
+
end
|
18
|
+
|
19
|
+
include Shell
|
20
|
+
include Logger
|
21
|
+
|
22
|
+
def git
|
23
|
+
::Dply::Helper.git
|
24
|
+
end
|
25
|
+
|
26
|
+
def tasks
|
27
|
+
::Dply::Helper.tasks
|
28
|
+
end
|
29
|
+
|
30
|
+
def error(msg)
|
31
|
+
::Dply::Error.new(msg)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/dply/linker.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'dply/helper'
|
2
|
+
module Dply
|
3
|
+
class Linker
|
4
|
+
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
attr_reader :src_dir, :dest_dir, :map, :dir_prefix
|
8
|
+
|
9
|
+
def initialize(src_dir, dest_dir, map: nil, dir_prefix: nil)
|
10
|
+
verify_absolute src_dir, dest_dir
|
11
|
+
@src_dir = src_dir
|
12
|
+
@dest_dir = dest_dir
|
13
|
+
@map = map
|
14
|
+
@dir_prefix = dir_prefix
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_symlinks
|
18
|
+
files.each do |f|
|
19
|
+
link_target = link_target(f)
|
20
|
+
absolute_source_path = absolute_source_path(f)
|
21
|
+
relative_path = absolute_source_path.relative_path_from link_target.parent
|
22
|
+
logger.debug "linking #{link_target} -> #{absolute_source_path}"
|
23
|
+
symlink(relative_path, link_target)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def files
|
28
|
+
@map ? mapped_files : all_files
|
29
|
+
end
|
30
|
+
|
31
|
+
def map
|
32
|
+
@map || default_map
|
33
|
+
end
|
34
|
+
|
35
|
+
def link_target(relative_source)
|
36
|
+
target = map[relative_source]
|
37
|
+
Pathname.new "#{dest_dir}/#{target}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def absolute_source_path(src)
|
41
|
+
Pathname.new "#{src_dir}/#{src}"
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def default_map
|
46
|
+
@h ||= Hash.new do |hash, key|
|
47
|
+
dir_prefix ? "#{dir_prefix}/#{key}" : "#{key}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def all_files
|
52
|
+
Dir.chdir(src_dir) { Dir.glob("*") }
|
53
|
+
end
|
54
|
+
|
55
|
+
def mapped_files
|
56
|
+
map.keys.collect do |k|
|
57
|
+
path = Pathname.new k
|
58
|
+
raise "config map path cannot be absoulte" if path.absolute?
|
59
|
+
k
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def verify_absolute(*paths)
|
64
|
+
paths.each do |path|
|
65
|
+
absolute = Pathname.new(path).absolute?
|
66
|
+
raise "#{path} not absolute" if not absolute
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|