camping 3.0.2 → 3.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6aa52530d539466610a0ae7b505a72176f38b2ba12975f776447dcfb4e6d6934
4
- data.tar.gz: 31c521e39db07c10472bff1d6e56bec41b55052bf0e40b3a8165e1266873815b
3
+ metadata.gz: e1aa24f1bf87479fdf76924e8a0ac6a72b308eebce898efad48e2a23879b5f45
4
+ data.tar.gz: 6779a418c8f44829aa14cfdb5633925a8479ab91c8d1bff0640b7dd7f6de5634
5
5
  SHA512:
6
- metadata.gz: 200a6af8d4e245e7bf1fac8bb5965ec9ec2a049fc2b3965b9129e5fcc296f251de7ec5fd83656bde13dac6e2869692f52dd5d707e5718e84a498da1f742f7d07
7
- data.tar.gz: b80af113694c5303ab1c955876dd6e6e0eb78d0324fa2b4d16f9361b8c8114e0af1cfdffd6761d452a22a3ee5c8febc679078ed50978a2d8a1385806d6da208b
6
+ metadata.gz: d68c77354dce8e339a0cd5371d31a99f775380f176bbac8edab4e36c5cff3d07224bad49f918c34b546f7bf57fa553b2bbc38945d82a0c482de7cf3b0292939e
7
+ data.tar.gz: 23fd9016b59844b38a9331a3cac4505d398cf350a27e310551d0a7f69eb4e950dad74ed487e53b71c7528e0bafb1310abe003a2dd68241ad5a73fce822dfaf03
data/README.md CHANGED
@@ -64,27 +64,38 @@ end
64
64
  ## Installation
65
65
 
66
66
  Interested yet? Luckily it's quite easy to install Camping. We'll be using
67
- a tool called RubyGems, so if you don't have that installed yet, go grab it!
68
- Once that's sorted out, open up a Terminal or Command Line and enter:
67
+ a tool called RubyGems, and Bundler, so if you don't have that installed
68
+ yet, go grab it! Once that's sorted out, open up a Terminal or Command
69
+ Line and enter:
69
70
 
70
71
  ```
71
72
  gem install camping
72
73
  ```
73
74
 
75
+ Also make certain to have Bundler installed:
76
+
77
+ ```
78
+ gem install bundler
79
+ ```
80
+
74
81
  ~~Even better, install the Camping Omnibus, a full package of recommended libs:~~ Camping Omnibus will return for summer vacation.
75
82
 
83
+ Now make a new directory filled with your camp essentials using the `camping new` command:
84
+
76
85
  ```
77
- gem install camping-omnibus
86
+ camping new Donuts # You can replace Donuts with whatever but CamelCased.
78
87
  ```
79
88
 
