rapid-core 0.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile.lock +35 -2
  3. data/Rakefile +77 -48
  4. data/doc/server.txt +15 -0
  5. data/features/settings/double-nested/default.feature +2 -2
  6. data/features/settings/double-nested/validates/presence_of.feature +1 -1
  7. data/features/settings/nested/default.feature +1 -1
  8. data/features/settings/nested/validates/presence_of.feature +1 -1
  9. data/features/settings/not_found.feature +2 -2
  10. data/features/step_definitions/settings_steps.rb +7 -3
  11. data/features/step_definitions/template_steps.rb +3 -1
  12. data/lib/rapid/check.rb +30 -23
  13. data/lib/rapid/core.rb +12 -0
  14. data/lib/rapid/error.rb +1 -0
  15. data/lib/rapid/module.rb +10 -1
  16. data/lib/rapid/railtie.rb +6 -0
  17. data/lib/rapid/setting/base.rb +31 -8
  18. data/lib/rapid/setting/boolean_setting.rb +20 -1
  19. data/lib/rapid/setting/definer.rb +11 -47
  20. data/lib/rapid/setting/integer_setting.rb +7 -7
  21. data/lib/rapid/setting/module.rb +56 -0
  22. data/lib/rapid/setting/namespace/base.rb +35 -60
  23. data/lib/rapid/setting/namespace/instance.rb +195 -28
  24. data/lib/rapid/setting/string_setting.rb +7 -1
  25. data/lib/rapid/settings.rb +51 -65
  26. data/lib/rapid/skeleton/base.rb +39 -18
  27. data/lib/rapid/skeleton/helpers/directory.rb +5 -6
  28. data/lib/rapid/skeleton/helpers/files.rb +62 -0
  29. data/lib/rapid/skeleton/helpers/gem.rb +43 -32
  30. data/lib/rapid/skeleton/helpers/if_setting.rb +44 -0
  31. data/lib/rapid/skeleton/helpers/migration.rb +102 -32
  32. data/lib/rapid/skeleton/helpers/route.rb +8 -12
  33. data/lib/rapid/skeleton/helpers/script.rb +1 -2
  34. data/lib/rapid/skeleton/helpers/template.rb +23 -25
  35. data/lib/rapid/skeleton/helpers/view.rb +7 -7
  36. data/lib/rapid/spec/template.rb +1 -1
  37. data/lib/rapid/version.rb +1 -1
  38. data/lib/rapid/web/base.rb +35 -0
  39. data/lib/rapid/web/bootstrap.rb +98 -0
  40. data/lib/rapid/web/controller_helpers.rb +60 -0
  41. data/lib/rapid/web/navigator.rb +18 -0
  42. data/lib/rapid/web/select_helpers.rb +63 -0
  43. data/lib/rapid/web/settings_form_builder.rb +205 -0
  44. data/lib/rapid/web/static_helpers.rb +28 -0
  45. data/lib/rapid/web/tasks.rb +10 -0
  46. data/public/rapid/core/bootstrap-collapse.js +136 -0
  47. data/public/rapid/core/bootstrap-responsive.min.css +3 -0
  48. data/public/rapid/core/bootstrap.min.css +556 -0
  49. data/public/rapid/core/jquery-1.7.1.js +9253 -0
  50. data/public/rapid/core/prettify.css +30 -0
  51. data/public/rapid/core/prettify.js +28 -0
  52. data/rapid-core.gemspec +5 -0
  53. data/spec/rapid/check_spec.rb +11 -4
  54. data/spec/rapid/module_spec.rb +18 -0
  55. data/spec/rapid/setting/base_spec.rb +71 -0
  56. data/spec/rapid/setting/boolean_setting_spec.rb +95 -0
  57. data/spec/rapid/setting/definer_spec.rb +7 -13
  58. data/spec/rapid/setting/integer_setting_spec.rb +49 -0
  59. data/spec/rapid/setting/module_spec.rb +25 -0
  60. data/spec/rapid/setting/namespace/base_spec.rb +88 -54
  61. data/spec/rapid/setting/namespace/instance_spec.rb +308 -5
  62. data/spec/rapid/setting/string_setting_spec.rb +43 -0
  63. data/spec/rapid/settings_spec.rb +65 -17
  64. data/spec/rapid/skeleton/base_spec.rb +113 -7
  65. data/spec/rapid/skeleton/helpers/directory_spec.rb +8 -6
  66. data/spec/rapid/skeleton/helpers/files_spec.rb +93 -0
  67. data/spec/rapid/skeleton/helpers/gem_spec.rb +65 -36
  68. data/spec/rapid/skeleton/helpers/if_setting_spec.rb +110 -0
  69. data/spec/rapid/skeleton/helpers/migration_spec.rb +190 -1
  70. data/spec/rapid/skeleton/helpers/route_spec.rb +13 -12
  71. data/spec/rapid/skeleton/helpers/script_spec.rb +2 -1
  72. data/spec/rapid/skeleton/helpers/template_spec.rb +22 -35
  73. data/spec/rapid/spec/template_spec.rb +1 -1
  74. data/spec/rapid/web/base_spec.rb +33 -0
  75. data/spec/rapid/web/bootstrap_spec.rb +72 -0
  76. data/spec/rapid/web/controller_helpers_spec.rb +86 -0
  77. data/spec/rapid/web/navigator_spec.rb +17 -0
  78. data/spec/rapid/web/select_helpers_spec.rb +71 -0
  79. data/spec/rapid/web/settings_form_builder_spec.rb +255 -0
  80. data/spec/rapid/web/static_helpers_spec.rb +26 -0
  81. data/spec/spec_helper.rb +3 -0
  82. data/views/index.erb +11 -0
  83. data/views/layout.erb +9 -0
  84. metadata +107 -12
  85. data/lib/rapid.rb +0 -37
  86. data/lib/rapid/setting/class_hash.rb +0 -34
  87. data/lib/rapid/setting/instance_hash.rb +0 -132
  88. data/lib/rapid/setting/instance_root.rb +0 -107
  89. data/spec/rapid/setting/instance_root_spec.rb +0 -161
