Changelog History
Page 1
-
v2.0.0.alpha8
May 19, 2022 -
v2.0.0.alpha7
March 08, 2020 -
v2.0.0.alpha6 Changes
February 10, 2022โ Added
- ๐ [Luca Guidi] Official support for Ruby: MRI 3.1
[Tim Riley] Introduce partial Slice imports and exports. It allows to selectively export a functionality from a slice and import into another.
Import from
search
slice, usessearch
as the imported key namespace:# config/application.rb module MyApp class Application < Hanami::Application config.slice(:admin) do import(from: :search) end end end
Import from
search
slice with custom namespace:# config/application.rb module MyApp class Application < Hanami::Application config.slice(:admin) do import(from: :search, as: :search_engine) end end end
Import specific keys from
search
slice# config/application.rb module MyApp class Application < Hanami::Application config.slice(:admin) do import(keys: ["run_query"], from: :search) end end end
Export only specific keys from
search
slice, and import them inadmin
# config/application.rb module MyApp class Application < Hanami::Application config.slice(:admin) do import(from: :search) end config.slice(:search) do container.config.exports = %w[run_query index_item] end end end
๐ Fixed
- [Luca Guidi] Ensure request logger to respect logger formatter option.
๐ Changed
- ๐ [Luca Guidi] Drop support for Ruby: MRI 2.6 and 2.7.
- [Tim Riley]
Hanami.init
=>Hanami.prepare
andhanami/init
=>hanami/prepare
- [Tim Riley]
Hanami.register_bootable
=>Hanami.register_provider
- [Tim Riley]
Hanami.start_bootable
=>Hanami.start
- [Tim Riley]
Hanami::Slice#init
=>Hanami::Slice#prepare
- [Tim Riley]
Hanami::Slice#register_bootable
=>Hanami::Slice#register_provider
- [Tim Riley]
Hanami::Slice#start_bootable
=>Hanami::Slice#start
-
v2.0.0.alpha5 Changes
January 12, 2022๐ Changed
๐ง [Luca Guidi] Sensible default configuration for application logger, with per-environment defaults:
The defaults are:
- In production, log for level
info
, send logs to$stdout
in JSON format without colours - In development, log for level
debug
, send logs to$stdout
in single-line format with colours - In test, log for level
debug
, send logs tolog/test.log
in single-line format without colours
To configure the logger:
module MyApp class Application < Hanami::Application config.logger.level = :info config.logger.stream = $stdout config.logger.stream = "/path/to/file" config.logger.stream = StringIO.new config.logger.format = :json config.logger.format = MyCustomFormatter.new config.logger.color = false # disable coloring config.logger.color = MyCustomColorizer.new config.logger.filters << "secret" # add config.logger.filters += ["yet", "another"] # add config.logger.filters = ["foo"] # replace # See https://ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger.html config.logger.options = ["daily"] # time based log rotation config.logger.options = [0, 1048576] # size based log rotation end end
To configure the logger for specific environments:
module MyApp class Application < Hanami::Application config.environment(:staging) do config.logger.level = :info end end end
To assign a custom replacement logger object:
module MyApp class Application < Hanami::Application config.logger = MyCustomLogger.new end end
- In production, log for level
[Tim Riley] Comprehensive
config.source_dirs
settingThis replaces the previous
component_dir_paths
setting, and contains two nested settings:config.source_dirs.component_dirs
(backed byDry::System::Config::ComponentDirs
), for directories of source files intended to be registered as componentsconfig.source_dirs.autoload_paths
, for directories of source files not intended for registration as components, but still to be made accessible by the autoloader
To add and configure your own additional component dirs:
module MyApp class Application < Hanami::Application # Adding a simple component dir config.source_dirs.component_dirs.add "serializers" # Adding a component dir with custom configuration config.source_dirs.component_dirs.add "serializers" do |dir| dir.auto_register = proc { |component| !component.identifier.start_with?("structs") } end end end
To customize the configuration of the default component dirs ("lib", "actions", "repositories", "views"):
module MyApp class Application < Hanami::Application # Customising a default component dir config.source_dirs.component_dirs.dir("lib").auto_register = proc { |component| !component.identifier.start_with?("structs") } # Setting default config to apply to all component dirs config.source_dirs.component_dirs.auto_register = proc { |component| !component.identifier.start_with?("entities") } # Removing a default component dir config.source_dirs.component_dirs.delete("views") end end
To configure the autoload paths (defaulting to
["entities"]
):module MyApp class Application < Hanami::Application # Adding your own autoload paths config.source_dirs.autoload_paths << "structs" # Or providing a full replacement config.source_dirs.autoload_paths = ["structs"] end end
[Tim Riley] Application router is lazy loaded (not requiring application to be fully booted) and now available via
Hanami.rack_app
orHanami.application.rack_app
, instead of the previousHanami.app
(which required the app to be booted first).
-
v2.0.0.alpha4 Changes
December 07, 2021โ Added
๐ [Luca Guidi] Manage Content Security Policy (CSP) with "zero-defaults" policy. New API to change CSP values and to disable the feature.
# Read a CSP value module MyApp class Application < Hanami::Application config.actions.content_security_policy[:base_uri] # => "'self'" end end
# Override a default CSP value module MyApp class Application < Hanami::Application # This line will generate the following CSP fragment # plugin-types ; config.actions.content_security_policy[:plugin_types] = nil end end
# Append to a default CSP value module MyApp class Application < Hanami::Application # This line will generate the following CSP fragment # script-src 'self' https://my.cdn.test; config.actions.content_security_policy[:script_src] += " https://my.cdn.test" end end
# Add a custom CSP key. Useful when CSP standard evolves. module MyApp class Application < Hanami::Application # This line will generate the following CSP fragment # my-custom-setting 'self'; config.actions.content_security_policy['my-custom-setting'] = "'self'" end end
# Delete a CSP key. module MyApp class Application < Hanami::Application config.actions.content_security_policy.delete(:object_src) end end
# Disable CSP feature. module MyApp class Application < Hanami::Application config.actions.content_security_policy = false end end
-
v2.0.0.alpha3 Changes
November 09, 2021โ Added
- [Luca Guidi] Added
Hanami.shutdown
to stop all bootable components in the application container - [Tim Riley] Added
component_dir_paths
application setting to allow for components to be loaded from additional directories inside each slice directory. To begin with, this defaults to%w[actions repositories views]
. Components inside these directories are expected to be namespaced to match the directory name; e.g. given amain
slice,slices/main/actions/home.rb
is expected to defineMain::Actions::Home
, and will be registered in the slice container as"actions.home"
.
๐ Changed
- [Tim Riley] A slice's classes can now be defined directly inside
slices/[slice_name]/lib/
; e.g. given amain
slice,slices/main/lib/example.rb
is expected to defineMain::Example
, and will be registered in the slice container as"example"
- ๐ง [Tim Riley] The root
lib/
directory is no longer configured as a component dir, and classes insidelib/[app_namespace]/
will no longer be auto-registered into the container. If you need to share components, create them in their own slices as appropriate, and import those slices into the other slices that require them. - ๐ง [Tim Riley]
lib/[app_namespace]/
is configured for autoloading, andlib/
is added to$LOAD_PATH
to support explicit requires for source files outsidelib/[app_namespace]/
. - ๐ง [Tim Riley] (Internal) Ported
Hanami::Configuration
and related classes to use dry-configurable - ๐ง [Tim Riley] Application inflector can be entirely replaced, if required, via
Hanami::Configuration#inflector=
. Custom inflection rules can still be provided to the default inflector viaHanami::Configuration#inflections
. ๐ง [Marc Busquรฉ] App settings are defined within a concrete class rather than an anonymous block, to allow for users to leverage the typical behavior of Ruby classes, such as for defining their own types module to use for coercing setting values. This class also relies on dry-configurable for its settings implementation, so the standard dry-configurable
setting
API is available, such as theconstructor:
anddefault:
options.# frozen_string_literal: true require "dry/types" require "hanami/application/settings" module TestApp class Settings < Hanami::Application::Settings # Example usage of a types module (previously not possible inside the anonymous block) Types = Dry.Types() setting :session_secret, constructor: Types::String.constrained(min_size: 20) setting :some_bool, constructor: Types::Params::Bool, default: false end end
[Marc Busquรฉ] Application
settings_loader
andsettings_loader_options
have been replaced withsettings_store
, which is an updated abstraction for providing setting values to work with the newHanami::Application::Settings
implementation noted above (seeApplication::Settings::DotenvStore
for the default store, which provides the same behavior as previously)๐ [Marc Busquรฉ] Routes are defined within a concrete class rather than an anonymous block, to provide consistency with the settings (noted above), as well a place for additional behavior (in future releases):
# frozen_string_literal: true require "hanami/application/routes" module MyApp class Routes < Hanami::Application::Routes define do slice :main, at: "/" do root to: "home.show" end end end end
- [Luca Guidi] Added
-
v2.0.0.alpha2 Changes
May 04, 2021โ Added
- ๐ [Luca Guidi] Official support for Ruby: MRI 3.0
- [Tim Riley] Code autoloading via Zeitwerk
- ๐ง [Tim Riley]
Hanami::Application
subclasses generate and configure aDry::System::Container
, accessible via.container
andAppNamespace::Container
, with several common container methods available directly via the application subclass (e.g.Bookshelf::Application["foo"]
orHanami.application["foo"]
) - [Tim Riley] Introduced
Hanami::Application.register_bootable
to register custom components - [Tim Riley] Introduced
Hanami::Application.keys
to get the list of resolved components [Tim Riley] Dynamically create an auto-injection mixin (e.g.
Bookshelf::Deps
)# frozen_string_literal: true module Bookshelf class CreateThing include Deps[service_client: "some_service.client"] def call(attrs) # Validate attrs, etc. service_client.create(attrs) end end end
[Tim Riley] Introduced application settings. They are accessible via
Hanami.application.settings
inconfig/settings.rb
๐ [Tim Riley] Introduced application slices to organise high-level application concerns. Slices are generated based on subdirectories of
slices/
, and map onto corresponding ruby module namespaces, e.g.slices/main
->Main
, with the slice instance itself beingMain::Slice
(as well as being accessible viaHanami.application.slices[:main]
)๐ง [Tim Riley] Each slice generates and configures has its own
Dry::System::Container
, accessible via the slice instance (e.g.Main::Slice.container
) as well as via its own constant (e.g.Main::Container
)[Tim Riley] Slice containers automatically import the application container, under the
"application"
namespace[Tim Riley] Allow slice containers to be imported by other slice containers
๐ Changed
- ๐ [Luca Guidi] Drop support for Ruby: MRI 2.5
- ๐ [Tim Riley] Removed
config.cookies
in favor ofconfig.actions.cookies
- ๐ [Tim Riley] Removed
config.sessions
in favor ofconfig.actions.sessions
- ๐ [Tim Riley] Removed
config.security
settings
-
v2.0.0.alpha1 Changes
January 30, 2019โ Added
- [Luca Guidi] Implemented from scratch
hanami version
- [Luca Guidi] Implemented from scratch
hanami server
- ๐ง [Luca Guidi] Main configuration is opinionated: when a setting is not specified in generated code, it uses a framework default.
- ๐ง [Luca Guidi] Main configuration setting
environment
: to yield env based settings (e.g.config.environment(:production) { |c| c.logger = {...} }
) - [Luca Guidi] Main configuration setting
base_url
: to set the base URL of the app (e.g.config.base_url = "https://example.com"
) - ๐ง [Luca Guidi] Main configuration setting
logger
: to set the logger options (e.g.config.logger = { level: :info, format: :json }
) - ๐ง [Luca Guidi] Main configuration setting
routes
: to set the path to routes file (e.g.config.routes = "path/to/routes"
) - ๐ง [Luca Guidi] Main configuration setting
cookies
: to set cookies options (e.g.config.cookies = { max_age: 300 }
) - ๐ง [Luca Guidi] Main configuration setting
sessions
: to set session options (e.g.config.sessions = :cookie, { secret: "abc" }
) - [Luca Guidi] Main configuration setting
default_request_format
: to set the fallback for request format (aka MIME Type) (e.g.config.default_request_format = :json
) - [Luca Guidi] Main configuration setting
default_response_format
: to set the default response format (aka MIME Type) (e.g.config.default_response_format = :json
) - ๐ง [Luca Guidi] Main configuration setting
middleware
to mount Rack middleware (e.g.config.middleware.use MyMiddleware, "argument"
) - ๐ [Luca Guidi] Main configuration setting
security
to set security settings (see below) - ๐ง [Luca Guidi] Main configuration setting
inflections
to configure inflections (e.g.config.inflections { |i| i.plural "virus", "viruses" }
) - [Luca Guidi] Main configuration security setting
x_frame_options
: defaults to"deny"
(e.g.config.security.x_frame_options = "sameorigin"
) - [Luca Guidi] Main configuration security setting
x_content_type_options
: defaults to"nosniff"
(e.g.config.security.x_content_type_options = nil
) - [Luca Guidi] Main configuration security setting
x_xss_protection
: defaults to"1; mode=block"
(e.g.config.security.x_xss_protection = "1"
) - ๐ [Luca Guidi] Main configuration security setting
content_security_policy
: defaults to"form-action 'self'; frame-ancestors 'self'; base-uri 'self'; default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self' https: data:; style-src 'self' 'unsafe-inline' https:; font-src 'self'; object-src 'none'; plugin-types application/pdf; child-src 'self'; frame-src 'self'; media-src 'self'"
(e.g.config.security.content_security_policy[:style_src] += " https://my.cdn.example"
to add another source) (e.g.config.security.content_security_policy[:plugin_types] = nil
to override the settings)
๐ Changed
- ๐ [Luca Guidi] Drop support for Ruby: MRI 2.3, and 2.4.
- [Luca Guidi]
Hanami::Application
must be used as superclass for main application underconfig/application.rb
(e.g.Bookshelf::Application
) - ๐ง [Luca Guidi] Main configuration is available at
config/application.rb
instead ofconfig/enviroment.rb
- ๐ง [Luca Guidi] Removed
Hanami.configure
in favor of main application configuration (e.g.Bookshelf::Application.config
) - [Luca Guidi] Removed DSL syntax for main configuration (from
cookies max_age: 600
toconfig.cookies = { max_age: 600 }
) - [Luca Guidi] Per enviroment settings must be wrapped in a block (e.g.
config.enviroment(:production) { |c| c.logger = {} }
) - ๐ [Luca Guidi] Concrete applications are no longer supported (e.g.
Web::Application
inapps/web/application.rb
) - ๐ง [Luca Guidi] Main routes must be configured at
config/routes.rb
: ```ruby
- [Luca Guidi] Implemented from scratch
-
v1.3.4 Changes
May 02, 2021๐ Fixed
- [Slava Kardakov] Fix generated
config.ru
require_relative
statement - [Armin] Fix
Hanami::CommonLogger
elapsed time compatibility withrack
2.1.0+ - โ
[Adam Daniels] Fix generated tests compatibility with
minitest
6.0+
- [Slava Kardakov] Fix generated
-
v1.3.3 Changes
September 20, 2019โ Added
- ๐ [Gray Manley] Standardize file loading for
.env
files (see: https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use)
๐ Fixed
- โ
[Alfonso Uceda & Luca Guidi] Ensure to use
:host
option when mounting an application in main router (e.g.mount Beta::Application.new, at: "/", host: "beta.hanami.test"
)
- ๐ [Gray Manley] Standardize file loading for