web-console 0.1.0

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 (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')