rapid-core 0.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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