web-console 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of web-console might be problematic. Click here for more details.

Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.markdown +121 -0
  4. data/Rakefile +48 -0
  5. data/app/assets/javascripts/web_console/application.js +4 -0
  6. data/app/assets/javascripts/web_console/console_sessions.js +24 -0
  7. data/app/assets/stylesheets/web_console/application.css +13 -0
  8. data/app/assets/stylesheets/web_console/console_sessions.css +8 -0
  9. data/app/controllers/web_console/application_controller.rb +12 -0
  10. data/app/controllers/web_console/console_sessions_controller.rb +23 -0
  11. data/app/helpers/web_console/application_helper.rb +4 -0
  12. data/app/helpers/web_console/console_session_helper.rb +4 -0
  13. data/app/models/web_console/console_session.rb +107 -0
  14. data/app/views/layouts/web_console/application.html.erb +14 -0
  15. data/app/views/web_console/console_sessions/index.html.erb +4 -0
  16. data/config/routes.rb +5 -0
  17. data/lib/web-console.rb +1 -0
  18. data/lib/web_console.rb +7 -0
  19. data/lib/web_console/engine.rb +38 -0
  20. data/lib/web_console/fiber.rb +48 -0
  21. data/lib/web_console/repl.rb +59 -0
  22. data/lib/web_console/repl/dummy.rb +38 -0
  23. data/lib/web_console/repl/irb.rb +61 -0
  24. data/lib/web_console/stream.rb +27 -0
  25. data/lib/web_console/version.rb +3 -0
  26. data/test/controllers/web_console/console_sessions_controller_test.rb +57 -0
  27. data/test/dummy/README.rdoc +28 -0
  28. data/test/dummy/Rakefile +6 -0
  29. data/test/dummy/app/assets/javascripts/application.js +13 -0
  30. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  31. data/test/dummy/app/controllers/application_controller.rb +5 -0
  32. data/test/dummy/app/helpers/application_helper.rb +2 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/test/dummy/bin/bundle +3 -0
  35. data/test/dummy/bin/rails +4 -0
  36. data/test/dummy/bin/rake +4 -0
  37. data/test/dummy/config.ru +4 -0
  38. data/test/dummy/config/application.rb +15 -0
  39. data/test/dummy/config/boot.rb +5 -0
  40. data/test/dummy/config/database.yml +25 -0
  41. data/test/dummy/config/environment.rb +5 -0
  42. data/test/dummy/config/environments/development.rb +29 -0
  43. data/test/dummy/config/environments/production.rb +80 -0
  44. data/test/dummy/config/environments/test.rb +36 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  47. data/test/dummy/config/initializers/inflections.rb +16 -0
  48. data/test/dummy/config/initializers/mime_types.rb +5 -0
  49. data/test/dummy/config/initializers/secret_token.rb +12 -0
  50. data/test/dummy/config/initializers/session_store.rb +3 -0
  51. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  52. data/test/dummy/config/locales/en.yml +23 -0
  53. data/test/dummy/config/routes.rb +2 -0
  54. data/test/dummy/db/development.sqlite3 +0 -0
  55. data/test/dummy/db/schema.rb +16 -0
  56. data/test/dummy/db/test.sqlite3 +0 -0
  57. data/test/dummy/log/development.log +26591 -0
  58. data/test/dummy/log/test.log +78368 -0
  59. data/test/dummy/public/404.html +58 -0
  60. data/test/dummy/public/422.html +58 -0
  61. data/test/dummy/public/500.html +57 -0
  62. data/test/dummy/public/favicon.ico +0 -0
  63. data/test/dummy/tmp/cache/assets/development/sprockets/0280bb38c5058cc31c4fcd8c392a5ec4 +0 -0
  64. data/test/dummy/tmp/cache/assets/development/sprockets/05bd7b24c0a86010ebb28b50ac7cad52 +0 -0
  65. data/test/dummy/tmp/cache/assets/development/sprockets/2a48be7daff14cf56911b263cbe017c7 +0 -0
  66. data/test/dummy/tmp/cache/assets/development/sprockets/3a37adb5ebd079cf67dae597b8c2e4f8 +0 -0
  67. data/test/dummy/tmp/cache/assets/development/sprockets/4f79e5f341043e081becefe4952395c5 +0 -0
  68. data/test/dummy/tmp/cache/assets/development/sprockets/508ab3c25833ea537a5e3fc90df33595 +0 -0
  69. data/test/dummy/tmp/cache/assets/development/sprockets/5a8ab22e707dfc7ba00691f90e054d7e +0 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/5adcb7569cdd03204d650e285f19351f +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/654a1bde557d359b957dc0aa12b0dfa0 +0 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/71f57313d6c92f5483915a6c2d79a506 +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/7ec0041a47c34b44e52e836c01454a1a +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/a1534e0c08b73ad82c2edb8c364caa66 +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/a841a3af20a321912acfed87036438fb +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/ad8eea7f774b674c29708ca90952764f +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/b0741545b4917192ba7b5e803c2e323d +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/b3159b06164dd474ff8efc3c84aefbba +0 -0
  79. data/test/dummy/tmp/cache/assets/development/sprockets/b40b7c5b2003544010f30f0bd3fb81b2 +0 -0
  80. data/test/dummy/tmp/cache/assets/development/sprockets/bbbe6a3ce382662666a355d708c83d2d +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/c4e26d8dbebb3afd7013acfefa564dd1 +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/ca53fb2717d5aac2f1c3939d9444fe3b +0 -0
  83. data/test/dummy/tmp/cache/assets/development/sprockets/d6b37d10680a997662c379d0ff7cad27 +0 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/e1d89809967e81220dca66770c50aa67 +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/e3d5cafc071e8f9a8efc88fddf721947 +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/f44e2a41bd51a92a84f99847ea675ba3 +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/f4a21ed9cebe2c83a9d988504dc6720b +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/f4d45273ff5b44879dab0a16805f4309 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/f5deea0ae9671fdb035aefc6c4ba1109 +0 -0
  90. data/test/dummy/tmp/cache/assets/test/sprockets/0280bb38c5058cc31c4fcd8c392a5ec4 +0 -0
  91. data/test/dummy/tmp/cache/assets/test/sprockets/05bd7b24c0a86010ebb28b50ac7cad52 +0 -0
  92. data/test/dummy/tmp/cache/assets/test/sprockets/2a48be7daff14cf56911b263cbe017c7 +0 -0
  93. data/test/dummy/tmp/cache/assets/test/sprockets/3824a9e25e846a4916b3ac1d67060782 +0 -0
  94. data/test/dummy/tmp/cache/assets/test/sprockets/3a37adb5ebd079cf67dae597b8c2e4f8 +0 -0
  95. data/test/dummy/tmp/cache/assets/test/sprockets/4f79e5f341043e081becefe4952395c5 +0 -0
  96. data/test/dummy/tmp/cache/assets/test/sprockets/508ab3c25833ea537a5e3fc90df33595 +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/5a8ab22e707dfc7ba00691f90e054d7e +0 -0
  98. data/test/dummy/tmp/cache/assets/test/sprockets/5adcb7569cdd03204d650e285f19351f +0 -0
  99. data/test/dummy/tmp/cache/assets/test/sprockets/632346eda030b596f513fff2de181743 +0 -0
  100. data/test/dummy/tmp/cache/assets/test/sprockets/654a1bde557d359b957dc0aa12b0dfa0 +0 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/71f57313d6c92f5483915a6c2d79a506 +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/9b9aee85f29dc573732fbb4001ceda00 +0 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/a841a3af20a321912acfed87036438fb +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/bbbe6a3ce382662666a355d708c83d2d +0 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/ca53fb2717d5aac2f1c3939d9444fe3b +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/d6b37d10680a997662c379d0ff7cad27 +0 -0
  107. data/test/dummy/tmp/cache/assets/test/sprockets/e1d89809967e81220dca66770c50aa67 +0 -0
  108. data/test/dummy/tmp/cache/assets/test/sprockets/e3d5cafc071e8f9a8efc88fddf721947 +0 -0
  109. data/test/dummy/tmp/cache/assets/test/sprockets/f44e2a41bd51a92a84f99847ea675ba3 +0 -0
  110. data/test/dummy/tmp/cache/assets/test/sprockets/f4a21ed9cebe2c83a9d988504dc6720b +0 -0
  111. data/test/dummy/tmp/cache/assets/test/sprockets/f4d45273ff5b44879dab0a16805f4309 +0 -0
  112. data/test/dummy/tmp/cache/assets/test/sprockets/f5deea0ae9671fdb035aefc6c4ba1109 +0 -0
  113. data/test/dummy/tmp/pids/server.pid +1 -0
  114. data/test/helpers/web_console/console_session_helper_test.rb +6 -0
  115. data/test/models/console_session_test.rb +110 -0
  116. data/test/test_helper.rb +15 -0
  117. data/test/web_console/repl/dummy_test.rb +54 -0
  118. data/test/web_console/repl/irb_test.rb +108 -0
  119. data/test/web_console/repl_test.rb +15 -0
  120. data/test/web_console_test.rb +91 -0
  121. data/vendor/assets/javascripts/jquery.console.js +727 -0
  122. metadata +303 -0
