lotusrb 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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>