lotusrb 0.2.0 → 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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +1 -1
  5. data/lib/lotus/application.rb +26 -1
  6. data/lib/lotus/application_name.rb +99 -0
  7. data/lib/lotus/cli.rb +8 -6
  8. data/lib/lotus/commands/console.rb +1 -1
  9. data/lib/lotus/commands/new.rb +13 -3
  10. data/lib/lotus/config/sessions.rb +1 -1
  11. data/lib/lotus/frameworks.rb +4 -23
  12. data/lib/lotus/generators/application/container/Gemfile.tt +1 -0
  13. data/lib/lotus/generators/application/container/Rakefile.rspec.tt +5 -0
  14. data/lib/lotus/generators/application/container/capybara.rb.rspec.tt +8 -0
  15. data/lib/lotus/generators/application/container/config/.env.development.tt +1 -1
  16. data/lib/lotus/generators/application/container/config/.env.test.tt +1 -1
  17. data/lib/lotus/generators/application/container/{features_helper.rb.tt → features_helper.rb.minitest.tt} +0 -0
  18. data/lib/lotus/generators/application/container/features_helper.rb.rspec.tt +12 -0
  19. data/lib/lotus/generators/application/container/lib/app_name.rb.tt +8 -2
  20. data/lib/lotus/generators/application/container/lib/config/mapping.rb.tt +7 -0
  21. data/lib/lotus/generators/application/container/rspec.rspec.tt +2 -0
  22. data/lib/lotus/generators/application/container/{spec_helper.rb.tt → spec_helper.rb.minitest.tt} +0 -0
  23. data/lib/lotus/generators/application/container/spec_helper.rb.rspec.tt +102 -0
  24. data/lib/lotus/generators/application/container.rb +20 -8
  25. data/lib/lotus/generators/slice.rb +10 -11
  26. data/lib/lotus/loader.rb +7 -0
  27. data/lib/lotus/logger.rb +141 -0
  28. data/lib/lotus/rendering_policy.rb +6 -21
  29. data/lib/lotus/templates/welcome.html +1 -1
  30. data/lib/lotus/version.rb +1 -1
  31. data/lib/lotus.rb +1 -0
  32. data/lotusrb.gemspec +3 -3
  33. metadata +27 -8
  34. data/lib/lotus/generators/slice/templates/application.html.erb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e0890eb6c32566368913554cabd9edeb2f00304
4
- data.tar.gz: 248452822b63ecc6ceb19224fa837d46bb3f5686
3
+ metadata.gz: 320e113169441d3fdb7bb851a72be8f17de2ec49
4
+ data.tar.gz: 89278bf192dad6ddeb32eba05f20fd140d455448
5
5
  SHA512:
6
- metadata.gz: 733c6c3d35a5939982b130b71d7cafd10ab78efa01594fac918adcbdce3bfd87d7ce8e9311c3b937aeccf93761ddb6704b8f02403092ca6ad54382a8b2f5a09b
7
- data.tar.gz: 59be6d52f37a14ca8d7190528496bc46ce67ee0f29745a38d3ee6459ea9f7cbf88cecd08f3987fa872726f5fdef3518a67166ad4a121ebf14558d6df05a323de
6
+ metadata.gz: 8f603661a19cc39c20aefa34afc8e150b0c1beb3d833658c4b075035b8fadb9c1d565f4b98907ff9ad4e44d71bec591f5542ca1c45e79a6b447ef2cf1ed24aa7
7
+ data.tar.gz: a29f1c9c800a857ce759e5d61618ee366afdb710dae60bc628142311d9a5daaf8904791cd023c77f538a3525f5f5a91fd4008064d6319f73449016f1cbcd0e4c
data/CHANGELOG.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # Lotus
2
2
  A complete web framework for Ruby
3
3
 
4
+ ## v0.2.1 - 2015-02-06
5
+ ### Added
6
+ - [Huy Do] Introduced `Lotus::Logger`
7
+ - [Jimmy Zhang] `lotus new` accepts a `--path` argument
8
+ - [Jimmy Zhang] Application generator for the current directory (`lotus new .`). This is useful to provide a web deliverable for existing Ruby gems.
9
+ - [Trung Lê] Add example mapping file for application generator: `lib/config/mapping.rb`
10
+ - [Hieu Nguyen] RSpec support for application generator: `--test=rspec` or `--test=minitest` (default)
11
+
12
+ ### Fixed
13
+ - [Luca Guidi] `lotus version` to previx `v` (eg `v0.2.1`)
14
+ - [Rob Yurkowski] Ensure application name doesn't contain special or forbidden characters
15
+ - [Luca Guidi] Ensure all the applications are loaded in console
16
+ - [Trung Lê] Container architecture: preload only `lib/<appname>/**/*.rb`
17
+ - [Hieu Nguyen] Fixed `lotus new` to print usage when application name isn't provided
18
+
4
19
  ## v0.2.0 - 2014-06-23
5
20
  ### Added
