Skip to content

Instantly share code, notes, and snippets.

@sawanoboly
Created August 2, 2012 09:51
Show Gist options
  • Save sawanoboly/3235998 to your computer and use it in GitHub Desktop.
Save sawanoboly/3235998 to your computer and use it in GitHub Desktop.
Checking config structure when deploy with capistrano.
# -*- coding: utf-8 -*-
# Capistranoのデプロイ時にコンフィグを作成する、作成元は "*.sample"ファイル
#
# 各環境用の設定を上書きした後、キー及びバリューのクラス、階層を元のsampleと比較し、
# 文字・数字の区別がついていることなどを確認する。
#
# TODO:Capistranoのモジュールにしたい
require 'yaml'
require 'json'
class ConfigContainer
attr_reader :path
attr_accessor :newconfig, :valid
def initialize(sample_name)
# NEEDHELP: newconfigにdupでコピーしているのに、@sampleconfigがどんどん汚染される
# compare_baseを作って回避しているが変な感じ。
@path = sample_name
begin
@sampleconfig = JSON.parse(File.read("#{sample_name}.sample"))
@compare_base = JSON.parse(File.read("#{sample_name}.sample"))
@newconfig = @sampleconfig.dup
rescue JSON::ParserError
@sampleconfig = YAML.load_file("#{sample_name}.sample")
@compare_base = YAML.load_file("#{sample_name}.sample")
@newconfig = @sampleconfig.dup
ensure
@valid = false
end
end
# NOTE: ステージ変更に悩んだが結局Keyのリネームに落ち着いた
def config_cast_stage(sample_env, stage)
## If a config needs environment.
@newconfig[stage] = @newconfig.delete(sample_env)
end
def compare_configs
begin
_compare_hash_all(@compare_base,@newconfig)
rescue => e
return "#{e.class}: #{e.message}"
else
@valid = true
end
end
# CONFUSED: config_cast_stage を通すと"development"キーでエラーとなるので
# その下だけ比較するものを用意した
def compare_configs_withenv(sample_env, stage)
begin
_compare_hash_all(@compare_base[sample_env],@newconfig[stage])
rescue => e
return "#{e.class}: #{e.message}"
else
@valid = true
end
end
private
# written by id:sutetotanuki
def _compare_hash_all(cf1, cf2, context = [])
case
when cf1.is_a?(Hash)
cf1.each do |key, value|
unless cf2.key?(key)
raise "Missing key : #{key} in path #{context.join(".")}"
next
end
value2 = cf2[key]
if (value.class != value2.class)
raise "Key value type mismatch : #{key} in path #{context.join(".")}"
next
end
if value.is_a?(Hash)
_compare_hash_all(value, cf2[key], (context << key))
next
end
end
when cf1.is_a?(Array)
cf1.each do |key|
if key.is_a?(Hash)
_compare_hash_all(key, cf2[key], (context << key))
next
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment