New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core application #975
Merged
Merged
Core application #975
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
37e2d3e
Remove old isolation specs
jodosha fd6b2ab
Introduce Hanami::Application and Hanami.application
jodosha 59758a4
Introduce Hanami.boot
jodosha dc1de6a
Introduce Hanami::Application#initialize
jodosha 95441bd
Introduce Hanami::Application#call
jodosha 213f7a3
Introduce basic boot process via command line
jodosha e5b5765
Merge branch 'unstable' into feature/application
jodosha fb1735d
Depend on hanami-controller unstable branch
jodosha 1224b65
Configure HTTP sessions
jodosha 8e3b548
Configure Rack middleware
jodosha ccb305a
Eager load code under lib/
jodosha 540c3a2
Mount Rack middleware inside Hanami::Application
jodosha 43c891b
Mount HTTP sessions middleware, if sessions are enabled. Bare minimum…
jodosha 8f27a55
Configure HTTP cookies
jodosha eae516a
Configure security settings
jodosha 7119b4e
Prefer class reopening over class_eval
jodosha 01dc826
Require project action during booting time
jodosha 7de7234
Bare minimum container
jodosha 120e27e
Whitelist apps to load under apps/. This is useful for selective app …
jodosha ad8551c
Enhanced security settings to make them serializable into HTTP headers
jodosha 64ee78b
Separate actions settings per application basis
jodosha eb41752
Hanami::Configuration default_request_format and default_response_format
jodosha e772ba5
Configure logger and base_url. Introduce Hanami.logger. Introduce env…
jodosha 932b4c3
Configure inflections
jodosha eb5c2cd
Finalize hanami server command
jodosha 763e768
Expect to find application definition under config/application.rb
jodosha 808bb66
Update lib/hanami/cli/commands.rb
kaikuchn a66bce1
Merge branch 'unstable' into feature/application
jodosha 684d9f6
hanami server: simplify option parsing and make it faster
jodosha 3ab512c
Preserve frozen state for default settings in configuration
jodosha ed2f920
Renamed Hanami::Configuration#to_router => #router_settings
jodosha 257e988
HTTP sessions settings: use parallel assigment to clafify storage and…
jodosha d9566d3
Remove commented line
jodosha cfd7adb
Remove :root component from Container, and use the related configurat…
jodosha 75946d9
Introduce 'hanami/boot', a file to require and have your Hanami app b…
jodosha File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# frozen_string_literal: true | ||
|
||
require "hanami/configuration" | ||
require "hanami/routes" | ||
require "hanami/router" | ||
|
||
module Hanami | ||
# Hanami application | ||
# | ||
# @since 2.0.0 | ||
class Application | ||
@_mutex = Mutex.new | ||
|
||
def self.inherited(app) | ||
@_mutex.synchronize do | ||
app.class_eval do | ||
@_mutex = Mutex.new | ||
@_configuration = Hanami::Configuration.new(env: Hanami.env) | ||
|
||
extend ClassMethods | ||
include InstanceMethods | ||
end | ||
|
||
Hanami.application = app | ||
end | ||
end | ||
|
||
# Class method interface | ||
# | ||
# @since 2.0.0 | ||
module ClassMethods | ||
def configuration | ||
@_configuration | ||
end | ||
|
||
alias config configuration | ||
|
||
def routes(&blk) | ||
@_mutex.synchronize do | ||
if blk.nil? | ||
raise "Hanami.application.routes not configured" unless defined?(@_routes) | ||
|
||
@_routes | ||
else | ||
@_routes = Routes.new(&blk) | ||
end | ||
end | ||
end | ||
end | ||
|
||
# Instance method interface | ||
# | ||
# @since 2.0.0 | ||
module InstanceMethods | ||
def initialize(configuration: self.class.configuration, routes: self.class.routes) | ||
@app = Rack::Builder.new do | ||
configuration.for_each_middleware do |m, *args| | ||
use m, *args | ||
end | ||
|
||
run Hanami::Router.new(**configuration.router_settings, &routes) | ||
end | ||
end | ||
|
||
def call(env) | ||
@app.call(env) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# frozen_string_literal: true | ||
|
||
require "bundler/setup" | ||
require "hanami" | ||
|
||
Hanami.boot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# frozen_string_literal: true | ||
|
||
require "hanami/cli" | ||
|
||
module Hanami | ||
# Hanami CLI | ||
# | ||
# @since 1.1.0 | ||
class CLI | ||
# Register a command to expand Hanami CLI | ||
# | ||
# @param name [String] the command name | ||
# @param command [NilClass,Hanami::CLI::Command,Hanami::CLI::Commands::Command] | ||
# the optional command | ||
# @param aliases [Array<String>] an optional list of aliases | ||
# | ||
# @since 1.1.0 | ||
# | ||
# @example Third party gem | ||
# require "hanami/cli/commands" | ||
# | ||
# module Hanami | ||
# module Webpack | ||
# module CLI | ||
# module Commands | ||
# class Generate < Hanami::CLI::Command | ||
# desc "Generate Webpack configuration" | ||
# | ||
# def call(*) | ||
# # ... | ||
# end | ||
# end | ||
# end | ||
# end | ||
# end | ||
# end | ||
# | ||
# Hanami::CLI.register "generate webpack", Hanami::Webpack::CLI::Commands::Generate | ||
# | ||
# # $ bundle exec hanami generate | ||
# # Commands: | ||
# # hanami generate action APP ACTION # Generate an action for app | ||
# # hanami generate app APP # Generate an app | ||
# # hanami generate mailer MAILER # Generate a mailer | ||
# # hanami generate migration MIGRATION # Generate a migration | ||
# # hanami generate model MODEL # Generate a model | ||
# # hanami generate secret [APP] # Generate session secret | ||
# # hanami generate webpack # Generate Webpack configuration | ||
def self.register(name, command = nil, aliases: [], &blk) | ||
Commands.register(name, command, aliases: aliases, &blk) | ||
end | ||
|
||
# CLI commands registry | ||
# | ||
# @since 1.1.0 | ||
# @api private | ||
module Commands | ||
extend Hanami::CLI::Registry | ||
|
||
require "hanami/cli/commands/server" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# frozen_string_literal: true | ||
|
||
module Hanami | ||
# Hanami CLI | ||
# | ||
# @since 1.1.0 | ||
class CLI | ||
module Commands | ||
# @since 1.1.0 | ||
# @api private | ||
class Server < Command | ||
desc "Start Hanami server (only for development)" | ||
|
||
option :server, desc: "Force a server engine (eg, webrick, puma, thin, etc..)" | ||
option :host, desc: "The host address to bind to" | ||
option :port, desc: "The port to run the server on", aliases: ["-p"] | ||
option :debug, desc: "Turn on debug output", type: :boolean | ||
option :warn, desc: "Turn on warnings", type: :boolean | ||
option :daemonize, desc: "Daemonize the server", type: :boolean | ||
option :pid, desc: "Path to write a pid file after daemonize" | ||
|
||
example [ | ||
" # Basic usage (it uses the bundled server engine)", | ||
"--server=webrick # Force `webrick` server engine", | ||
"--host=0.0.0.0 # Bind to a host", | ||
"--port=2306 # Bind to a port" | ||
] | ||
|
||
# @since 1.1.0 | ||
# @api private | ||
def call(**args) | ||
require "hanami" | ||
require "hanami/container" | ||
require "hanami/server" | ||
|
||
options = parse_arguments(args) | ||
Hanami::Server.new(options).start | ||
end | ||
|
||
private | ||
|
||
DEFAULT_CONFIG = "config.ru" | ||
private_constant :DEFAULT_CONFIG | ||
|
||
DEFAULT_HOST = "0.0.0.0" | ||
private_constant :DEFAULT_HOST | ||
|
||
DEFAULT_PORT = "2300" | ||
private_constant :DEFAULT_PORT | ||
|
||
OPTIONAL_SETTINGS = %i[ | ||
server | ||
debug | ||
warn | ||
daemonize | ||
pid | ||
].freeze | ||
|
||
def parse_arguments(args) | ||
Hanami::Container.start(:env) | ||
|
||
{ | ||
config: DEFAULT_CONFIG, | ||
Host: host(args), | ||
Port: port(args), | ||
AccessLog: [] | ||
}.merge( | ||
args.slice(*OPTIONAL_SETTINGS) | ||
) | ||
end | ||
|
||
def host(args) | ||
args.fetch(:host) do | ||
ENV.fetch("HANAMI_HOST", DEFAULT_HOST) | ||
end | ||
end | ||
|
||
def port(args) | ||
args.fetch(:port) do | ||
ENV.fetch("HANAMI_PORT", DEFAULT_PORT) | ||
end | ||
end | ||
end | ||
end | ||
|
||
register "server", Commands::Server, aliases: ["s"] | ||
end | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we want a different name for this, since the pairing of
application
/app
may be a little confusing?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@timriley This is the only instance of
Hanami::Application
subclass in the process. So it's the app.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so for a booted application,
Hanami.application
is the application's class (via theHanami::Application.inherited
hook) andHanami.app
is the one instance of that application class? Is that right? i.e.I still feel like that's a pretty confusing pairing of names. "app" is just shorthand for "application", they're synonyms. It feels a little odd that we use them both here, holding 2 different (though obviously related) things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@timriley Which name do you suggest? 😃 Please remember that
Hanami.app
is short and memorable, and it's used by public facing integration specs.Eg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jodosha What about
project
for the container application? You used "project" four times in the main message to refer to this :) It's not quite as memorible or short asapp
, but it's not hard to remember either. I agree with @timriley that usingapp
andapplication
as different things would be confusing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure to if keeping project is a good idea. The intention is to remove the word "project" from the terminology. See my YT video.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could stick with app in both methods but disambiguate between the two with a suffix, e.g.
#application
and#application_class
? (maybe paired with shorter#app
aliases too)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that
app
returns an instance of the application, I would say a natural name for the other method should beapp_class
. I would also say this should be a private API anyway.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can understand some of the confusion between "Hanami project" referring to this whole effort, but I still think "project" is a natural and obvious way to talk about what the "umbrella" app is.
Will
apps/
be renamed toslices/
? They're still Rack-compatible apps. While I like the naming of "slices" and it seems appropriate, I feel like this is re-inventing the wheel and causes more confusion than it's worth.Hanami.app
(orHanami.application
) being a different thing fromHanami::App
is confusing. If we want to use "slice", we should go all the way and renameHanami::App
toHanami::Slice
. I don't think we should do that, but we should be consistent if we're changing the terminology.Django uses the
project
/application
distinction in the same way we have been: https://medium.com/@timmykko/a-quick-glance-of-django-for-beginners-688bc6630fab(Also, for others, here's the YouTube video, since it hasn't been linked in this PR yet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jodosha Thoughts on the above? ☝️ (Don't mean to bother you, I just want to make sure you saw it since I didn't mention you in the comment.) 🌸