6
21
  - [Luca Guidi] Introduced `lotus new` as a command to generate applications. It supports "container" architecture for now.
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Luca Guidi
1
+ Copyright © 2014-2015 Luca Guidi
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -384,4 +384,4 @@ __Lotus__ uses [Semantic Versioning 2.0.0](http://semver.org)
384
384
 
385
385
  ## Copyright
386
386
 
387
- Copyright 2014 Luca Guidi – Released under MIT License
387
+ Copyright © 2014-2015 Luca Guidi – Released under MIT License
@@ -145,7 +145,14 @@ module Lotus
145
145
  Lotus::Loader.new(application).load!
146
146
  end
147
147
 
148
- # Preload all the registered applications
148
+ # Preload all the registered applications, by yielding their configurations
149
+ # and preparing the frameworks.
150
+ #
151
+ # This is useful for testing suites, where we want to make Lotus frameworks
152
+ # ready, but not preload applications code.
153
+ #
154
+ # This allows to test components such as views or actions in isolation and
155
+ # to have faster boot times.
149
156
  #
150
157
  # @return [void]
151
158
  #
@@ -154,6 +161,24 @@ module Lotus
154
161
  synchronize do
155
162
  applications.each(&:load!)
156
163
  end
164
+
165
+ nil
166
+ end
167
+
168
+ # Full preload for all the registered applications.
169
+ #
170
+ # This is useful in console where we want all the application code available.
171
+ #
172
+ # @return [void]
173
+ #
174
+ # @since 0.2.1
175
+ # @api private
176
+ def self.preload_applications!
177
+ synchronize do
178
+ applications.each { |app| app.new }
179
+ end
180
+
181
+ nil
157
182
  end
158
183
 
159
184
  # Return the configuration for this application
@@ -0,0 +1,99 @@
1
+ module Lotus
2
+ # An application name.
3
+ #
4
+ # @since 0.2.1
5
+ class ApplicationName
6
+
7
+ # A list of words that are prohibited from forming the application name
8
+ #
9
+ # @since 0.2.1
10
+ RESERVED_WORDS = %w(lotus).freeze
11
+
12
+
13
+ # Initialize and check against reserved words
14
+ #
15
+ # An application name needs to be translated in quite a few ways:
16
+ # First, it must be checked against a list of reserved words and rejected
17
+ # if it is invalid. Secondly, assuming it is not invalid, it must be able
18
+ # to be output roughly as given, but with the following changes:
19
+ #
20
+ # 1. downcased,
21
+ # 2. with surrounding spaces removed,
22
+ # 3. with internal whitespace rendered as underscores
23
+ # 4. with underscores de-duplicated
24
+ #
25
+ # which is the default output. It must also be transformable into an
26
+ # environment variable.
27
+ #
28
+ # @return [Lotus::ApplicationName] a new instance of the application name
29
+ #
30
+ # @since 0.2.1
31
+ def initialize(name)
32
+ @name = sanitize(name)
33
+ ensure_validity!
34
+ end
35
+
36
+
37
+ # Returns the cleaned application name.
38
+ #
39
+ # @example
40
+ # ApplicationName.new("my-App ").to_s # => "my-app"
41
+ #
42
+ # @since 0.2.1
43
+ def to_s
44
+ @name
45
+ end
46
+
47
+
48
+ # Returns the application name uppercased with non-alphanumeric characters
49
+ # as underscores.
50
+ #
51
+ # @example
52
+ # ApplicationName.new("my-app").to_env_s => "MY_APP"
53
+ #
54
+ # @since 0.2.1
55
+ def to_env_s
56
+ @name.upcase.gsub(/\W/, '_')
57
+ end
58
+
59
+
60
+ # Returns true if a potential application name matches one of the reserved
61
+ # words.
62
+ #
63
+ # @example
64
+ # Lotus::ApplicationName.invalid?("lotus") # => true
65
+ #
66
+ # @since 0.2.1
67
+ def self.invalid?(name)
68
+ RESERVED_WORDS.include?(name)
69
+ end
70
+
71
+
72
+ private
73
+
74
+ # Raises RuntimeError with explanation if the provided name is invalid.
75
+ #
76
+ # @api private
77
+ # @since 0.2.1
78
+ def ensure_validity!
79
+ if self.class.invalid?(@name)
80
+ raise RuntimeError,
81
+ "application name must not be any one of the following: " +
82
+ RESERVED_WORDS.join(", ")
83
+ end
84
+ end
85
+
86
+
87
+ # Cleans a string to be a functioning application name.
88
+ #
89
+ # @api private
90
+ # @since 0.2.1
91
+ def sanitize(name)
92
+ name
93
+ .downcase
94
+ .strip
95
+ .gsub(/\s/, '_')
96
+ .gsub(/_{2,}/, '_')
97
+ end
98
+ end
99
+ end
data/lib/lotus/cli.rb CHANGED
@@ -8,7 +8,7 @@ module Lotus
8
8
 
9
9
  desc 'version', 'prints Lotus version'
10
10
  def version
11
- puts Lotus::VERSION
11
+ puts "v#{ Lotus::VERSION }"
12
12
  end
13
13
 
14
14
  desc 'server', 'starts a lotus server'
@@ -61,14 +61,16 @@ module Lotus
61
61
  end
62
62
 
63
63
  desc 'new', 'generates a new application'
64
- method_option :architecture, aliases: '-a', desc: 'application architecture', type: :string, default: 'container'
65
- method_option :application, desc: 'application name', type: :string, default: 'web'
66
- method_option :application_base_url, desc: 'application base url', type: :string, default: '/'
67
- method_option :lotus_head, desc: 'use Lotus HEAD', type: :boolean, default: false
64
+ method_option :architecture, aliases: '-a', desc: 'application architecture', type: :string, default: 'container'
65
+ method_option :application, desc: 'application name', type: :string, default: 'web'
66
+ method_option :application_base_url, desc: 'application base url', type: :string, default: '/'
67
+ method_option :path, desc: 'path', type: :string
68
+ method_option :test, desc: 'application test framework (rspec/minitest)', type: :string, default: 'minitest'
69
+ method_option :lotus_head, desc: 'use Lotus HEAD', type: :boolean, default: false
68
70
  method_option :help, aliases: '-h', desc: 'displays the usage method'
69
71
 
70
72
  def new(name = nil)
71
- if options[:help]
73
+ if options[:help] || name.nil?
72
74
  invoke :help, ['new']
73
75
  else
74
76
  require 'lotus/commands/new'
@@ -28,7 +28,7 @@ module Lotus
28
28
 
29
29
  # Add convenience methods to the main:Object binding
30
30
  TOPLEVEL_BINDING.eval('self').send(:include, Methods)
31
- Lotus::Application.preload!
31
+ Lotus::Application.preload_applications!
32
32
 
33
33
  engine.start
34
34
  end
@@ -1,4 +1,5 @@
1
1
  require 'pathname'
2
+ require 'lotus/application_name'
2
3
  require 'lotus/utils/string'
3
4
  require 'lotus/utils/class'
4
5
 
@@ -9,12 +10,12 @@ module Lotus
9
10
 
10
11
  attr_reader :app_name, :source, :target, :cli, :options
11
12
 
12
- def initialize(app_name, environment, cli)
13
- @app_name = app_name
13
+ def initialize(app_name_or_path, environment, cli)
14
+ @app_name = ApplicationName.new(_get_real_app_name(app_name_or_path))
14
15
  @options = environment.to_options
15
16
  @arch = @options.fetch(:architecture)
16
17
 
17
- @target = Pathname.pwd.join(@app_name)
18
+ @target = Pathname.pwd.join(@options.fetch(:path, app_name_or_path))
18
19
  @source = Pathname.new(@options.fetch(:source) { ::File.dirname(__FILE__) + '/../generators/application/' }).join(@arch)
19
20
 
20
21
  @cli = cli
@@ -27,6 +28,15 @@ module Lotus
27
28
  def start
28
29
  @command.start
29
30
  end
31
+
32
+ private
33
+ def _get_real_app_name(app_name_or_path)
34
+ if app_name_or_path.include?(::File::SEPARATOR)
35
+ raise ArgumentError.new("Invalid application name. If you want to set application path, please use --path option")
36
+ end
37
+
38
+ app_name_or_path == '.' ? ::File.basename(Dir.getwd) : app_name_or_path
39
+ end
30
40
  end
31
41
  end
32
42
  end
@@ -17,7 +17,7 @@ module Lotus
17
17
 
18
18
  # Localhost string for detecting localhost host configuration
19
19
  #
20
- # @since x.x.x
20
+ # @since 0.2.0
21
21
  # @api private
22
22
  BLACKLISTED_DOMAINS = %w(localhost).freeze
23
23
 
@@ -1,29 +1,10 @@
1
1
  require 'lotus/router'
2
2
  require 'lotus/view'
3
3
  require 'lotus/controller'
4
+ require 'lotus/action/glue'
4
5
 
5
- module Lotus
6
- module Frameworks
7
- module Action
8
- module Rack
9
- ENV_KEY = 'lotus.action'.freeze
10
-
11
- protected
12
- def finish
13
- super
14
- @_env[ENV_KEY] = self
15
- end
16
- end
17
- end
18
- end
19
- end
20
-
21
- Lotus::Action::Rack.class_eval do
22
- prepend Lotus::Frameworks::Action::Rack
23
- end
24
-
25
- Lotus::Action.class_eval do
26
- def to_rendering
27
- exposures.merge(format: format)
6
+ Lotus::Controller.configure do
7
+ prepare do
8
+ include Lotus::Action::Glue
28
9
  end
29
10
  end
@@ -18,6 +18,7 @@ gem 'lotus-model', '<%= config[:lotus_model_version] %>'
18
18
 
19
19
  group :test do
20
20
  <%- if config[:test] == 'rspec' -%>
21
+ gem 'rspec'
21
22
  <%- else -%>
22
23
  gem 'minitest'
23
24
  <%- end -%>
@@ -0,0 +1,5 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
@@ -0,0 +1,8 @@
1
+ module RSpec
2
+ module FeatureExampleGroup
3
+ def self.included(group)
4
+ group.metadata[:type] = :feature
5
+ Capybara.app = Lotus::Container.new
6
+ end
7
+ end
8
+ end
@@ -1,2 +1,2 @@
1
1
  # Define ENV variables for development environment
2
- <%= config[:app_name].upcase %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_development"
2
+ <%= config[:app_name].to_env_s %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_development"
@@ -1,2 +1,2 @@
1
1
  # Define ENV variables for test environment
2
- <%= config[:app_name].upcase %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_test"
2
+ <%= config[:app_name].to_env_s %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_test"
@@ -0,0 +1,12 @@
1
+ # Require this file for feature tests
2
+ require_relative './spec_helper'
3
+
4
+ require 'capybara'
5
+ require 'capybara/rspec'
6
+
7
+ RSpec.configure do |config|
8
+ config.include RSpec::FeatureExampleGroup
9
+
10
+ config.include Capybara::DSL, feature: true
11
+ config.include Capybara::RSpecMatchers, feature: true
12
+ end
@@ -1,5 +1,5 @@
1
1
  require 'lotus/model'
2
- Dir["#{ __dir__ }/**/*.rb"].each { |file| require_relative file }
2
+ Dir["#{ __dir__ }/<%= config[:app_name] %>/**/*.rb"].each { |file| require_relative file }
3
3
 
4
4
  Lotus::Model.configure do
5
5
  # Database adapter
@@ -14,11 +14,17 @@ Lotus::Model.configure do
14
14
  # adapter type: :sql, uri: 'postgres://localhost/<%= config[:app_name] %>_development'
15
15
  # adapter type: :sql, uri: 'mysql://localhost/<%= config[:app_name] %>_development'
16
16
  #
17
- adapter type: :file_system, uri: ENV['<%= config[:app_name].upcase %>_DATABASE_URL']
17
+ adapter type: :file_system, uri: ENV['<%= config[:app_name].to_env_s %>_DATABASE_URL']
18
18
 
19
19
  ##
20
20
  # Database mapping
21
21
  #
22
+ # You can specify mapping file to load with:
23
+ #
24
+ # mapping "#{__dir__}/config/mapping"
25
+ #
26
+ # Alternatively, you can use a block syntax like the following:
27
+ #
22
28
  mapping do
23
29
  # collection :users do
24
30
  # entity User
@@ -0,0 +1,7 @@
1
+ # collection :users do
2
+ # entity User
3
+ # repository UserRepository
4
+ #
5
+ # attribute :id, Integer
6
+ # attribute :name, String
7
+ # end
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,102 @@
1
+ # Require this file for unit tests
2
+ ENV['LOTUS_ENV'] ||= 'test'
3
+
4
+ require_relative '../config/environment'
5
+
6
+ Dir[__dir__ + '/support/**/*.rb'].each { |f| require f }
7
+
8
+ # This file was generated by the `rspec --init` command. Conventionally, all
9
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
10
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
11
+ # this file to always be loaded, without a need to explicitly require it in any
12
+ # files.
13
+ #
14
+ # Given that it is always loaded, you are encouraged to keep this file as
15
+ # light-weight as possible. Requiring heavyweight dependencies from this file
16
+ # will add to the boot time of your test suite on EVERY test run, even for an
17
+ # individual file that may not need all of that loaded. Instead, consider making
18
+ # a separate helper file that requires the additional dependencies and performs
19
+ # the additional setup, and require it from the spec files that actually need
20
+ # it.
21
+ #
22
+ # The `.rspec` file also contains a few flags that are not defaults but that
23
+ # users commonly want.
24
+ #
25
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
26
+ RSpec.configure do |config|
27
+ # Preload application for testing in isolation components
28
+ config.before(:suite) { Lotus::Application.preload! }
29
+
30
+ # rspec-expectations config goes here. You can use an alternate
31
+ # assertion/expectation library such as wrong or the stdlib/minitest
32
+ # assertions if you prefer.
33
+ config.expect_with :rspec do |expectations|
34
+ # This option will default to `true` in RSpec 4. It makes the `description`
35
+ # and `failure_message` of custom matchers include text for helper methods
36
+ # defined using `chain`, e.g.:
37
+ # be_bigger_than(2).and_smaller_than(4).description
38
+ # # => "be bigger than 2 and smaller than 4"
39
+ # ...rather than:
40
+ # # => "be bigger than 2"
41
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
42
+ end
43
+
44
+ # rspec-mocks config goes here. You can use an alternate test double
45
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
46
+ config.mock_with :rspec do |mocks|
47
+ # Prevents you from mocking or stubbing a method that does not exist on
48
+ # a real object. This is generally recommended, and will default to
49
+ # `true` in RSpec 4.
50
+ mocks.verify_partial_doubles = true
51
+ end
52
+
53
+ # The settings below are suggested to provide a good initial experience
54
+ # with RSpec, but feel free to customize to your heart's content.
55
+ =begin
56
+ # These two settings work together to allow you to limit a spec run
57
+ # to individual examples or groups you care about by tagging them with
58
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
59
+ # get run.
60
+ config.filter_run :focus
61
+ config.run_all_when_everything_filtered = true
62
+
63
+ # Limits the available syntax to the non-monkey patched syntax that is
64
+ # recommended. For more details, see:
65
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
66
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
67
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
68
+ config.disable_monkey_patching!
69
+
70
+ # This setting enables warnings. It's recommended, but in some cases may
71
+ # be too noisy due to issues in dependencies.
72
+ config.warnings = true
73
+
74
+ # Many RSpec users commonly either run the entire suite or an individual
75
+ # file, and it's useful to allow more verbose output when running an
76
+ # individual spec file.
77
+ if config.files_to_run.one?
78
+ # Use the documentation formatter for detailed output,
79
+ # unless a formatter has already been configured
80
+ # (e.g. via a command-line flag).
81
+ config.default_formatter = 'doc'
82
+ end
83
+
84
+ # Print the 10 slowest examples and example groups at the
85
+ # end of the spec run, to help surface which specs are running
86
+ # particularly slow.
87
+ config.profile_examples = 10
88
+
89
+ # Run specs in random order to surface order dependencies. If you find an
90
+ # order dependency and want to debug it, you can fix the order by providing
91
+ # the seed, which is printed after each run.
92
+ # --seed 1234
93
+ config.order = :random
94
+
95
+ # Seed global randomization in this process using the `--seed` CLI option.
96
+ # Setting this allows you to use `--seed` to deterministically reproduce
97
+ # test failures related to randomization by passing the same `--seed` value
98
+ # as the one that triggered the failure.
99
+ Kernel.srand config.seed
100
+ =end
101
+ end
102
+
@@ -10,15 +10,18 @@ module Lotus
10
10
 
11
11
  @slice_generator = Slice.new(command)
12
12
  @lotus_head = options.fetch(:lotus_head)
13
+ @test = options[:test]
13
14
  @lotus_model_version = '~> 0.2'
14
15
 
15
16
  cli.class.source_root(source)
16
17
  end
17
18
 
18
19
  def start
20
+
19
21
  opts = {
20
22
  app_name: app_name,
21
23
  lotus_head: @lotus_head,
24
+ test: @test,
22
25
  lotus_model_version: @lotus_model_version
23
26
  }
24
27
 
@@ -30,6 +33,7 @@ module Lotus
30
33
  'config/.env.development.tt' => 'config/.env.development',
31
34
  'config/.env.test.tt' => 'config/.env.test',
32
35
  'lib/app_name.rb.tt' => "lib/#{ app_name }.rb",
36
+ 'lib/config/mapping.rb.tt' => 'lib/config/mapping.rb',
33
37
  }