@@ -15,12 +15,11 @@ module Rapid
15
15
  end
16
16
 
17
17
  def push_directory path, options = {}
18
- full_path = File.join project_path, path
19
-
20
- if_setting = options[:if]
21
- return if if_setting && !set?(if_setting)
22
-
23
- FileUtils.mkdir_p full_path
18
+ if if_setting_off? options
19
+ delete_project_directory path
20
+ else
21
+ make_project_directory path
22
+ end
24
23
  end
25
24
 
26
25
  def pull_directory path, options = {}
@@ -0,0 +1,62 @@
1
+ module Rapid
2
+ module Skeleton
3
+ module Helpers
4
+
5
+ module Files
6
+
7
+ protected
8
+
9
+ def read_template_file file_path
10
+ full_path = File.join templates_path, file_path
11
+ File.open(full_path) { |f| f.read }
12
+
13
+ rescue Errno::ENOENT => e
14
+ raise Rapid::TemplateNotFoundError.new(e.message)
15
+ end
16
+
17
+ def project_file_exists? file_path
18
+ full_path = File.join project_path, file_path
19
+ File.exists? full_path
20
+ end
21
+
22
+ def make_project_directory path
23
+ full_path = File.join project_path, path
24
+ FileUtils.mkdir_p full_path
25
+ end
26
+
27
+ def delete_project_directory path
28
+ full_path = File.join project_path, path
29
+ FileUtils.rm_rf full_path
30
+ end
31
+
32
+ def read_project_file file_path
33
+ full_path = File.join project_path, file_path
34
+ File.open(full_path) { |f| f.read }
35
+ rescue Errno::ENOENT => e
36
+ raise Rapid::ProjectFileNotFoundError.new(e.message)
37
+ end
38
+
39
+ def write_project_file file_path, file_content
40
+ make_project_directory File.dirname(file_path)
41
+
42
+ full_path = File.join project_path, file_path
43
+ File.open(full_path, 'w') { |f| f.write file_content }
44
+ end
45
+
46
+ def delete_project_file file_path
47
+ full_path = File.join project_path, file_path
48
+ FileUtils.rm_rf full_path
49
+ end
50
+
51
+ def chmod_project_file chmod, file_path
52
+ full_path = File.join project_path, file_path
53
+ File.chmod chmod, full_path
54
+ rescue Errno::ENOENT => e
55
+ raise Rapid::ProjectFileNotFoundError.new(e.message)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -4,15 +4,10 @@ module Rapid
4
4
 
