Skip to content

Commit

Permalink
Add support for spec name (#12)
Browse files Browse the repository at this point in the history
* Support spec name in config #11

* Remove debug code

* Add custom stringify_keys

* Fix a bunch of rubocop issues

* Fix another bunch of issues

* Fix a fatal bug and bump beta2

* Doc about specs [ci skip]

* Add conf migration message

* Bump 1.0.0 beta3
  • Loading branch information
crispgm committed Sep 3, 2018
1 parent db1d8cf commit e583bb8
Show file tree
Hide file tree
Showing 14 changed files with 186 additions and 52 deletions.
2 changes: 2 additions & 0 deletions .rubocop.yml
Expand Up @@ -2,3 +2,5 @@ Style/StringLiterals:
Enabled: false
Metrics/MethodLength:
Max: 30
Style/Documentation:
Enabled: false
43 changes: 35 additions & 8 deletions README.md
Expand Up @@ -31,6 +31,7 @@ $ caravan --help
-o, --once Deploy for once
-b, --debug Debug mode
-l, --load YAML_FILE YAML file (Default: ./caravan.yml)
-c, --spec SPEC_NAME Spec name (Default: master)
--version Show version
```

Expand Down Expand Up @@ -65,13 +66,14 @@ $ caravan --init

A `caravan.yml` will be generated as `/path/to/src/caravan.yml`. You may specify any options in command arguments except source path.

```
debug: false
deploy_mode: rsync_local
incremental: true
exclude:
- ".git"
- ".svn"
```yaml
master:
debug: false
deploy_mode: rsync_local
incremental: true
exclude:
- ".git"
- ".svn"
```

You may also write `src` and `dst` to `caravan.yml`. Hence, deployment made even easier.
Expand All @@ -86,6 +88,31 @@ $ caravan
$ caravan --load my-caravan.yml
```

`caravan.yml` can work with multi specs. The default spec is `master` and you may declare others.

```yaml
master:
src: .
dst: /path/to/dst
debug: false
deploy_mode: rsync_local
incremental: true
exclude:
- ".git"
- ".svn"
debugmode:
src: .
dst: /path/to/dst
debug: true
deploy_mode: rsync
incremental: true
```

```
$ caravan -c master
$ caravan -c debugmode
```

### Deploy Modes

* Shell
Expand All @@ -108,7 +135,7 @@ $ caravan --load my-caravan.yml
- [x] `before_deploy`
- [x] `after_deploy`
- [x] `before_destroy`
- [ ] ~~Multiple deployment configurations~~
- [x] Multiple deployment configurations
- [ ] Extension to deploy methods

## License
Expand Down
1 change: 0 additions & 1 deletion docs/Gemfile
Expand Up @@ -28,4 +28,3 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.0" if Gem.win_platform?

35 changes: 27 additions & 8 deletions exe/caravan
Expand Up @@ -6,6 +6,7 @@ require "optparse"
require "caravan"

options = {}
# rubocop:disable Metrics/BlockLength
option_parser = OptionParser.new do |opts|
opts.banner = "Caravan #{Caravan::VERSION}\nCopyright (c) David Zhang 2018\n"
opts.separator ""
Expand All @@ -14,6 +15,10 @@ option_parser = OptionParser.new do |opts|
options[:yaml] = value
end

opts.on("-c SPEC_NAME", "--spec SPEC_NAME", "Spec name") do |value|
options[:spec] = value
end

opts.on("-s SOURCE_PATH", "--source SOURCE_PATH", "Source path") do |value|
options[:src] = value
end
Expand Down Expand Up @@ -53,19 +58,33 @@ option_parser = OptionParser.new do |opts|
exit
end
end
# rubocop:enable Metrics/BlockLength

if ARGV.length == 0
merged_conf = Caravan::Config.merge({}, Caravan.process_conf("."))
default_spec_name = Caravan::Config.default_spec_name

if ARGV.length.zero?
merged_conf = Caravan::Config.merge({}, Caravan.process_conf("."), default_spec_name)
else
option_parser.parse!(ARGV)
if options.key?(:yaml)
merged_conf = Caravan::Config.merge(options, Caravan.process_conf(options[:src], options[:yaml]))
else
merged_conf = Caravan::Config.merge(options, Caravan.process_conf(options[:src]))
end
spec_name = options[:spec] || default_spec_name
merged_conf = if options.key?(:yaml)
Caravan::Config.merge(
options,
Caravan.process_conf(options[:src], options[:yaml]),
spec_name
)
else
Caravan::Config.merge(
options,
Caravan.process_conf(options[:src]),
spec_name
)
end
end

if merged_conf.key?("src") && merged_conf.key?("dst") && merged_conf.key?("deploy_mode")
if merged_conf.key?("src") &&
merged_conf.key?("dst") &&
merged_conf.key?("deploy_mode")
Caravan.start(merged_conf)
else
Caravan::Message.error("No src, dst, deploy_mode specified. Cannot deploy.")
Expand Down
18 changes: 16 additions & 2 deletions lib/caravan.rb
@@ -1,5 +1,6 @@
require "caravan/command"
require "caravan/config"
require "caravan/config_migration"
require "caravan/deploy"
require "caravan/deploy_methods/shell"
require "caravan/deploy_methods/scp"
Expand All @@ -21,7 +22,11 @@ def start(merged_conf)

Caravan::Config.pretty_puts(merged_conf)

deployer = Caravan::Deploy.create_deployer(src_path, target_path, deploy_mode)
deployer = Caravan::Deploy.create_deployer(
src_path,
target_path,
deploy_mode
)
deployer.debug = true if debug
exit(-1) if deployer.nil?

Expand Down Expand Up @@ -62,6 +67,7 @@ def create_listener(deployer, src_path)
return unless deployer.before_deploy
deployer.run
deployer.after_deploy
# rubocop:enable Lint/NonLocalExitFromIterator
end
end

Expand All @@ -70,6 +76,11 @@ def process_conf(src_path, yaml_name = Caravan::Config.default_conf_name)
src_path = '.' if src_path.nil?
user_config_path = File.join(File.expand_path(src_path), yaml_name)
conf = Caravan::Config.from(user_config_path)
Caravan::Message.warn(
"Caravan now support multiple specs in `caravan.yml`. " \
"The default spec is `master`. " \
"And we detect that you may need to migrate."
) if Caravan::ConfigMigration.need_migrate?(conf)
conf
end

Expand All @@ -78,7 +89,10 @@ def sleep_forever
end

def dump_default_conf
user_config_path = File.join(File.expand_path("."), Caravan::Config.default_conf_name)
user_config_path = File.join(
File.expand_path("."),
Caravan::Config.default_conf_name
)
default_conf = Caravan::Config.default_conf

Caravan::Config.dump(user_config_path, default_conf)
Expand Down
2 changes: 1 addition & 1 deletion lib/caravan/command.rb
Expand Up @@ -4,7 +4,7 @@ class << self
def run(cmd, debug = false)
output = `#{cmd}`
Caravan::Message.debug(cmd) if debug
return $?.exitstatus, output
return $CHILD_STATUS.exitstatus, output
end
end
end
Expand Down
47 changes: 34 additions & 13 deletions lib/caravan/config.rb
Expand Up @@ -3,16 +3,19 @@
module Caravan
class Config < Hash
DEFAULT_CONFIG = {
"debug" => false,
"deploy_mode" => "rsync",
"incremental" => true,
"exclude" => %w(
.git .svn
),
"once" => false
"master" => {
"debug" => false,
"deploy_mode" => "rsync",
"incremental" => true,
"exclude" => %w(
.git .svn
),
"once" => false
}
}.freeze

DEFAULT_CONFIG_NAME = "caravan.yml".freeze
DEFAULT_SPEC_NAME = "master".freeze

class << self
def default_conf
Expand All @@ -23,6 +26,10 @@ def default_conf_name
DEFAULT_CONFIG_NAME
end

def default_spec_name
DEFAULT_SPEC_NAME
end

def from(user_config_path)
if File.exist?(user_config_path)
YAML.load_file(user_config_path)
Expand All @@ -34,20 +41,24 @@ def from(user_config_path)
end

def dump(user_config_path, user_config)
# rubocop:disable Metrics/LineLength
File.open(user_config_path, "w") do |f|
f.write("# Generated Caravan's configuration file.\n")
f.write("# Use `caravan --help` for instructions on all the configuration values.\n")
f.write("# Add `src` and `dst` to specify the source and destination.\n")
f.write(user_config.to_yaml)
end
# rubocop:enable Metrics/LineLength
end

def merge(options, conf)
if conf.nil?
merged_conf = Caravan::Config.default_conf
else
merged_conf = conf
end
def merge(options, conf, spec = Caravan::Config.default_spec_name)
merged_conf = if conf.nil?
Caravan::Message.warn("Fail to load conf. Use default instead.")
default_spec_name = Caravan::Config.default_spec_name
Caravan::Config.default_conf[default_spec_name]
else
stringify_keys(conf)[spec]
end

merged_conf["src"] = options[:src] if options.key?(:src)
merged_conf["dst"] = options[:dst] if options.key?(:dst)
Expand All @@ -64,6 +75,16 @@ def pretty_puts(conf)
Caravan::Message.info("=> #{k}: #{v}")
end
end

private

def stringify_keys(conf)
new_conf = {}
conf.each do |sym, v|
new_conf[sym.to_s] = v
end
new_conf
end
end
end
end
18 changes: 18 additions & 0 deletions lib/caravan/config_migration.rb
@@ -0,0 +1,18 @@
module Caravan
class ConfigMigration
class << self
def need_migrate?(conf)
return true if conf.nil? || conf.empty?

if !conf.key?("src") ||
!conf.key?("dst") ||
!conf.key?("deploy_mode")
Caravan::Message.debug("Conf may need migrate.")
return true
end

false
end
end
end
end
8 changes: 5 additions & 3 deletions lib/caravan/deploy.rb
Expand Up @@ -89,11 +89,11 @@ def run

status = 0
if block_given?
status, output = yield src, dst
status, _output = yield src, dst
debug_msg("Block `run` returned #{status}")
end

Message.error("Deploying block returned false") unless status == 0
Message.error("Deploying block returned false") unless status.zero?
status
end

Expand All @@ -120,7 +120,9 @@ def before_destroy
def relative_path(path)
working_dir = Dir.pwd
path_routes = path.split(working_dir)
return nil if path_routes.nil? || path_routes.empty? || path_routes.size < 2
return nil if path_routes.nil? ||
path_routes.empty? ||
path_routes.size < 2

path_routes[-1]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/caravan/version.rb
@@ -1,3 +1,3 @@
module Caravan
VERSION = "0.7.0".freeze
VERSION = "1.0.0.beta3".freeze
end
25 changes: 25 additions & 0 deletions test/conf_mig_test.rb
@@ -0,0 +1,25 @@
require "test_helper"

class ConfMigTest < CaravanTest
context "need migrate" do
should "return true of nil or empty" do
assert_equal(true, Caravan::ConfigMigration.need_migrate?(nil))
assert_equal(true, Caravan::ConfigMigration.need_migrate?({}))
end

should "return true" do
conf = {}
conf["debug"]= true,
assert_equal(true, Caravan::ConfigMigration.need_migrate?(conf))
end

should "return false" do
conf = {}
conf["debug"]= true,
conf["src"] = "."
conf["dst"] = "dummy"
conf["deploy_mode"] = "rsync"
assert_equal(false, Caravan::ConfigMigration.need_migrate?(conf))
end
end
end

0 comments on commit e583bb8

Please sign in to comment.