34
38
 
35
39
  empty_directories = [
@@ -40,19 +44,27 @@ module Lotus
40
44
 
41
45
  case options[:test]
42
46
  when 'rspec'
47
+ templates.merge!(
48
+ 'Rakefile.rspec.tt' => 'Rakefile',
49
+ 'rspec.rspec.tt' => '.rspec',
50
+ 'spec_helper.rb.rspec.tt' => 'spec/spec_helper.rb',
51
+ 'features_helper.rb.rspec.tt' => 'spec/features_helper.rb',
52
+ 'capybara.rb.rspec.tt' => 'spec/support/capybara.rb'
53
+ )
43
54
  else # minitest (default)
44
55
  templates.merge!(
45
- 'Rakefile.minitest.tt' => 'Rakefile',
46
- 'spec_helper.rb.tt' => 'spec/spec_helper.rb',
47
- 'features_helper.rb.tt' => 'spec/features_helper.rb'
56
+ 'Rakefile.minitest.tt' => 'Rakefile',
57
+ 'spec_helper.rb.minitest.tt' => 'spec/spec_helper.rb',
58
+ 'features_helper.rb.minitest.tt' => 'spec/features_helper.rb'
48
59
  )
49
-
50
- empty_directories << [
51
- "spec/#{ app_name }/entities",
52
- "spec/#{ app_name }/repositories"
53
- ]
54
60
  end
55
61
 
62
+ empty_directories << [
63
+ "spec/#{ app_name }/entities",
64
+ "spec/#{ app_name }/repositories",
65
+ "spec/support"
66
+ ]
67
+
56
68
  templates.each do |src, dst|
57
69
  cli.template(source.join(src), target.join(dst), opts)
58
70
  end
@@ -1,6 +1,7 @@
1
1
  require 'securerandom'
2
2
  require 'lotus/generators/abstract'
3
3
  require 'lotus/utils/string'
4
+ require 'lotus/application_name'
4
5
 
5
6
  module Lotus
6
7
  module Generators
@@ -8,8 +9,9 @@ module Lotus
8
9
  def initialize(command)
9
10
  super
10
11
 
11
- @slice_name = options.fetch(:application)
12
- @upcase_slice_name = @slice_name.upcase
12
+ application_name = ApplicationName.new(options.fetch(:application))
13
+ @slice_name = application_name.to_s
14
+ @upcase_slice_name = application_name.to_env_s
13
15
  @classified_slice_name = Utils::String.new(@slice_name).classify
14
16
 
15
17
  @source = Pathname.new(::File.dirname(__FILE__) + '/../generators/slice')
@@ -44,15 +46,12 @@ module Lotus
44
46
  "public/stylesheets"
45
47
  ]