5
5
  module Gem
6
6
 
7
- def gemfile_path
8
- File.join project_path, "Gemfile" if project_path
9
- end
10
-
11
7
  protected
12
8
 
13
9
  def validate_gemfile_exists
14
- path = gemfile_path
15
- if path && !File.exists?(path)
10
+ if project_path && !project_file_exists?("Gemfile")
16
11
  errors.add :gem, "file does not exist"
17
12
  end
18
13
 
@@ -31,29 +26,25 @@ module Rapid
31
26
  options = Hash === args.last ? args.pop : {}
32
27
  version = args.first
33
28
 
34
- path = gemfile_path
35
-
36
- if path.blank?
29
+ if project_path.blank?
37
30
  error gem_name, "Unknown Gemfile location"
38
31
  return
39
32
  end
40
33
 
41
- unless File.exists? path
34
+ unless project_file_exists?("Gemfile")
42
35
  error gem_name, "Gemfile doesn't exist"
43
36
  return
44
37
  end
45
38
 
46
- content = File.open(path) {|f| f.read }
47
-
48
- if_setting = options[:if]
39
+ content = read_project_file "Gemfile"
49
40
 
50
41
  if has_gem? gem_name, content
51
42
  ok gem_name, "is in your Gemfile"
52
- self[if_setting] = true if if_setting
43
+ if_set! true, options
53
44
 
54
- elsif if_setting
45
+ elsif has_if_setting?(options)
55
46
  ok gem_name, "isn't in your Gemfile"
56
- self[if_setting] = false
47
+ if_set! false, options
57
48
 
58
49
  else
59
50
  error gem_name, "isn't in your Gemfile"
@@ -64,27 +55,21 @@ module Rapid
64
55
  options = Hash === args.last ? args.pop : {}
65
56
  version = args.first
66
57
 
67
- path = gemfile_path
68
- return false unless path
58
+ return false unless project_file_exists?("Gemfile")
69
59
 
70
- content = File.open(path) {|f| f.read }
60
+ content = read_project_file "Gemfile"
71
61
 
72
- add_gem_to_content! [name, version, options], content
62
+ if if_setting_off?(options)
63
+ remove_gem_from_content! content, name, version, options
64
+ else
65
+ add_gem_to_content! content, name, version, options
66
+ end
73
67
 
74
- File.open(path, 'w') {|f| f.write content }
68
+ write_project_file "Gemfile", content
75
69
  true
76
70
  end
77
71
 
78
- def add_gem_to_content! gem, content
79
- gem_name = gem.first
80
- gem_version = gem[1]
81
- gem_options = gem[2]
82
-
83
- if_setting = gem_options.delete :if
84
- return if if_setting && !set?(if_setting)
85
-
86
- return if has_gem? gem, content
87
-
72
+ def gem_group_index content, gem_options
88
73
  if gem_options[:group]
89
74
  gem_group = gem_options[:group]