80
- If not, you should be aware of that Camping itself only depends on
81
- [Rack](https://github.com/rack/rack), and if you're going to use the views you also
82
- need to install **[markaby](https://github.com/markaby/markaby)**, and if you're going to use the database you need
83
- **activerecord** as well.
89
+ Move to your new directory, then use bundler to install all of your camp's dependencies:
84
90
 
85
91
  ```
86
- gem install markaby
87
- gem install activerecord
92
+ cd donuts; bundle install
93
+ ```
94
+
95
+ You can now run camping using the `camping` command. We recommend running camping in development mode locally. Make certain to prefix the camping command with `bundle exec` to run your app with the gems you've installed just for your camp:
96
+
97
+ ```
98
+ bundle exec camping -e development
88
99
  ```
89
100
 
90
101
  ## Learning
@@ -107,6 +118,10 @@ like chatting with us, you should join [#camping @ irc.freenode.net](http://java
107
118
 
108
119
  Tests should be run using bundler and rake: `bundle exec rake`.
109
120
 
121
+ ## Minting Releases
122
+
123
+ We use Ruby Gems to distribute versions of Camping.
124
+
110
125
  ## Authors
111
126
 
112
127
  Camping was originally crafted by [why the lucky stiff](http://en.wikipedia.org/wiki/Why_the_lucky_stiff),
data/Rakefile CHANGED
@@ -70,6 +70,18 @@ Rake::TestTask.new(:test) do |t|
70
70
  t.test_files = FileList['test/app_*.rb', 'test/gear/gear_*.rb']
71
71
  end
72
72
 
73
+ ## Reloader Tests
74
+ Rake::TestTask.new(:reloader) do |t|
75
+ t.libs << "test"
76
+ t.test_files = FileList['test/reload_*.rb']
77
+ end
78
+
79
+ ## Reloader Tests
80
+ Rake::TestTask.new(:configreloader) do |t|
81
+ t.libs << "test"
82
+ t.test_files = FileList['test/config_*.rb']
83
+ end
84
+
73
85
  ## Diff
74
86
  desc "Compare camping and camping-unabridged"
75
87
  task :diff do
@@ -97,7 +109,7 @@ end
97
109
  error = false
98
110
 
99
111
  ## Check
100
- task :check => ["test", "check:valid", "check:equal", "check:size", "check:lines", "check:exit"]
112
+ task :check => ["test", "reloader", "configreloader", "check:valid", "check:equal", "check:size", "check:lines", "check:exit"]
101
113
  namespace :check do
102
114
 
103
115
  desc "Check source code validity"
@@ -0,0 +1,14 @@
1
+ # Campguide is a small helper to map common errors in a Camping project to a quick resolution.
2
+ module Campguide
3
+ Errors = {"wrong number of arguments (given 3, expected 0)" => "ArgumentError. This is sometimes caused when you try to send a request to a controller when a camping app hasn't made camp yet. make certain to call Camping.make_camp to set up your apps."}
4
+
5
+ class << self
6
+
7
+ # accepts string error messages and tries to match them with better explanations of the error.
8
+ def make_sense(error_message)
9
+ message = Errors[error_message]
10
+ puts message ? message : error_message
11
+ end
12
+
13
+ end
14
+ end
@@ -237,9 +237,79 @@ task :test => 'test:all'
237
237
  namespace 'test' do
238
238
  Rake::TestTask.new('all') do |t|
239
239
  t.libs << 'test'
240
- t.test_files = FileList['test/nuts_*.rb']
240
+ t.test_files = FileList['test/test_*.rb']
241
241
  end
242
242
  end
243
+ TXT
244
+ end
245
+
246
+ # writes a test_helper
247
+ def make_test_helper
248
+ write 'test/test_helper.r', <<-TXT
249
+ # Test Helper
250
+ $:.unshift File.dirname(__FILE__) + '/../'
251
+
252
+ begin
253
+ require 'rubygems'
254
+ rescue LoadError
255
+ end
256
+
257
+ require 'minitest/autorun'
258
+ require 'rack/test'
259
+ require 'minitest/reporters'
260
+ require 'minitest/hooks'
261
+ Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(:color => true)]
262
+
263
+ # Default TestCase with some helpers.
264
+ # The same stuff we use for Camping itself.
265
+ class TestCase < MiniTest::Test
266
+ include Rack::Test::Methods
267
+ include Minitest::Hooks
268
+
269
+ def self.inherited(mod)
270
+ mod.app = Object.const_get(mod.to_s[/\w+/])
271
+ super
272
+ end
273
+
274
+ class << self
275
+ attr_accessor :app
276
+ end
277
+
278
+ def setup
279
+ super
280
+ Camping.make_camp
281
+ end
282
+
283
+ def body() last_response.body end
284
+ def app() self.class.app end
285
+
286
+ def response_body() last_response.to_a end
287
+
288
+ def assert_reverse
289
+ begin
290
+ yield
291
+ rescue Exception
292
+ else
293
+ assert false, "Block didn't fail"
294
+ end
295
+ end
296
+
297
+ def assert_body(str, message="")
298
+ case str
299
+ when Regexp
300
+ assert_match(str, last_response.body.strip, message)
301
+ else
302
+ assert_equal(str.to_s, last_response.body.strip, message)
303
+ end
304
+ end
305
+
306
+ def assert_status(code, message="")
307
+ assert_equal(code, last_response.status, message)
308
+ end
309
+
310
+ def test_silly; end
311
+ end
312
+
243
313
  TXT
244
314
  end
245
315
 
@@ -274,6 +344,7 @@ group :test do
274
344
  gem 'minitest', '~> 5.0'
275
345
  gem 'minitest-reporters'
276
346
  gem 'rack-test'
347
+ gem 'minitest-hooks'
277
348
  end
278
349
 
279
350
  GEM
@@ -287,6 +358,8 @@ Camping is really fun and I hope you enjoy it.
287
358
 
288
359
  Start camping by running: `camping` in the root directory.
289
360
 
361
+ To start Camping in development mode run: `camping -e development
362
+
290
363
  READ
291
364
  end
292
365
 
@@ -360,47 +433,55 @@ RUBY
360
433
  end
361
434
 
362
435
  class Commands
436
+ class << self
363
437
 
364
- # A helper method to spit out Routes for an application
365
- def self.routes(theApp = Camping, silent = false)
366
- routes = Camping::CommandsHelpers::RoutesParser.parse theApp
367
- routes.display unless silent == true
368
- return routes
369
- end
438
+ # A helper method to spit out Routes for an application
439
+ def routes(theApp = Camping, silent = false)
440
+ routes = Camping::CommandsHelpers::RoutesParser.parse theApp
441
+ routes.display unless silent == true
442
+ return routes
443
+ end
370
444
 
371
- def self.new_cmd(app_name=:Camp)
372
-
373
- # Normalize the app_name
374
- Camping::CommandsHelpers.app_name_from_input(app_name) => {app_name:, snake_name:, camel_name:}
375
-
376
- # make a directory then move there.
377
- # _original_dir = Dir.pwd
378
- Dir.mkdir("#{snake_name}") unless Dir.exist?("#{snake_name}")
379
- Dir.chdir("#{snake_name}")
380
-
381
- # generate a new camping app in a directory named after it:
382
- Generators::make_camp_file(camel_name)
383
- Generators::make_gitignore()
384
- Generators::make_rakefile()
385
- Generators::make_ruby_version()
386
- Generators::make_configkdl()
387
- Generators::make_gemfile()
388
- Generators::make_readme()
389
- Generators::make_public_folder()
390
- Generators::make_test_folder()
391
-
392
- # optionally add omnibus support
393
- # add src/ folder
394
- # add lib/ folder
395
- # add views/ folder
396
-
397
- # optionally add a local database too, through guidebook
398
- # add db/ folder
399
- # add db/migrate folder
400
- # add db/config.kdl
401
- # append migrations stuff to Rakefile.
402
- `ls`
403
- end
445
+ def new_cmd(app_name=:Camp)
446
+
447
+ # Normalize the app_name
448
+ Camping::CommandsHelpers.app_name_from_input(app_name) => {app_name:, snake_name:, camel_name:}
449
+
450
+ # make a directory then move there.
451
+ # _original_dir = Dir.pwd
452
+ Dir.mkdir("#{snake_name}") unless Dir.exist?("#{snake_name}")
453
+ Dir.chdir("#{snake_name}")
454
+
455
+ # generate a new camping app in a directory named after it:
456
+ Generators::make_camp_file(camel_name)
457
+ Generators::make_gitignore()
458
+ Generators::make_rakefile()
459
+ Generators::make_ruby_version()
460
+ Generators::make_configkdl()
461
+ Generators::make_gemfile()
462
+ Generators::make_readme()
463
+ Generators::make_public_folder()
464
+ Generators::make_test_folder()
465
+ Generators::make_test_helper()
466
+
467
+ # optionally add omnibus support
468
+ # add src/ folder
469
+ # add lib/ folder
470
+ # add views/ folder
471
+
472
+ # optionally add a local database too, through guidebook
473
+ # add db/ folder
474
+ # add db/migrate folder
475
+ # add db/config.kdl
476
+ # append migrations stuff to Rakefile.
477
+ `ls`
478
+ end
479
+
480
+ # TODO: Create this generator
481
+ # generates the apps folder from apps found in camp.rb or config.ru
482
+ # def generate_apps_folder
483
+ # end
404
484
 
485
+ end
405
486
  end
406
487
  end
@@ -1,48 +1,48 @@
1
1
  # This gear is originally from filtering_camping gem by judofyr, and techarc.
2
2
  module Gear
3
- module Filters
4
- module ClassMethods
5
- def filters
6
- @_filters ||= {:before => [], :after => []}
7
- end
3
+ module Filters
4
+ module ClassMethods
5
+ def filters
6
+ @_filters ||= {:before => [], :after => []}
7
+ end
8
8
 
9
- def before(actions, &blk)
10
- actions = [actions] unless actions.is_a?(Array)
11
- actions.each do |action|
12
- filters[:before] << [action, blk]
13
- end
14
- end
9
+ def before(actions, &blk)
10
+ actions = [actions] unless actions.is_a?(Array)
11
+ actions.each do |action|
12
+ filters[:before] << [action, blk]
13
+ end
14
+ end
15
15
 
16
- def after(actions, &blk)
17
- actions = [actions] unless actions.is_a?(Array)
18
- actions.each do |action|
19
- filters[:after] << [action, blk]
20
- end
21
- end
22
- end
16
+ def after(actions, &blk)
17
+ actions = [actions] unless actions.is_a?(Array)
18
+ actions.each do |action|
19
+ filters[:after] << [action, blk]
20
+ end
21
+ end
22
+ end
23
23
 
24
- def self.included(mod)
25
- mod.extend(ClassMethods)
26
- end
24
+ def self.included(mod)
25
+ mod.extend(ClassMethods)
26
+ end
27
27
 
28
- def self.setup(app, *a, &block) end
28
+ def self.setup(app, *a, &block) end
29
29
 
30
- def run_filters(type)
31
- o = self.class.to_s.split("::")
32
- filters = Object.const_get(o.first).filters
33
- filters[type].each do |filter|
34
- if (filter[0].is_a?(Symbol) && (filter[0] == o.last.to_sym || filter[0] == :all)) ||
35
- (filter[0].is_a?(String) && /^#{filter[0]}\/?$/ =~ @env.REQUEST_URI)
36
- self.instance_eval(&filter[1])
37
- end
38
- end
39
- end
30
+ def run_filters(type)
31
+ o = self.class.to_s.split("::")
32
+ filters = Object.const_get(o.first).filters
33
+ filters[type].each do |filter|
34
+ if (filter[0].is_a?(Symbol) && (filter[0] == o.last.to_sym || filter[0] == :all)) ||
35
+ (filter[0].is_a?(String) && /^#{filter[0]}\/?$/ =~ @env.REQUEST_URI)
36
+ self.instance_eval(&filter[1])
37
+ end
38
+ end
39
+ end
40
40
 
41
- def service(*a)
42
- run_filters(:before)
43
- super(*a)
44
- run_filters(:after)
45
- self
46
- end
47
- end
41
+ def service(*a)
42
+ run_filters(:before)
43
+ super(*a)
44
+ run_filters(:after)
45
+ self
46
+ end
47
+ end
48
48
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # lib/camping/config
3
2
  # load and parse settings.
4
3
 
5
4
  begin
@@ -1,3 +1,6 @@
1
+ require 'zeitwerk'
2
+ require 'listen'
3
+
1
4
  module Camping
2
5
  # == The Camping Reloader
3
6
  #
@@ -31,18 +34,39 @@ module Camping
31
34
  # Blog and Wiki, but they will update themselves if yourapp.rb changes.
32
35
  #
33
36
  # You can also give Reloader more than one script.
34
- class Reloader
37
+ class Loader
35
38
  attr_reader :file
39
+ Loaders = []
36
40
 
37
- def initialize(file, &blk)
41
+ def initialize(file=nil, &blk)
38
42
  @file = file
39
43
  @mtime = Time.at(0)
40
44
  @requires = []
41
45
  @apps = {}
42
46
  @callback = blk
43
-
47
+ @root = Dir.pwd
48
+ @file = @root + '/camp.rb' if @file == nil
49
+ @zeit = Zeitwerk::Loader.new
50
+ Loaders << @zeit
51
+
52
+ # setup Zeit for this reloader
53
+ setup_zeit(@zeit)
54
+
55
+ # setup recursive listener on the apps and lib directories from the source script.
56
+ @listener = Listen.to("#{@root}/apps", "#{@root}/lib", "#{@root}") do |modified, added, removed|
57
+ @mtime = Time.now
58
+ reload!
59
+ end
60
+ start
44
61
  end
45
62
 
63
+ # pass through methods to the Listener.
64
+ # for testing purposes.
65
+ def processing_events?;@listener.processing? end
66
+ def stop;@listener.stop end
67
+ def pause;@listener.pause end
68
+ def start;@listener.start end
69
+
46
70
  def name
47
71
  @name ||= begin
48
72
  base = @file.dup
@@ -52,29 +76,29 @@ module Camping
52
76
  end
53
77
  end
54
78
 
55
- # Loads the apps available in this script. Use <tt>apps</tt> to get
56
- # the loaded apps.
57
- def load_apps(old_apps)
79
+ # remove_constants called inside this.
80
+ def load_everything()
58
81
  all_requires = $LOADED_FEATURES.dup
59
82
  all_apps = Camping::Apps.dup
60
83
 
61
84
  load_file
85
+ reload_directory("#{@root}/apps")
86
+ reload_directory("#{@root}/lib")
87
+ Camping.make_camp
62
88
  ensure
63
89
  @requires = []
64
- dirs = []
65
90
  new_apps = Camping::Apps - all_apps
66
91
 
67
92
  @apps = new_apps.inject({}) do |hash, app|
68
93
  if file = app.options[:__FILE__]
69
94
  full = File.expand_path(file)
70
95
  @requires << [file, full]
71
- dirs << full.sub(/\.[^.]+$/, '')
72
96
  end
73
97
 
74
98
  key = app.name.to_sym
75
99
  hash[key] = app
76
100
 
77
- if !old_apps.include?(key)
101
+ apps.each do |app|
78
102
  @callback.call(app) if @callback
79
103
  app.create if app.respond_to?(:create)
80
104
  end
@@ -84,12 +108,13 @@ module Camping
84
108
 
85
109
  ($LOADED_FEATURES - all_requires).each do |req|
86
110
  full = full_path(req)
87
- @requires << [req, full] if dirs.any? { |x| full.index(x) == 0 }
111
+ @requires << [req, full] # if dirs.any? { |x| full.index(x) == 0 }
88
112
  end
89
113
 
90
114
  @mtime = mtime
91
115
 
92
116
  self
117
+
93
118
  end
94
119
 
95
120
  # load_file
@@ -102,13 +127,15 @@ module Camping
102
127
  else
103
128
  load(@file)
104
129
  end
130
+ @requires << [@file, File.expand_path(@file)]
105
131
  end
106
132
 
107
- # Removes all the apps defined in this script.
108
- def remove_apps
109
- @requires.each do |(path, full)|
110
- $LOADED_FEATURES.delete(path)
111
- end
133
+ # removes all constants recursively included using this script as a root.
134
+ # so everything in /apps, and /lib in relation from this script.
135
+ def remove_constants
136
+ @requires.each do |(path, full)|
137
+ $LOADED_FEATURES.delete(path)
138
+ end
112
139
 
113
140
  @apps.each do |name, app|
114
141
  Camping::Apps.delete(app)
@@ -116,6 +143,7 @@ module Camping
116
143
  end.dup
117
144
  ensure
118
145
  @apps.clear
146
+ @requires.clear
119
147
  end
120
148
 
121
149
  # Reloads the file if needed. No harm is done by calling this multiple
@@ -125,8 +153,10 @@ module Camping
125
153
  reload!
126
154
  end
127
155
 
156
+ # Force a reload.
128
157
  def reload!
129
- load_apps(remove_apps)
158
+ remove_constants
159
+ load_everything
130
160
  end
131
161
 
132
162
  # Checks if both scripts watches the same file.
@@ -144,6 +174,46 @@ module Camping
144
174
 
145
175
  private
146
176
 
177
+ # sets up Zeit autoloading for the script locations.
178
+ def setup_zeit(loader)
179
+ loader.push_dir("#{@root}/apps") if can_add_directory "#{@root}/apps"
180
+ loader.push_dir("#{@root}/lib") if can_add_directory "#{@root}/lib"
181
+ loader.enable_reloading if ENV['environment'] == 'development'
182
+ loader.setup
183
+ end
184
+
185
+ # verifies that we can add a directory to the loader.
186
+ # used for testing to prevent multiple loaders from watching the same directory.
187
+ def can_add_directory(directory)
188
+ if Dir.exist?("#{@root}/apps")
189
+ Loaders.each do |loader|
190
+ return false if loader.dirs.include? directory
191
+ end
192
+ true
193
+ else
194
+ false
195
+ end
196
+ end
197
+
198
+ # Splits the descendent files and folders found in a given directory for eager loading and recursion.
199
+ def folders_and_files_in(directory)
200
+ directory = directory + "/*" # unless directory
201
+ [Dir.glob(directory).select {|f| !File.directory? f },
202
+ Dir.glob(directory).select {|f| File.directory? f }]
203
+ end
204
+
205
+ # Reloads a directory recursively. loading more shallow files before deeper files.
206
+ def reload_directory(directory)
207
+ files, folders = folders_and_files_in(directory)
208
+ files.each {|file|
209
+ @requires << [file, File.expand_path(file)]
210
+ load file
211
+ }
212
+ folders.each {|folder|
213
+ reload_directory folder
214
+ }
215
+ end
216
+
147
217
  def mtime
148
218
  @requires.map do |(path, full)|
149
219
  File.mtime(full)
@@ -161,4 +231,7 @@ module Camping
161
231
  end
162
232
  end
163
233
  end
234
+
235
+ Reloader = Loader
236
+
164
237
  end
data/lib/camping/loads.rb CHANGED
@@ -8,8 +8,8 @@ require 'bundler/setup'
8
8
 
9
9
  # internal dependencies
10
10
  require 'camping/tools'
11
+ require 'camping/campguide'
11
12
  require 'camping/gear/filters'
12
13
  require 'camping/gear/nancy'
13
14
  require 'camping/gear/inspection'
14
15
  require 'camping/gear/kuddly'
15
-
@@ -3,7 +3,7 @@ require 'erb'
3
3
  require 'rack'
4
4
  require 'rackup'
5
5
  require 'camping/version'
6
- require 'camping/reloader'
6
+ require 'camping/loader'
7
7
  require 'camping/commands'
8
8
 
9
9
  # == The Camping Server (for development)
@@ -128,9 +128,10 @@ module Camping
128
128
  exit
129
129
  end
130
130
 
131
+ @reloader.reload!
132
+ r = @reloader
133
+
131
134
  if options[:routes] == true
132
- @reloader.reload!
133
- r = @reloader
134
135
  eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil }
135
136
  ARGV.clear
136
137
  Camping::Commands.routes
@@ -139,16 +140,11 @@ module Camping
139
140
 
140
141
  if options[:server] == "console"
141
142
  puts "** Starting console"
142
- @reloader.reload!
143
- r = @reloader
144
143
  eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil }
145
144
  ARGV.clear
146
145
  IRB.start
147
146
  exit
148
147
  else
149
- @reloader.reload!
150
- r = @reloader
151
- Camping.make_camp
152
148
  name = server.name[/\w+$/]
153
149
  puts "** Starting #{name} on #{options[:Host]}:#{options[:Port]}"
154
150
  super
@@ -215,7 +211,6 @@ module Camping
215
211
  def call(env)
216
212
  if ENV['environment'] == 'development'
217
213
  @reloader.reload
218
- Camping.make_camp
219
214
  end
220
215
 
221
216
  # our switch statement iterates through possible app outcomes, no apps
@@ -1,5 +1,5 @@
1
1
  require 'rack/session'
2
- class InsecureSecret < Exception #:nodoc: all
2
+ class InsecureSecretError < Exception #:nodoc: all
3
3
  end
4
4
  module Camping
5
5
  # == Getting Started
@@ -31,7 +31,7 @@ module Camping
31
31
  def self.included(app)
32
32
  key = "#{app}.state".downcase
33
33
  secret = app.options[:secret] || ['camping-secret',__FILE__, File.mtime('Rakefile')].join(":")*2
34
- raise InsecureSecret, "You're Session Secret is too short. Minimum length is 64." if secret.length < 64
34
+ raise InsecureSecretError, "Your Session Secret is too short. Minimum length is 64." if secret.length < 64
35
35
  app.use Rack::Session::Cookie, :key => key, :secrets => secret
36
36
  end
37
37
  end
@@ -1,5 +1,5 @@
1
1
  module Camping
2
- VERSION = "3.0.2"
2
+ VERSION = "3.1.2"
3
3
  def self.version
4
4
  VERSION
5
5
  end