46
48
 
47
- case options[:test]
48
- when 'rspec'
49
- else # minitest (default)
50
- empty_directories << [
51
- "../../spec/#{ opts[:slice_name] }/features",
52
- "../../spec/#{ opts[:slice_name] }/controllers",
53
- "../../spec/#{ opts[:slice_name] }/views"
54
- ]
55
- end
49
+ # Add testing directories (spec/ is the default for both MiniTest and RSpec)
50
+ empty_directories << [
51
+ "../../spec/#{ opts[:slice_name] }/features",
52
+ "../../spec/#{ opts[:slice_name] }/controllers",
53
+ "../../spec/#{ opts[:slice_name] }/views"
54
+ ]
56
55
 
57
56
  ##
58
57
  # config/environment.rb
data/lib/lotus/loader.rb CHANGED
@@ -40,6 +40,7 @@ module Lotus
40
40
  _configure_model_framework! if defined?(Lotus::Model)
41
41
  _configure_controller_framework!
42
42
  _configure_view_framework!
43
+ _configure_logger!
43
44
  end
44
45
 
45
46
  def _configure_controller_framework!
@@ -87,6 +88,12 @@ module Lotus
87
88
  end
88
89
  end
89
90
 
91
+ def _configure_logger!
92
+ unless application_module.const_defined?('Logger', false)
93
+ logger = Lotus::Logger.new(application_module.to_s)
94
+ application_module.const_set('Logger', logger)
95
+ end
96
+ end
90
97
 