@@ -0,0 +1,7 @@
1
+ require 'active_support/lazy_load_hooks'
2
+ require 'web_console/engine'
3
+ require 'web_console/repl'
4
+
5
+ module WebConsole
6
+ ActiveSupport.run_load_hooks(:web_console, self)
7
+ end
@@ -0,0 +1,38 @@
1
+ require 'ipaddr'
2
+ require 'rails/engine'
3
+ require 'jquery-rails'
4
+
5
+ module WebConsole
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace WebConsole
8
+
9
+ config.web_console = ActiveSupport::OrderedOptions.new
10
+ config.web_console.default_mount_path = '/console'
11
+ config.web_console.whitelisted_ips = '127.0.0.1'
12
+
13
+ initializer 'web_console.add_default_route' do |app|
14
+ # While we don't need the route in the test environment, we define it
15
+ # there as well, so we can easily test it.
16
+ if Rails.env.development? || Rails.env.test?
17
+ app.routes.append do
18
+ mount WebConsole::Engine => app.config.web_console.default_mount_path
19
+ end
20
+ end
21
+ end
22
+
23
+ initializer 'web_console.process_whitelisted_ips' do
24
+ # Ensure that it is an array of IPAddr instances and it is defaulted to
25
+ # 127.0.0.1 if not precent. Only unique entries are left in the end.
26
+ config.web_console.whitelisted_ips = Array(config.web_console.whitelisted_ips)
27
+ config.web_console.whitelisted_ips.map! do |ip|
28
+ ip.is_a?(IPAddr) ? ip : IPAddr.new(ip.presence || '127.0.0.1')
29
+ end.uniq!
30
+
31
+ # IPAddr instances can cover whole networks, so simplify the #include?
32
+ # check for the most common case.
33
+ def (config.web_console.whitelisted_ips).include?(ip)
34
+ ip.is_a?(IPAddr) ? super : any? { |net| net.include?(ip.to_s) }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ module WebConsole
2
+ # Poor Man's Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)
3
+ # (c) 2008 Aman Gupta (tmm1)
4
+ #
5
+ # For the purposes of our REPL adapters there is a need for fiber invocation
6
+ # across threads. The native implementation does not support that.
7
+ class FiberError < StandardError; end
8
+
9
+ class Fiber
10
+ def initialize
11
+ raise ArgumentError, 'new Fiber requires a block' unless block_given?
12
+
13
+ @yield = Queue.new
14
+ @resume = Queue.new
15
+
16
+ @thread = Thread.new { @yield.push [ *yield(*@resume.pop) ] }
17
+ @thread.abort_on_exception = true
18
+ @thread[:fiber] = self
19
+ end
20
+ attr_reader :thread
21
+
22
+ def resume(*args)
23
+ raise FiberError, 'dead fiber called' unless @thread.alive?
24
+ @resume.push(args)
25
+ result = @yield.pop
26
+ result.size > 1 ? result : result.first
27
+ end
28
+
29
+ def yield(*args)
30
+ @yield.push(args)
31
+ result = @resume.pop
32
+ result.size > 1 ? result : result.first
33
+ end
34
+
35
+ def self.yield(*args)
36
+ raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
37
+ fiber.yield(*args)
38
+ end
39
+
40
+ def self.current
41
+ Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
42
+ end
43
+
44
+ def inspect
45
+ "#<#{self.class}:0x#{self.object_id.to_s(16)}>"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,59 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module WebConsole
4
+ module REPL
5
+ extend self
6
+
7
+ # Registry of REPL implementations mapped to their correspondent adapter
8
+ # classes.
9
+ #
10
+ # Don't manually alter the registry. Use WebConsole::REPL.register_adapter
11
+ # for adding entries.
12
+ def adapters
13
+ @adapters ||= {}
14
+ end
15
+
16
+ # Register an adapter into the adapters registry.
17
+ #
18
+ # Registration maps and adapter class to an existing REPL implementation,
19
+ # that we call an adaptee constant. If the adaptee constant is not given,
20
+ # it is automatically derived from the adapter class name.
21
+ #
22
+ # For example, adapter named +WebConsole::REPL::IRB+ will derive the
23
+ # adaptee constant to +::IRB+.
24
+ #
25
+ # If a block is given, it would be evaluated right after the adapter
26
+ # registration.
27
+ def register_adapter(adapter_class, adaptee_constant = nil, options = {})
28
+ if adaptee_constant.is_a?(Hash)
29
+ options = adaptee_constant
30
+ adaptee_constant = nil
31
+ end
32
+ adaptee_constant = adapter_class if options[:standalone]
33
+ adaptee_constant ||= derive_adaptee_constant_from(adapter_class)
34
+ adapters[adaptee_constant] = adapter_class
35
+ yield if block_given?
36
+ end
37
+
38
+ # Get the default adapter for the given application.
39
+ #
40
+ # By default the application will be Rails.application and the adapter
41
+ # will be chosen from Rails.application.config.console.
42
+ #
43
+ # If no suitible adapter is found for the configured Rails console, a dummy
44
+ # adapter will be used. You can evaluate code in it, but it won't support
45
+ # any advanced features, like multiline code evaluation.
46
+ def default(app = Rails.application)
47
+ adapters[app.config.console || ::IRB] || adapters[Dummy]
48
+ end
49
+
50
+ private
51
+ def derive_adaptee_constant_from(cls, suffix = 'REPL')
52
+ "::#{cls.name.split('::').last.gsub(/#{suffix}$/i, '')}".constantize
53
+ end
54
+ end
55
+ end
56
+
57
+ # Require the builtin adapters.
58
+ require 'web_console/repl/irb'
59
+ require 'web_console/repl/dummy'
@@ -0,0 +1,38 @@
1
+ require 'web_console/stream'
2
+
3
+ module WebConsole
4
+ module REPL
5
+ # == Dummy\ Adapter
6
+ #
7
+ # Dummy adapter that is used as a fallback for REPL with no adapters.
8
+ #
9
+ # It provides only the most basic code evaluation with no multiline code
10
+ # support.
11
+ class Dummy
12
+ def initialize(binding = TOPLEVEL_BINDING)
13
+ @binding = binding
14
+ end
15
+
16
+ def prompt
17
+ '>> '
18
+ end
19
+
20
+ def send_input(input)
21
+ eval_result = nil
22
+ streams_output = Stream.threadsafe_capture! do
23
+ eval_result = @binding.eval(input).inspect
24
+ end
25
+ "#{streams_output}=> #{eval_result}\n"
26
+ rescue Exception => exc
27
+ exc.backtrace.join("\n")
28
+ end
29
+ end
30
+
31
+ register_adapter Dummy, standalone: true do
32
+ require 'rails/console/app'
33
+ require 'rails/console/helpers'
34
+
35
+ TOPLEVEL_BINDING.eval('self').send(:include, Rails::ConsoleMethods)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ require 'irb'
2
+ require 'web_console/fiber'
3
+ require 'web_console/stream'
4
+
5
+ module WebConsole
6
+ module REPL
7
+ # == IRB\ Adapter
8
+ #
9
+ # Adapter for the IRB REPL, which is the default Ruby on Rails console.
10
+ class IRB
11
+ # For some reason™ we have to be ::IRB::StdioInputMethod subclass to get
12
+ # #prompt populated.
13
+ #
14
+ # Not a pretty OOP, but for now, we just have to deal with it.
15
+ class FiberInputMethod < ::IRB::StdioInputMethod
16
+ def initialize; end
17
+
18
+ def gets
19
+ @previous = Fiber.yield
20
+ end
21
+
22
+ def encoding
23
+ (@previous || '').encoding
24
+ end
25
+ end
26
+
27
+ def initialize(binding = TOPLEVEL_BINDING)
28
+ initialize_irb_session!
29
+ @input = FiberInputMethod.new
30
+ @irb = ::IRB::Irb.new(::IRB::WorkSpace.new(binding), @input)
31
+ @fiber = Fiber.new { @irb.eval_input }.tap(&:resume)
32
+ finalize_irb_session!
33
+ end
34
+
35
+ def prompt
36
+ @input.prompt
37
+ end
38
+
39
+ def send_input(input)
40
+ Stream.threadsafe_capture! { @fiber.resume("#{input}\n") }
41
+ end
42
+
43
+ private
44
+ def initialize_irb_session!(ap_path = nil)
45
+ ::IRB.init_config(ap_path)
46
+ end
47
+
48
+ def finalize_irb_session!
49
+ ::IRB.conf[:MAIN_CONTEXT] = @irb.context
50
+ end
51
+ end
52
+
53
+ register_adapter IRB do
54
+ require 'rails/console/app'
55
+ require 'rails/console/helpers'
56
+
57
+ # Include all of the rails console helpers in the IRB session.
58
+ ::IRB::ExtendCommandBundle.send :include, Rails::ConsoleMethods
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,27 @@
1
+ module WebConsole
2
+ module Stream
3
+ extend Mutex_m
4
+
5
+ def self.threadsafe_capture!(*streams)
6
+ streams = [$stdout, $stderr] if streams.empty?
7
+ synchronize do
8
+ begin
9
+ streams_copy = streams.collect(&:dup)
10
+ replacement = Tempfile.new(name)
11
+ streams.each do |stream|
12
+ stream.reopen(replacement)
13
+ stream.sync = true
14
+ end
15
+ yield
16
+ streams.each(&:rewind)
17
+ replacement.read
18
+ ensure
19
+ replacement.unlink
20
+ streams.each_with_index do |stream, i|
21
+ stream.reopen(streams_copy[i])
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module WebConsole
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ module WebConsole
4
+ class ConsoleSessionsControllerTest < ActionController::TestCase
5
+ setup do
6
+ # Where does .stubs lives?
7
+ def @request.remote_ip; '127.0.0.1' end
8
+ end
9
+
10
+ test 'index is successful' do
11
+ get :index, use_route: 'web_console'
12
+ assert_response :success
13
+ end
14
+
15
+ test 'index creates new console session' do
16
+ assert_difference 'ConsoleSession::INMEMORY_STORAGE.size' do
17
+ get :index, use_route: 'web_console'
18
+ end
19
+ end
20
+
21
+ test 'update updates new console session' do
22
+ get :index, use_route: 'web_console'
23
+ assert_not_nil console_session = assigns(:console_session)
24
+
25
+ put :update, id: console_session.id, input: 42, use_route: 'web_console'
26
+ assert_match %r{42}, console_session.output
27
+ end
28
+
29
+ test 'update failes when session is no longer available' do
30
+ get :index, use_route: 'web_console'
31
+ assert_not_nil console_session = assigns(:console_session)
32
+
33
+ ConsoleSession::INMEMORY_STORAGE.delete(console_session.id)
34
+ put :update, id: console_session.id, input: 42, use_route: 'web_console'
35
+ assert_response :gone
36
+ end
37
+
38
+ test 'blocks requests from non-whitelisted ips' do
39
+ def @request.remote_ip; '128.0.0.1' end
40
+ get :index, use_route: 'web_console'
41
+ assert_response :unauthorized
42
+ end
43
+
44
+ test 'index generated path' do
45
+ assert_generates mount_path, {
46
+ use_route: 'web_console',
47
+ controller: 'console_sessions'
48
+ }, {}, {controller: 'console_sessions'}
49
+ end
50
+
51
+ private
52
+
53
+ def mount_path
54
+ WebConsole::Engine.config.web_console.default_mount_path
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
6
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')