90
75
  group_index = content.index %(group :#{gem_group} do)
@@ -94,6 +79,30 @@ module Rapid
94
79
  group_index = content.index %(group #{groups.collect {|g| g.to_sym.inspect}.join(", ")} do)
95
80
  end
96
81
 
82
+ group_index
83
+ end
84
+
85
+ def remove_gem_from_content! content, gem_name, gem_version, gem_options
86
+ return unless has_gem? gem_name, content
87
+
88
+ group_index = gem_group_index content, gem_options
89
+
90
+ if group_index
91
+ gem_options.delete :group
92
+ gem_options.delete :groups
93
+ gem_method = gem_method_call gem_name, gem_version, gem_options
94
+ else
95
+ gem_method = gem_method_call gem_name, gem_version, gem_options
96
+ end
97
+
98
+ content.gsub! /\n[\ ]*#{gem_method}[^\n]*/, ""
99
+ end
100
+
101
+ def add_gem_to_content! content, gem_name, gem_version, gem_options
102
+ return if has_gem? gem_name, content
103
+
104
+ group_index = gem_group_index content, gem_options
105
+
97
106
  if group_index
98
107
  end_index = content.index("\nend", group_index)
99
108
  rest = content[end_index+4..-1]
@@ -110,7 +119,9 @@ module Rapid
110
119
  end
111
120
 
112
121
  def has_gem? gem_name, content
113
- content.index(%(gem "#{gem_name}")) != nil || content.index(%(gem '#{gem_name}')) != nil
122
+ with_double_quotes = Regexp.new(%(\n[\ ]*gem "#{gem_name}"))
123
+ with_single_quotes = Regexp.new(%(\n[\ ]*gem '#{gem_name}'))
124
+ content.index(with_double_quotes) != nil || content.index(with_single_quotes) != nil
114
125
  end
115
126
 
116
127
  def gem_method_call gem_name, gem_version, gem_options
@@ -0,0 +1,44 @@
1
+ module Rapid
2
+ module Skeleton
3
+ module Helpers
4
+
5
+ module IfSetting
6
+
7
+ protected
8
+
9
+ def has_if_setting? options
10
+ options[:if] != nil
11
+ end
12
+
13
+ def if_setting_off? options
14
+ # TODO unless
15
+ if_setting = options.delete :if
16
+ return false if if_setting.nil?
17
+
18
+ if if_setting.is_a?(Array)
19
+ if_setting.each {|s| return true unless set?(s) }
20
+ false
21
+ else
22
+ !set?(if_setting)
23
+ end
24
+ end
25
+
26
+ def if_set! bool, options
27
+ if_setting = options[:if]
28
+ if if_setting.nil?
29
+ # do nothing
30
+
31
+ elsif if_setting.is_a?(Array)
32
+ if_setting.each {|s| self[s] = bool if self[s] == nil }
33
+
34
+ else
35
+ self[if_setting] = bool
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+
@@ -6,38 +6,108 @@ module Rapid
6
6
 
7
7
  protected
8
8
 
9
- # def migration migration_path
10
- # if pushing?
11
- # push_migration path
12
- # elsif pulling?
13
- # pull_migration path
14
- # end
15
- # end
16
- #
17
- # def push_migration migration_path
18
- #
19
- # end
20
- #
21
- # def unique_prefix
22
- # if @timestamp
23
- # @timestamp + 1
24
- # else
25
- # @timestamp ||= Time.now.strftime("%Y%m%d%H%M%S").to_i
26
- # end
27
- # end
28
- #
29
- # def create_migration migration
30
- # if migration =~ /^[0-9]+_/
31
- # suffix = $'
32
- # else
33
- # suffix = migration
34
- # end
35
- #
36
- # template_path = File.join 'db', 'migrate', "#{migration}.rb"
37
- # output_path = File.join 'db', 'migrate', "#{unique_prefix}_#{suffix}.rb"
38
- #
39
- # push_template template_path, :to => output_path
40
- # end
9
+ def migration_path path
10
+ path = "#{path}.rb" unless path.ends_with? ".rb"
11
+ File.join 'db', 'migrate', path
12
+ end
13
+
14
+ def migration migration, options = {}
15
+ if pushing?
16
+ push_migration migration, options
17
+ elsif pulling?
18
+ pull_migration migration, options
19
+ end
20
+ end
21
+
22
+ def push_migration migration, options
23
+ if if_setting_off? options
24
+ remove_migration migration, options
25
+
26
+ else
27
+ migration_out = migration_path timestamped_migration(migration)
28
+ template_path = migration_path migration
29
+
30
+ push_template template_path, :to => migration_out
31
+ end
32
+ end
33
+
34
+ def pull_migration migration, options
35
+ project_migration = find_project_migration migration
36
+
37
+ if project_migration.nil?
38
+ if_set! false, options
39
+ else
40
+ if_set! true, options
41
+ pull_template migration_path(migration), :to => migration_path(project_migration)
42
+ end
43
+ end
44
+
45
+ def timestamped_migration migration
46
+ if @migration_unique_prefix
47
+ @migration_unique_prefix += 1
48
+ else
49
+ @migration_unique_prefix ||= Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
50
+ end
51
+
52
+ name = migration.gsub /^[0-9]+_/, ""
53
+ "#{@migration_unique_prefix}_#{name}"
54
+ end
55
+
56
+ def find_project_migration migration
57
+ dir = File.join project_path, 'db', 'migrate'
58
+ pattern = File.join dir, '*.rb'
59
+ Dir.glob(pattern).each do |full_path|
60
+ name = full_path[dir.length+1..-4]
61
+
62
+ if name =~ /^[0-9]+_/ && $' == migration
63
+ return name
64
+
65
+ elsif name == migration
66
+ return name
67
+ end
68
+
69
+ end
70
+
71
+ nil
72
+ end
73
+
74
+ def remove_migration migration, options
75
+ existing_migration = find_project_migration migration
76
+ return unless existing_migration
77
+
78
+ project_migration_path = migration_path existing_migration
79
+
80
+ in_version = in_version_control? project_migration_path
81
+ in_schema = in_local_schema? project_migration_path
82
+
83
+ if in_version && in_schema
84
+ reverse_migration existing_migration, options
85
+
86
+ elsif in_version
87
+ # great it's already reversed!
88
+
89
+ elsif in_schema
90
+ error migration, "must be rolled back before removing"
91
+
92
+ else
93
+ delete_project_file project_migration_path
94
+ end
95
+ end
96
+
97
+ def reverse_migration migration, options
98
+ # TODO swap the up and down methods in the migration
99
+
100
+ end
101
+
102
+ def in_local_schema? migration_file
103
+ # TODO find what create_table, add_index, add_column are in the migration file
104
+
105
+ # see if those changes are in the schema.rb
106
+ end
107
+
108
+ def in_version_control? project_file
109
+ # TODO use grit to see if the project_file is in git
110
+ end
41
111
 
42
112
  end
43
113
 
@@ -5,14 +5,13 @@ module Rapid
5
5
  module Route
6
6
 
7
7
  def routes_path
8
- File.join project_path, "config", "routes.rb" if project_path
8
+ @routes_path ||= File.join "config", "routes.rb"
9
9
  end
10
10
 
11
11
  protected
12
12
 
13
13
  def validate_routes_file_exists
14
- path = routes_path
15
- if path && !File.exists?(path)
14
+ if project_path && !project_file_exists?(routes_path)
16
15
  errors.add :routes, "file does not exist"
17
16
  end
18
17
 
@@ -28,19 +27,17 @@ module Rapid
28
27
  end
29
28
 
30
29
  def pull_route type, path, options = {}
31
- file_path = routes_path
32
-
33
- if file_path.blank?
30
+ if project_path.blank?
34
31
  error "config/routes.rb", "location is unknown"
35
32
  return
36
33
  end
37
34
 
38
- unless File.exists? file_path
35
+ unless project_file_exists? routes_path
39
36
  error "config/routes.rb", "doesn't exist"
40
37
  return
41
38
  end
42
39
 
43
- content = File.open(file_path) {|f| f.read }
40
+ content = read_project_file routes_path
44
41
 
45
42
  if has_route? content, type, path
46
43
  ok "#{type} '#{path}'", "exists"
@@ -50,14 +47,13 @@ module Rapid
50
47
  end
51
48
 
52
49
  def push_route type, path, options = {}
53
- file_path = routes_path
54
- return false unless file_path
50
+ return false if project_path.blank? || !project_file_exists?(routes_path)
55
51
 
56
- content = File.open(file_path) {|f| f.read }
52
+ content = read_project_file routes_path
57
53
 
58
54
  add_route_to_content! content, type, path, options
59
55
 
60
- File.open(file_path, 'w') {|f| f.write content }
56
+ write_project_file routes_path, content
61
57
  true
62
58
  end
63
59