91
98
  def load_frameworks!
92
99
  _load_view_framework!
@@ -0,0 +1,141 @@
1
+ require 'logger'
2
+ require 'lotus/utils/string'
3
+
4
+ module Lotus
5
+ # Lotus logger
6
+ #
7
+ # Implement with the same interface of Ruby std lib `Logger`.
8
+ # It uses `STDOUT` as output device.
9
+ #
10
+ #
11
+ #
12
+ # When a Lotus application is initialized, it creates a logger for that specific application.
13
+ # For instance for a `Bookshelf::Application` a `Bookshelf::Logger` will be available.
14
+ #
15
+ # This is useful for auto-tagging the output. Eg (`[Booshelf]`).
16
+ #
17
+ # When used stand alone (eg. `Lotus::Logger.info`), it tags lines with `[Shared]`.
18
+ #
19
+ #
20
+ #
21
+ # The available severity levels are the same of `Logger`:
22
+ #
23
+ # * debug
24
+ # * error
25
+ # * fatal
26
+ # * info
27
+ # * unknown
28
+ # * warn
29
+ #
30
+ # Those levels are available both as class and instance methods.
31
+ #
32
+ # @since 0.2.1
33
+ #
34
+ # @see http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger.html
35
+ # @see http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger/Severity.html
36
+ #
37
+ # @example Basic usage
38
+ # require 'lotus'
39
+ #
40
+ # module Bookshelf
41
+ # class Application < Lotus::Application
42
+ # end
43
+ # end
44
+ #
45
+ # # Initialize the application with the following code:
46
+ # Bookshelf::Application.load!
47
+ # # or
48
+ # Bookshelf::Application.new
49
+ #
50
+ # Bookshelf::Logger.info('Hello')
51
+ # # => I, [2015-01-10T21:55:12.727259 #80487] INFO -- [Bookshelf] : Hello
52
+ #
53
+ # Bookshelf::Logger.new.info('Hello')
54
+ # # => I, [2015-01-10T21:55:12.727259 #80487] INFO -- [Bookshelf] : Hello
55
+ #
56
+ # @example Standalone usage
57
+ # require 'lotus'
58
+ #
59
+ # Lotus::Logger.info('Hello')
60
+ # # => I, [2015-01-10T21:55:12.727259 #80487] INFO -- [Lotus] : Hello
61
+ #
62
+ # Lotus::Logger.new.info('Hello')
63
+ # # => I, [2015-01-10T21:55:12.727259 #80487] INFO -- [Lotus] : Hello
64
+ #
65
+ # @example Custom tagging
66
+ # require 'lotus'
67
+ #
68
+ # Lotus::Logger.new('FOO').info('Hello')
69
+ # # => I, [2015-01-10T21:55:12.727259 #80487] INFO -- [FOO] : Hello
70
+ class Logger < ::Logger
71
+ # Lotus::Logger default formatter
72
+ #
73
+ # @since 0.2.1
74
+ # @api private
75
+ #
76
+ # @see http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger/Formatter.html
77
+ class Formatter < ::Logger::Formatter
78
+ # @since 0.2.1
79
+ # @api private
80
+ attr_writer :application_name
81
+
82
+ # @since 0.2.1
83
+ # @api private
84
+ #
85
+ # @see http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger/Formatter.html#method-i-call
86
+ def call(severity, time, progname, msg)
87
+ progname = "[#{@application_name}] #{progname}"
88
+ super(severity, time.utc, progname, msg)
89
+ end
90
+ end
91
+
92
+ # Default application name.
93
+ # This is used as a fallback for tagging purposes.
94
+ #
95
+ # @since 0.2.1
96
+ # @api private
97
+ DEFAULT_APPLICATION_NAME = 'Lotus'.freeze
98
+
99
+ # @since 0.2.1
100
+ # @api private
101
+ attr_writer :application_name
102
+
103
+ # Initialize a logger
104
+ #
105
+ # @param application_name [String] an optional application name used for
106
+ # tagging purposes
107
+ #
108
+ # @since 0.2.1
109
+ def initialize(application_name = nil)
110
+ super(STDOUT)
111
+
112
+ @application_name = application_name
113
+ @formatter = Lotus::Logger::Formatter.new.tap { |f| f.application_name = self.application_name }
114
+ end
115
+
116
+ # Returns the current application name, this is used for tagging purposes
117
+ #
118
+ # @return [String] the application name
119
+ #
120
+ # @since 0.2.1
121
+ def application_name
122
+ @application_name || _application_name_from_namespace || _default_application_name
123
+ end
124
+
125
+ private
126
+ # @since 0.2.1
127
+ # @api private
128
+ def _application_name_from_namespace
129
+ class_name = self.class.name
130
+ namespace = Utils::String.new(class_name).namespace
131
+
132
+ class_name != namespace and return namespace
133
+ end
134
+
135
+ # @since 0.2.1
136
+ # @api private
137
+ def _default_application_name
138
+ DEFAULT_APPLICATION_NAME
139
+ end
140
+ end
141
+ end
@@ -14,13 +14,8 @@ module Lotus
14
14
 
