sga_fields_synchronizer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/generators/fields_synchronizer/fields_synchronizer_generator.rb +123 -0
- data/generators/fields_synchronizer/templates/fields_dictionary.example +209 -0
- data/generators/fields_synchronizer/templates/migration.rb +46 -0
- data/lib/fields_reader.rb +33 -0
- data/lib/sga_fields_synchronizer.rb +1 -0
- data/sga_fields_synchronizer.gemspec +58 -0
- data/test/helper.rb +10 -0
- data/test/test_sga_fields_synchronizer.rb +7 -0
- metadata +88 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 tim.teng
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
= sga_fields_synchronizer
|
2
|
+
|
3
|
+
Sometimes we have some table fields change frequently, espically for me, we are now building a flash game, there're many characters table, each has many attributes(fields). Game planners
|
4
|
+
frequently change them, they send me a excel file or whatever, I have to diff it with the previous one, get the changes, put them into migration file and finnally apply to database.
|
5
|
+
It takes me much time and it's really a born job. So, I coded this migration generator to save my time.
|
6
|
+
|
7
|
+
sga_fields_synchronizer is based on a configure file, which defines the table structure, once you have any modification on the table, just edit the yml file, change the column defination,
|
8
|
+
or just remove the node (if you intend to remove the column)
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
gem install sga_fields_synchronizer
|
13
|
+
|
14
|
+
== Usage
|
15
|
+
|
16
|
+
First, run './script/generate fields_synchronizer init' to copy the configure yml into config/ folder
|
17
|
+
|
18
|
+
Second, after you editing the yml file properly, just type './script/generate fields_synchronizer sync' to generate migration file
|
19
|
+
|
20
|
+
Third, invoke 'rake db:migrate' to apply the chages
|
21
|
+
|
22
|
+
You also can generate migrations excluded specified tables with '--skip-table' option, this will automatically excluded tables you specified. By default, sga_fields_synchronizer will skip table "common_fields".
|
23
|
+
|
24
|
+
Once you want to apply DRY principle on your cofigure file, just reference the sample yml file.
|
25
|
+
|
26
|
+
== Configure file
|
27
|
+
|
28
|
+
the root node of the configure file is "configs" by convention, so don't remove that node. the subsequent nodes are tables. Each table field is defined as Array, the first element is the translation
|
29
|
+
the second is the field type, such as string, text, integer, etc. The third element is optional, it stands for column options.
|
30
|
+
|
31
|
+
== Note on Patches/Pull Requests
|
32
|
+
|
33
|
+
* Fork the project.
|
34
|
+
* Make your feature addition or bug fix.
|
35
|
+
* Add tests for it. This is important so I don't break it in a
|
36
|
+
future version unintentionally.
|
37
|
+
* Commit, do not mess with rakefile, version, or history.
|
38
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
39
|
+
* Send me a pull request. Bonus points for topic branches.
|
40
|
+
|
41
|
+
== Copyright
|
42
|
+
|
43
|
+
Copyright (c) 2010 tim.teng. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "sga_fields_synchronizer"
|
8
|
+
gem.summary = %Q{A synchronizer for most frequently edited columns}
|
9
|
+
gem.description = %Q{ A synchronizer for most frequently edited columns based on yml file}
|
10
|
+
gem.email = "tim.rubist@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/tteng/sga_fields_synchronizer"
|
12
|
+
gem.authors = ["tim.teng"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "sga_fields_synchronizer #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'fields_reader'
|
2
|
+
|
3
|
+
class FieldsSynchronizerGenerator < Rails::Generator::Base
|
4
|
+
|
5
|
+
def initialize(runtime_args, runtime_options = {})
|
6
|
+
super
|
7
|
+
@action_to_invoke = runtime_args.shift
|
8
|
+
unless ["init", "sync"].include?(@action_to_invoke)
|
9
|
+
STDOUT.puts 'Invalid arguments!'
|
10
|
+
STDOUT.puts banner
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def manifest
|
16
|
+
recorded_session = record do |m|
|
17
|
+
if(@action_to_invoke == "init")
|
18
|
+
STDOUT.puts ' init ...'
|
19
|
+
unless File.exist? File.join(RAILS_ROOT,'config','fields_dictionary.yml')
|
20
|
+
m.template "fields_dictionary.example", "config/fields_dictionary.yml"
|
21
|
+
else
|
22
|
+
STDOUT.puts "#{RAILS_ROOT}/config/fields_dictionary.yml already exists, override it?(y/n)"
|
23
|
+
if gets.chomp =~ /^y/i
|
24
|
+
m.template "fields_dictionary.example", "config/fields_dictionary.yml"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
elsif(@action_to_invoke == "sync")
|
29
|
+
|
30
|
+
FieldsReader.init
|
31
|
+
skipped_tables = (options[:skipped_table] || []) << "common_fields"
|
32
|
+
dictionary = File.join(RAILS_ROOT,'config','fields_dictionary.yml')
|
33
|
+
STDOUT.puts " skip table: #{skipped_tables.join(',')}"
|
34
|
+
STDOUT.puts " dictionary: #{dictionary}"
|
35
|
+
|
36
|
+
(FieldsReader.keys - skipped_tables).each do |t|
|
37
|
+
model = t.singularize.camelize.constantize
|
38
|
+
table_columns = get_table_columns model
|
39
|
+
target_columns = FieldsReader.send t
|
40
|
+
removed_columns = get_to_be_deleted_columns(table_columns,target_columns)
|
41
|
+
changed_columns = get_changed_columns(table_columns, target_columns)
|
42
|
+
added_columns = get_added_columns(table_columns, target_columns)
|
43
|
+
unless removed_columns.empty? && changed_columns.empty? && added_columns.empty?
|
44
|
+
m.directory "db/migrate"
|
45
|
+
migration_name = "#{migration_prefix}_change_table_#{t}"
|
46
|
+
m.migration_template 'migration.rb', 'db/migrate',
|
47
|
+
:assigns => { :migration_name => migration_name.camelize,
|
48
|
+
:removed_columns => removed_columns,
|
49
|
+
:changed_columns => changed_columns,
|
50
|
+
:added_columns => added_columns,
|
51
|
+
:table_name => t
|
52
|
+
},
|
53
|
+
:migration_file_name => migration_name.camelize
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_options! opt
|
62
|
+
opt.on('--skip-table tab1, tab2, tab3 ', Array, 'tables skipped to do synchronization') do |v|
|
63
|
+
options[:skipped_table] = v
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def banner
|
68
|
+
%Q{
|
69
|
+
Usage: #{$0} init
|
70
|
+
Usage: #{$0} sync [--skip-table t1,[t2 [,t3]]]"
|
71
|
+
Example: #{$0} init
|
72
|
+
#{$0} sync
|
73
|
+
#{$0} sync --skip-table t1, t2, t3
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def get_to_be_deleted_columns tab_cols, tgt_cols
|
80
|
+
tab_cols_dup = tab_cols.dup
|
81
|
+
tab_cols_dup.delete_if{|k,v| tgt_cols.keys.include?(k)}
|
82
|
+
tab_cols_dup
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_table_columns model
|
86
|
+
model.columns.inject({}) do |hash, column|
|
87
|
+
hash[column.name] = column
|
88
|
+
hash
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_changed_columns tab_cols, tgt_cols
|
93
|
+
(tab_cols.keys & tgt_cols.keys).inject({}) do |hash, col|
|
94
|
+
origin_type = tab_cols[col].type.to_s
|
95
|
+
target_type = tgt_cols[col][1]
|
96
|
+
if origin_type == target_type
|
97
|
+
unless(target_col_options = tgt_cols[col][2]).blank?
|
98
|
+
[:null, :default, :limit, :precision, :scale].each do |k|
|
99
|
+
next unless target_col_options.keys.include?(k)
|
100
|
+
if target_col_options[k] != tab_cols[col].send(k)
|
101
|
+
hash[col] = [tgt_cols[col], tab_cols[col]]
|
102
|
+
break
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
else
|
107
|
+
hash[col] = [tgt_cols[col], tab_cols[col]]
|
108
|
+
end
|
109
|
+
hash
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def get_added_columns tab_cols, tgt_cols
|
114
|
+
tgt_dup = tgt_cols.dup
|
115
|
+
tgt_dup.delete_if {|k,v| tab_cols.keys.include?(k)}
|
116
|
+
tgt_dup
|
117
|
+
end
|
118
|
+
|
119
|
+
def migration_prefix
|
120
|
+
"sync_#{Time.now.strftime("%y%b%d%a").underscore}_#{('%0.4f' % rand)[2,4]}"
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# 公共属性, refers: http://sgftrac/trac/wiki/DataDictionary
|
2
|
+
# By TengXianggong, 20100617
|
3
|
+
# 数据结构:
|
4
|
+
|
5
|
+
# 属性名
|
6
|
+
# - 前台显示名称
|
7
|
+
# - 数据类型
|
8
|
+
# - 字段属性(hash)
|
9
|
+
|
10
|
+
|
11
|
+
####################################################
|
12
|
+
############ Shared Fields ########
|
13
|
+
############ Last edited by Tengxianggong ########
|
14
|
+
############ Last edited at Jun 17, 2010 ########
|
15
|
+
####################################################
|
16
|
+
configs:
|
17
|
+
|
18
|
+
common_fields: &common_fields
|
19
|
+
name:
|
20
|
+
- "名称"
|
21
|
+
- "string"
|
22
|
+
job_id:
|
23
|
+
- "职业类型"
|
24
|
+
- "integer"
|
25
|
+
- :limit: 10
|
26
|
+
:default: 1
|
27
|
+
level:
|
28
|
+
- "等级"
|
29
|
+
- "integer"
|
30
|
+
- :default: 1
|
31
|
+
health_point:
|
32
|
+
- "生命值"
|
33
|
+
- "integer"
|
34
|
+
max_health_point:
|
35
|
+
- "生命上限"
|
36
|
+
- "integer"
|
37
|
+
magic_point:
|
38
|
+
- "魔法值"
|
39
|
+
- "integer"
|
40
|
+
max_magic_point:
|
41
|
+
- "魔法上限"
|
42
|
+
- "integer"
|
43
|
+
max_attack_point:
|
44
|
+
- "最大攻击力"
|
45
|
+
- "integer"
|
46
|
+
min_attack_point:
|
47
|
+
- "最小攻击力"
|
48
|
+
- "integer"
|
49
|
+
max_magic_attack_point:
|
50
|
+
- "最大法术攻击力"
|
51
|
+
- "integer"
|
52
|
+
min_magic_attack_point:
|
53
|
+
- "最小法术攻击力"
|
54
|
+
- "integer"
|
55
|
+
max_defence_point:
|
56
|
+
- "最大防御力"
|
57
|
+
- "integer"
|
58
|
+
min_defence_point:
|
59
|
+
- "最小防御力"
|
60
|
+
- "integer"
|
61
|
+
max_magic_defence_point:
|
62
|
+
- "最大法术防御力"
|
63
|
+
- "integer"
|
64
|
+
min_magic_defence_point:
|
65
|
+
- "最小法术防御力"
|
66
|
+
- "integer"
|
67
|
+
health_restore_speed:
|
68
|
+
- "生命恢复"
|
69
|
+
- "integer"
|
70
|
+
magic_restore_speed:
|
71
|
+
- "法力恢复"
|
72
|
+
- "integer"
|
73
|
+
attack_hit_rate:
|
74
|
+
- "物理命中率"
|
75
|
+
- "integer"
|
76
|
+
magic_hit_rate:
|
77
|
+
- "魔法命中率"
|
78
|
+
- "integer"
|
79
|
+
attack_dodge_rate:
|
80
|
+
- "物理闪避率"
|
81
|
+
- "integer"
|
82
|
+
magic_dodge_rate:
|
83
|
+
- "魔法闪避率"
|
84
|
+
- "integer"
|
85
|
+
power_hit_rate:
|
86
|
+
- "暴击率"
|
87
|
+
- "integer"
|
88
|
+
power_hit_point:
|
89
|
+
- "暴击威力"
|
90
|
+
- "integer"
|
91
|
+
explode_point:
|
92
|
+
- "爆发值"
|
93
|
+
- "integer"
|
94
|
+
luck_point:
|
95
|
+
- "幸运值"
|
96
|
+
- "integer"
|
97
|
+
defence_rate:
|
98
|
+
- "伤害减免概率"
|
99
|
+
- "integer"
|
100
|
+
defence_level:
|
101
|
+
- "伤害减免等级"
|
102
|
+
- "integer"
|
103
|
+
move_speed:
|
104
|
+
- "行走速度"
|
105
|
+
- "integer"
|
106
|
+
attack_speed:
|
107
|
+
- "攻击速度"
|
108
|
+
- "integer"
|
109
|
+
fire_attack:
|
110
|
+
- "火属性伤害"
|
111
|
+
- "integer"
|
112
|
+
thunder_attack:
|
113
|
+
- "雷属性伤害"
|
114
|
+
- "integer"
|
115
|
+
ice_attack:
|
116
|
+
- "冰属性伤害"
|
117
|
+
- "integer"
|
118
|
+
poison_attack:
|
119
|
+
- "毒属性伤害"
|
120
|
+
- "integer"
|
121
|
+
fire_defence:
|
122
|
+
- "火属性防御"
|
123
|
+
- "integer"
|
124
|
+
thunder_defence:
|
125
|
+
- "雷属性防御"
|
126
|
+
- "integer"
|
127
|
+
ice_defence:
|
128
|
+
- "冰属性防御"
|
129
|
+
- "integer"
|
130
|
+
poison_defence:
|
131
|
+
- "毒属性防御"
|
132
|
+
- "integer"
|
133
|
+
|
134
|
+
####################################################
|
135
|
+
############ PlayerCharacter Fields ########
|
136
|
+
############ Last edited by Tengxianggong ########
|
137
|
+
############ Last edited at Jun 17, 2010 ########
|
138
|
+
####################################################
|
139
|
+
|
140
|
+
player_characters:
|
141
|
+
|
142
|
+
<<: *common_fields
|
143
|
+
|
144
|
+
gender:
|
145
|
+
- "性别"
|
146
|
+
- "integer"
|
147
|
+
head_picture:
|
148
|
+
- "头像"
|
149
|
+
- "integer"
|
150
|
+
hair_style:
|
151
|
+
- "发型"
|
152
|
+
- "integer"
|
153
|
+
hair_color:
|
154
|
+
- "发色"
|
155
|
+
- "integer"
|
156
|
+
exp:
|
157
|
+
- "经验值"
|
158
|
+
- "integer"
|
159
|
+
stage:
|
160
|
+
- "修仙阶段"
|
161
|
+
- "integer"
|
162
|
+
skill_point:
|
163
|
+
- "元神点数"
|
164
|
+
- "integer"
|
165
|
+
fame_point:
|
166
|
+
- "声望值"
|
167
|
+
- "integer"
|
168
|
+
contribution_point:
|
169
|
+
- "贡献值"
|
170
|
+
- "integer"
|
171
|
+
pk_point:
|
172
|
+
- "PK值"
|
173
|
+
- "integer"
|
174
|
+
family_id:
|
175
|
+
- "归属家族"
|
176
|
+
- "integer"
|
177
|
+
house_id:
|
178
|
+
- "归属门派"
|
179
|
+
- "integer"
|
180
|
+
attack_talisman:
|
181
|
+
- "攻击法宝"
|
182
|
+
- "integer"
|
183
|
+
defence_talisman:
|
184
|
+
- "防御法宝"
|
185
|
+
- "integer"
|
186
|
+
assist_talisman:
|
187
|
+
- "辅助法宝"
|
188
|
+
- "integer"
|
189
|
+
left_finger:
|
190
|
+
- "左手指"
|
191
|
+
- "integer"
|
192
|
+
right_finger:
|
193
|
+
- "右手指"
|
194
|
+
- "integer"
|
195
|
+
shoes:
|
196
|
+
- "鞋子"
|
197
|
+
- "integer"
|
198
|
+
helmet:
|
199
|
+
- "头盔"
|
200
|
+
- "integer"
|
201
|
+
necklace:
|
202
|
+
- "项链"
|
203
|
+
- "integer"
|
204
|
+
clothing:
|
205
|
+
- "衣服"
|
206
|
+
- "integer"
|
207
|
+
cloaks:
|
208
|
+
- "披风"
|
209
|
+
- "integer"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
2
|
+
<%
|
3
|
+
def options_from_table_column col
|
4
|
+
str = [":#{col.type}"]
|
5
|
+
str << ":default => #{col.default}" unless col.default.nil?
|
6
|
+
str << ":null => false " unless col.null
|
7
|
+
str << ":limit => #{col.limit}" unless col.limit.nil?
|
8
|
+
str << ":precision => #{col.precision}" unless col.precision.nil?
|
9
|
+
str << ":scale => #{col.scale}" unless col.scale.nil?
|
10
|
+
str << ":primary => true" if col.primary
|
11
|
+
str.join(', ')
|
12
|
+
end
|
13
|
+
|
14
|
+
def options_from_target_column hash
|
15
|
+
hash.map{|el| el[0]=":#{el[0]}"; el * " => "} * ", "
|
16
|
+
end
|
17
|
+
%>
|
18
|
+
def self.up
|
19
|
+
<% removed_columns.each_pair do |col, col_info| %>
|
20
|
+
remove_column :<%=table_name%>, :<%=col%>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% added_columns.each_pair do |col, col_info| %>
|
24
|
+
add_column :<%=table_name%>, :<%=col%>, :<%=col_info[1]%>, <%= options_from_target_column col_info[2] %>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
<% changed_columns.each_pair do |col, col_info| %>
|
28
|
+
change_column :<%=table_name%>, :<%=col%>, :<%=col_info[0][1]%>, <%= options_from_target_column col_info[0][2]%>
|
29
|
+
<% end %>
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.down
|
33
|
+
<% removed_columns.each do |col, col_info| %>
|
34
|
+
add_column :<%=table_name.to_sym%>, :<%= col%>, <%= options_from_table_column col_info%>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<% added_columns.each_pair do |col, col_info| %>
|
38
|
+
remove_column :<%=table_name%>, :<%=col%>
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
<% changed_columns.each_pair do |col, col_info| %>
|
42
|
+
change_column :<%=table_name%>, :<%=col%>, <%= options_from_table_column col_info[1]%>
|
43
|
+
<% end %>
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class FieldsReader
|
4
|
+
|
5
|
+
YAML_PATH = File.join(RAILS_ROOT, "config", "fields_dictionary.yml")
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def init reload=false
|
10
|
+
raise "Missing Config File, Please Check Whether #{YAML_PATH} exists." unless File.exists?(YAML_PATH)
|
11
|
+
if reload
|
12
|
+
@@config = YAML.load_file(YAML_PATH)["configs"]
|
13
|
+
else
|
14
|
+
@@config ||= YAML.load_file(YAML_PATH)["configs"]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing mth, *args
|
19
|
+
if mth.to_s =~ /^(.*)=$/
|
20
|
+
@@config[$1] = args.first
|
21
|
+
else
|
22
|
+
@@config.respond_to?(mth) ? @@config.send(mth) : @@config[mth.to_s]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_back
|
27
|
+
File.open(YAML_PATH,'w'){|f| YAML.dump({"configs" => @@config},f)}
|
28
|
+
init(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'fields_reader'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{sga_fields_synchronizer}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["tim.teng"]
|
12
|
+
s.date = %q{2010-06-23}
|
13
|
+
s.description = %q{ A synchronizer for most frequently edited columns based on yml file}
|
14
|
+
s.email = %q{tim.rubist@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"generators/fields_synchronizer/fields_synchronizer_generator.rb",
|
27
|
+
"generators/fields_synchronizer/templates/fields_dictionary.example",
|
28
|
+
"generators/fields_synchronizer/templates/migration.rb",
|
29
|
+
"lib/fields_reader.rb",
|
30
|
+
"lib/sga_fields_synchronizer.rb",
|
31
|
+
"sga_fields_synchronizer.gemspec",
|
32
|
+
"test/helper.rb",
|
33
|
+
"test/test_sga_fields_synchronizer.rb"
|
34
|
+
]
|
35
|
+
s.homepage = %q{http://github.com/tteng/sga_fields_synchronizer}
|
36
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = %q{1.3.6}
|
39
|
+
s.summary = %q{A synchronizer for most frequently edited columns}
|
40
|
+
s.test_files = [
|
41
|
+
"test/helper.rb",
|
42
|
+
"test/test_sga_fields_synchronizer.rb"
|
43
|
+
]
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
53
|
+
end
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sga_fields_synchronizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- tim.teng
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-06-23 00:00:00 +08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: thoughtbot-shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
description: " A synchronizer for most frequently edited columns based on yml file"
|
33
|
+
email: tim.rubist@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- LICENSE
|
40
|
+
- README.rdoc
|
41
|
+
files:
|
42
|
+
- .document
|
43
|
+
- .gitignore
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- VERSION
|
48
|
+
- generators/fields_synchronizer/fields_synchronizer_generator.rb
|
49
|
+
- generators/fields_synchronizer/templates/fields_dictionary.example
|
50
|
+
- generators/fields_synchronizer/templates/migration.rb
|
51
|
+
- lib/fields_reader.rb
|
52
|
+
- lib/sga_fields_synchronizer.rb
|
53
|
+
- sga_fields_synchronizer.gemspec
|
54
|
+
- test/helper.rb
|
55
|
+
- test/test_sga_fields_synchronizer.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/tteng/sga_fields_synchronizer
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: A synchronizer for most frequently edited columns
|
86
|
+
test_files:
|
87
|
+
- test/helper.rb
|
88
|
+
- test/test_sga_fields_synchronizer.rb
|