15
15
  LOTUS_ACTION = 'lotus.action'.freeze
16
16
 
17
- SUCCESSFUL_STATUSES = (200..201).freeze
18
- STATUSES_WITHOUT_BODY = Set.new((100..199).to_a << 204 << 205 << 301 << 302 << 304).freeze
19
- EMPTY_BODY = Array.new.freeze
20
- RENDERABLE_FORMATS = [:all, :html].freeze
21
- CONTENT_TYPE = 'Content-Type'.freeze
22
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
23
- HEAD = 'HEAD'.freeze
17
+ SUCCESSFUL_STATUSES = (200..201).freeze
18
+ RENDERABLE_FORMATS = [:all, :html].freeze
24
19
 
25
20
  def initialize(configuration)
26
21
  @controller_pattern = %r{#{ configuration.controller_pattern.gsub(/\%\{(controller|action)\}/) { "(?<#{ $1 }>(.*))" } }}
@@ -30,7 +25,7 @@ module Lotus
30
25
  end
31
26
 
32
27
  def render(env, response)
33
- body = _render(env, response) || _render_head(env)
28
+ body = _render(env, response)
34
29
 
35
30
  response[BODY] = Array(body) unless body.nil?
36
31
  response
@@ -47,7 +42,7 @@ module Lotus
47
42
  def _render_action(action, response)
48
43
  if successful?(response)
49
44
  view_for(action, response).render(
50
- action.to_rendering
45
+ action.exposures
51
46
  )
52
47
  end
53
48
  end
@@ -58,26 +53,16 @@ module Lotus
58
53
  end
59
54
  end
60
55
 
61
- def _render_head(env)
62
- EMPTY_BODY if head?(env)
63
- end
64
-
65
56
  def renderable?(env)
66
- !head?(env) and
67
- env.delete(LOTUS_ACTION)
57
+ ((action = env.delete(LOTUS_ACTION)) && action.renderable? ) and action
68
58
  end
69
59
 
70
60
  def successful?(response)
71
61
  SUCCESSFUL_STATUSES.include?(response[STATUS])
72
62
  end
73
63
 
74
- def head?(env)
75
- env[REQUEST_METHOD] == HEAD
76
- end
77
-
78
64
  def render_status_page?(action, response)
79
- RENDERABLE_FORMATS.include?(action.format) &&
80
- !STATUSES_WITHOUT_BODY.include?(response[STATUS])
65
+ RENDERABLE_FORMATS.include?(action.format)
81
66
  end
82
67
 
83
68
  def view_for(action, response)
@@ -43,7 +43,7 @@
43
43
  </div>
44
44
  </div>
45
45
  <div id="footer">
46
- &copy; 2014 Luca Guidi &mdash; Lotus is released under the MIT License.
46
+ &copy; 2015 Luca Guidi &mdash; Lotus is released under the MIT License.
47
47
  </div>
48
48
  </body>
49
49
  </html>
data/lib/lotus/version.rb CHANGED
@@ -2,5 +2,5 @@ module Lotus
2
2
  # Defines the version
3
3
  #
4
4
  # @since 0.1.0
5
- VERSION = '0.2.0'.freeze
5
+ VERSION = '0.2.1'.freeze
6
6
  end
data/lib/lotus.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'lotus/version'
2
2
  require 'lotus/application'
3
3
  require 'lotus/container'
4
+ require 'lotus/logger'
4
5
 
5
6
  # A complete web framework for Ruby
6
7
  #
data/lotusrb.gemspec CHANGED
@@ -19,9 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
  spec.required_ruby_version = '>= 2.0.0'
21
21
 
22
- spec.add_dependency 'lotus-utils', '~> 0.3', '>= 0.3.2'
23
- spec.add_dependency 'lotus-router', '~> 0.2'
24
- spec.add_dependency 'lotus-controller', '~> 0.3'
22
+ spec.add_dependency 'lotus-utils', '~> 0.3', '>= 0.3.4'
23
+ spec.add_dependency 'lotus-router', '~> 0.2', '>= 0.2.1'
24
+ spec.add_dependency 'lotus-controller', '~> 0.3', '>= 0.3.2'
25
25
  spec.add_dependency 'lotus-view', '~> 0.3'
26
26
  spec.add_dependency 'shotgun', '~> 0.9'
27
27
  spec.add_dependency 'dotenv', '~> 1.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lotusrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-23 00:00:00.000000000 Z
11
+ date: 2015-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lotus-utils
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '0.3'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.3.2
22
+ version: 0.3.4
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '0.3'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.3.2
32
+ version: 0.3.4
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: lotus-router
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -37,6 +37,9 @@ dependencies:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0.2'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.2.1
40
43
  type: :runtime
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -44,6 +47,9 @@ dependencies:
44
47
  - - "~>"
45
48
  - !ruby/object:Gem::Version
46
49
  version: '0.2'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.2.1
47
53
  - !ruby/object:Gem::Dependency
48
54
  name: lotus-controller
49
55
  requirement: !ruby/object:Gem::Requirement
@@ -51,6 +57,9 @@ dependencies:
51
57
  - - "~>"
52
58
  - !ruby/object:Gem::Version
53
59
  version: '0.3'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.3.2
54
63
  type: :runtime
55
64
  prerelease: false
56
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,6 +67,9 @@ dependencies:
58
67
  - - "~>"
59
68
  - !ruby/object:Gem::Version
60
69
  version: '0.3'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.3.2
61
73
  - !ruby/object:Gem::Dependency
62
74
  name: lotus-view
63
75
  requirement: !ruby/object:Gem::Requirement
@@ -184,6 +196,7 @@ files:
184
196
  - bin/lotus
185
197
  - lib/lotus.rb
186
198
  - lib/lotus/application.rb
199
+ - lib/lotus/application_name.rb
187
200
  - lib/lotus/cli.rb
188
201
  - lib/lotus/commands/console.rb
189
202
  - lib/lotus/commands/new.rb
@@ -206,29 +219,35 @@ files:
206
219
  - lib/lotus/generators/application/container/.gitkeep
207
220
  - lib/lotus/generators/application/container/Gemfile.tt
208
221
  - lib/lotus/generators/application/container/Rakefile.minitest.tt
222
+ - lib/lotus/generators/application/container/Rakefile.rspec.tt
223
+ - lib/lotus/generators/application/container/capybara.rb.rspec.tt
209
224
  - lib/lotus/generators/application/container/config.ru.tt
210
225
  - lib/lotus/generators/application/container/config/.env.development.tt
211
226
  - lib/lotus/generators/application/container/config/.env.test.tt
212
227
  - lib/lotus/generators/application/container/config/.env.tt
213
228
  - lib/lotus/generators/application/container/config/environment.rb.tt
214
229
  - lib/lotus/generators/application/container/db/.gitkeep
215
- - lib/lotus/generators/application/container/features_helper.rb.tt
230
+ - lib/lotus/generators/application/container/features_helper.rb.minitest.tt
231
+ - lib/lotus/generators/application/container/features_helper.rb.rspec.tt
216
232
  - lib/lotus/generators/application/container/lib/app_name.rb.tt
217
233
  - lib/lotus/generators/application/container/lib/chirp/entities/.gitkeep
218
234
  - lib/lotus/generators/application/container/lib/chirp/repositories/.gitkeep
219
- - lib/lotus/generators/application/container/spec_helper.rb.tt
235
+ - lib/lotus/generators/application/container/lib/config/mapping.rb.tt
236
+ - lib/lotus/generators/application/container/rspec.rspec.tt
237
+ - lib/lotus/generators/application/container/spec_helper.rb.minitest.tt
238
+ - lib/lotus/generators/application/container/spec_helper.rb.rspec.tt
220
239
  - lib/lotus/generators/slice.rb
221
240
  - lib/lotus/generators/slice/.gitkeep.tt
222
241
  - lib/lotus/generators/slice/action.rb.tt
223
242
  - lib/lotus/generators/slice/application.rb.tt
224
243
  - lib/lotus/generators/slice/config/mapping.rb.tt
225
244
  - lib/lotus/generators/slice/config/routes.rb.tt
226
- - lib/lotus/generators/slice/templates/application.html.erb
227
245
  - lib/lotus/generators/slice/templates/application.html.erb.tt
228
246
  - lib/lotus/generators/slice/templates/template.html.erb.tt
229
247
  - lib/lotus/generators/slice/view.rb.tt
230
248
  - lib/lotus/generators/slice/views/application_layout.rb.tt
231
249
  - lib/lotus/loader.rb
250
+ - lib/lotus/logger.rb
232
251
  - lib/lotus/middleware.rb
233
252
  - lib/lotus/rendering_policy.rb
234
253
  - lib/lotus/routes.rb
@@ -263,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
282
  version: '0'
264
283
  requirements: []
265
284
  rubyforge_project:
266
- rubygems_version: 2.2.2
285
+ rubygems_version: 2.4.5
267
286
  signing_key:
268
287
  specification_version: 4
269
288
  summary: A complete web framework for Ruby
@@ -1,9 +0,0 @@
1
- <!doctype HTML>
2
- <html>
3
- <head>
4
- <title>Chirp!</title>
5
- </head>
6
- <body>
7
- <%= yield %>
8
- </body>
9
- </html>