diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba05bbfe..408649872 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v0.25.2 - 2020-02-03 + +* bug fixes +* performance improvements +* deps update + ## v0.22.9 - 2020-01-06 * refactoring of the Rendering engine (**breaking**) diff --git a/Project.toml b/Project.toml index 5f0f2f526..a385ce3da 100755 --- a/Project.toml +++ b/Project.toml @@ -47,16 +47,16 @@ URIParser = "0.4" julia = "1.2" [extras] +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" +LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04" -Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" -Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" -LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36" -Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" [targets] -test = ["SafeTestsets", "Test", "TestSetExtensions", "Pkg", "Random", "Revise", "Logging","LoggingExtras", "Sockets", "Dates"] +test = ["SafeTestsets", "Test", "TestSetExtensions", "Pkg", "Random", "Revise", "Logging", "LoggingExtras", "Sockets", "Dates"] diff --git a/files/new_app/config/initializers/logging.jl b/files/new_app/config/initializers/logging.jl index 62708c8ee..2b0794be2 100644 --- a/files/new_app/config/initializers/logging.jl +++ b/files/new_app/config/initializers/logging.jl @@ -9,11 +9,11 @@ function initialize_logging() isdir(Genie.config.path_log) || mkpath(Genie.config.path_log) LoggingExtras.DemuxLogger( LoggingExtras.FileLogger(joinpath(Genie.config.path_log, "$(Genie.config.app_env)-$(Dates.today()).log"), always_flush = true, append = true), - LoggingExtras.ConsoleLogger(stdout, Genie.config.log_level), + Logging.ConsoleLogger(stdout, Genie.config.log_level), include_current_global = false ) else - LoggingExtras.ConsoleLogger(stdout, Genie.config.log_level) + Logging.ConsoleLogger(stdout, Genie.config.log_level) end timestamp_logger(logger) = LoggingExtras.TransformerLogger(logger) do log @@ -25,4 +25,4 @@ function initialize_logging() nothing end -@async initialize_logging() \ No newline at end of file +initialize_logging() \ No newline at end of file diff --git a/files/new_app/config/initializers/searchlight.jl b/files/new_app/config/initializers/searchlight.jl index ce0bf091a..fe9af9f09 100644 --- a/files/new_app/config/initializers/searchlight.jl +++ b/files/new_app/config/initializers/searchlight.jl @@ -2,8 +2,7 @@ using SearchLight, SearchLight.QueryBuilder function initialize_searchlight() try - SearchLight.Configuration.load() |> SearchLight.Database.connect! - SearchLight.load_resources() + SearchLight.Configuration.load() |> SearchLight.connect! catch ex @error ex end diff --git a/files/new_app/db/connection.yml b/files/new_app/db/connection.yml index 996ad52c2..44ef72dbb 100644 --- a/files/new_app/db/connection.yml +++ b/files/new_app/db/connection.yml @@ -25,4 +25,4 @@ test: username: password: port: - config: + config: \ No newline at end of file diff --git a/src/AppServer.jl b/src/AppServer.jl index e3c3b5253..594cd6591 100755 --- a/src/AppServer.jl +++ b/src/AppServer.jl @@ -42,7 +42,7 @@ function startup(port::Int = Genie.config.server_port, host::String = Genie.conf verbose::Bool = false, ratelimit::Union{Rational{Int},Nothing} = nothing, server::Union{Sockets.TCPServer,Nothing} = nothing) :: ServersCollection - update_config(port, host, ws_port, async) + update_config(port, host, ws_port) if Genie.config.websockets_server SERVERS.websockets = @async HTTP.listen(host, ws_port) do req @@ -76,11 +76,10 @@ function startup(port::Int = Genie.config.server_port, host::String = Genie.conf end -function update_config(port::Int, host::String, ws_port::Int, async::Bool) :: Nothing +function update_config(port::Int, host::String, ws_port::Int) :: Nothing Genie.config.server_port = port Genie.config.server_host = host Genie.config.websockets_port = ws_port - Genie.config.run_as_server = ! async nothing end diff --git a/src/Generator.jl b/src/Generator.jl index a71166336..6f437fc62 100755 --- a/src/Generator.jl +++ b/src/Generator.jl @@ -4,23 +4,22 @@ Generates various Genie files. module Generator import Revise, SHA, Dates, Pkg, Logging -import Genie, Genie.FileTemplates, Genie.Inflector, Genie.Configuration, Genie.Util, Genie.Exceptions +import Genie const JULIA_PATH = joinpath(Sys.BINDIR, "julia") """ - newcontroller(cmd_args::Dict{String,Any}) :: Nothing + newcontroller(resource_name::String) :: Nothing Generates a new Genie controller file and persists it to the resources folder. """ -function newcontroller(cmd_args::Dict{String,Any}; path::String = ".", pluralize::Bool = true) :: Nothing - resource_name = cmd_args["controller:new"] - Genie.Inflector.is_singular(resource_name) && pluralize && (resource_name = Inflector.to_plural(resource_name)) +function newcontroller(resource_name::String; path::String = ".", pluralize::Bool = true, mvc_support::Bool = true) :: Nothing + Genie.Inflector.is_singular(resource_name) && pluralize && (resource_name = Genie.Inflector.to_plural(resource_name)) resource_name = uppercasefirst(resource_name) - resource_path = setup_resource_path(resource_name, path = path) + resource_path = mvc_support ? setup_resource_path(resource_name, path = path) : (ispath(path) ? path : mkpath(path)) cfn = controller_file_name(resource_name) write_resource_file(resource_path, cfn, resource_name, :controller, pluralize = pluralize) && @info "New controller created at $(abspath(joinpath(resource_path, cfn)))" @@ -30,16 +29,13 @@ end """ - newresource(cmd_args::Dict{String,Any}, config::Settings) :: Nothing + newresource(resource_name::String, config::Settings) :: Nothing Generates all the files associated with a new resource and persists them to the resources folder. """ -function newresource(cmd_args::Dict{String,Any}; path::String = ".", pluralize::Bool = true) :: Nothing - resource_name = uppercasefirst(cmd_args["resource:new"]) - - if Genie.Inflector.is_singular(resource_name) && pluralize - resource_name = Genie.Inflector.to_plural(resource_name) - end +function newresource(resource_name::String; path::String = ".", pluralize::Bool = true) :: Nothing + Genie.Inflector.is_singular(resource_name) && pluralize && + (resource_name = Genie.Inflector.to_plural(resource_name)) resource_path = setup_resource_path(resource_name, path = path) for (resource_file, resource_type) in [(controller_file_name(resource_name), :controller)] @@ -54,16 +50,6 @@ function newresource(cmd_args::Dict{String,Any}; path::String = ".", pluralize:: end -""" - newresource(resource_name::Union{String,Symbol}) :: Nothing - -Generates all the files associated with a new resource and persists them to the resources folder. -""" -function newresource(resource_name::Union{String,Symbol}; path::String = ".", pluralize::Bool = true) :: Nothing - newresource(Dict{String,Any}("resource:new" => string(resource_name)), path = path, pluralize = pluralize) -end - - """ setup_resource_path(resource_name::String) :: String @@ -89,7 +75,7 @@ end Generates all resouce files and persists them to disk. """ function write_resource_file(resource_path::String, file_name::String, resource_name::String, resource_type::Symbol; pluralize::Bool = true) :: Bool - resource_name = (pluralize ? (Inflector.to_plural(resource_name)) : resource_name) |> Inflector.from_underscores + resource_name = (pluralize ? (Genie.Inflector.to_plural(resource_name)) : resource_name) |> Genie.Inflector.from_underscores try if resource_type == :controller @@ -106,7 +92,7 @@ function write_resource_file(resource_path::String, file_name::String, resource_ if resource_type == :test resource_does_not_exist(resource_path, file_name) || return true open(joinpath(resource_path, file_name), "w") do f - name = pluralize ? (Inflector.tosingular(resource_name)) : resource_name + name = pluralize ? (Genie.Inflector.tosingular(resource_name)) : resource_name write(f, Genie.FileTemplates.newtest(resource_name, name)) end end diff --git a/src/Renderer.jl b/src/Renderer.jl index 2d4e30c66..3b06cd642 100755 --- a/src/Renderer.jl +++ b/src/Renderer.jl @@ -150,6 +150,17 @@ function WebRenderable(wr::WebRenderable, content_type::Symbol, status::Int, hea end +function WebRenderable(f::Function, args...) + fr::String = try + f()::String + catch + Base.invokelatest(f)::String + end + + WebRenderable(fr, args...) +end + + function render end diff --git a/src/Router.jl b/src/Router.jl index 3a171bdf2..6d5a0b1d2 100755 --- a/src/Router.jl +++ b/src/Router.jl @@ -459,10 +459,17 @@ function match_routes(req::HTTP.Request, res::HTTP.Response, params::Params) :: return try run_hook(controller, BEFORE_HOOK) - result = (Genie.Configuration.isdev() ? Base.invokelatest(r.action) : (r.action)()) |> to_response + # result = (Genie.Configuration.isdev() ? Base.invokelatest(r.action) : (r.action)()) |> to_response + result = try + (r.action)() |> to_response + catch + Base.invokelatest(r.action) |> to_response + end + run_hook(controller, AFTER_HOOK) result + catch ex if isa(ex, Genie.Exceptions.ExceptionalResponse) return ex.response @@ -520,7 +527,13 @@ function match_channels(req, msg::String, ws_client, params::Params) :: String return try run_hook(controller, BEFORE_HOOK) - result = (Genie.Configuration.isdev() ? Base.invokelatest(c.action) : (c.action)()) |> string + + result = try + (c.action)() |> string + catch + Base.invokelatest(c.action) |> string + end + run_hook(controller, AFTER_HOOK) result diff --git a/src/Toolbox.jl b/src/Toolbox.jl index 0969d7a8c..7ffa0e49c 100644 --- a/src/Toolbox.jl +++ b/src/Toolbox.jl @@ -104,30 +104,25 @@ end """ - new(cmd_args::Dict{String,Any}, config::Settings) :: Nothing - new(task_name::String, config::Settings = App.config) :: Nothing + new(task_name::String) :: Nothing Generates a new Genie task file. """ -function new(cmd_args::Dict{String,Any}, config::Genie.Configuration.Settings = Genie.config) :: Nothing - tfn = taskfilename(cmd_args, config) +function new(task_name::String) :: Nothing + task_name = validtaskname(task_name) + tfn = taskfilename(task_name) isfile(tfn) && throw(Genie.Exceptions.FileExistsException(tfn)) isdir(Genie.config.path_tasks) || mkpath(Genie.config.path_tasks) - f = open(tfn, "w") - write(f, Genie.FileTemplates.newtask(taskmodulename(cmd_args["task:new"]))) - close(f) + open(tfn, "w") do io + write(io, Genie.FileTemplates.newtask(taskmodulename(task_name))) + end @info "New task created at $tfn" nothing end -function new(task_name::String, config::Genie.Configuration.Settings = Genie.config) :: Nothing - new(Dict{String,Any}("task:new" => validtaskname(task_name)), config) - - nothing -end """ @@ -135,8 +130,8 @@ end Computes the name of a Genie task based on the command line input. """ -function taskfilename(cmd_args::Dict{String,Any}, config::Genie.Configuration.Settings = Genie.config) :: String - joinpath(Genie.config.path_tasks, cmd_args["task:new"] * ".jl") +function taskfilename(task_name::String) :: String + joinpath(Genie.config.path_tasks, "$task_name.jl") end diff --git a/src/genie_module.jl b/src/genie_module.jl index 25aa80e51..76ecea174 100644 --- a/src/genie_module.jl +++ b/src/genie_module.jl @@ -9,12 +9,12 @@ import REPL, REPL.Terminals """ - newcontroller(controller_name::String) :: Nothing + newcontroller(controller_name::Union{String,Symbol}) :: Nothing Creates a new `controller` file. If `pluralize` is `false`, the name of the controller is not automatically pluralized. """ -function newcontroller(controller_name::String; pluralize::Bool = true) :: Nothing - Generator.newcontroller(Dict{String,Any}("controller:new" => controller_name), pluralize = pluralize) +function newcontroller(controller_name::Union{String,Symbol}; path::String = ".", pluralize::Bool = true, mvc_support::Bool = false) :: Nothing + Generator.newcontroller(string(controller_name), path = path, pluralize = pluralize, mvc_support = mvc_support) load_resources() nothing @@ -22,15 +22,15 @@ end """ - newresource(resource_name::String; pluralize::Bool = true, context::Union{Module,Nothing} = nothing) :: Nothing + newresource(resource_name::Union{String,Symbol}; pluralize::Bool = true, context::Union{Module,Nothing} = nothing) :: Nothing Creates all the files associated with a new resource. If `pluralize` is `false`, the name of the resource is not automatically pluralized. """ -function newresource(resource_name::String; pluralize::Bool = true, context::Union{Module,Nothing} = nothing) :: Nothing +function newresource(resource_name::Union{String,Symbol}; path::String = ".", pluralize::Bool = true, context::Union{Module,Nothing} = nothing) :: Nothing context = default_context(context) - Generator.newresource(Dict{String,Any}("resource:new" => resource_name), pluralize = pluralize) + Generator.newresource(string(resource_name), path = path, pluralize = pluralize) try pluralize || error("SearchLight resources need to be pluralized") @@ -47,13 +47,14 @@ end """ - newtask(task_name::String) :: Nothing + newtask(task_name::Union{String,Symbol}) :: Nothing Creates a new Genie `Task` file. """ -function newtask(task_name::String) :: Nothing +function newtask(task_name::Union{String,Symbol}) :: Nothing + task_name = string(task_name) endswith(task_name, "Task") || (task_name = task_name * "Task") - Toolbox.new(Dict{String,Any}("task:new" => task_name), Genie.config) + Toolbox.new(task_name) nothing end diff --git a/src/renderers/Html.jl b/src/renderers/Html.jl index 5bd7b7335..e95b86a3e 100644 --- a/src/renderers/Html.jl +++ b/src/renderers/Html.jl @@ -74,7 +74,9 @@ function normal_element(elems::Vector, elem::String, args = [], attrs...) :: HTM for e in elems e === nothing && continue - if isa(e, Function) + if isa(e, Vector) + print(io, join(e)) + elseif isa(e, Function) print(io, e(), "\n") else print(io, e, "\n") @@ -299,7 +301,7 @@ end function Genie.Renderer.render(::Type{MIME"text/html"}, data::String; context::Module = @__MODULE__, layout::Union{String,Nothing} = nothing, vars...) :: Genie.Renderer.WebRenderable try - Genie.Renderer.WebRenderable(Base.invokelatest(render(data; context = context, layout = layout, vars...))::String) + render(data; context = context, layout = layout, vars...) |> Genie.Renderer.WebRenderable catch ex isa(ex, KeyError) && Genie.Renderer.changebuilds() # it's a view error so don't reuse them rethrow(ex) @@ -309,10 +311,9 @@ end function Genie.Renderer.render(::Type{MIME"text/html"}, viewfile::Genie.Renderer.FilePath; layout::Union{Nothing,Genie.Renderer.FilePath} = nothing, context::Module = @__MODULE__, vars...) :: Genie.Renderer.WebRenderable try - Genie.Renderer.WebRenderable(Base.invokelatest(render(viewfile; layout = layout, context = context, vars...))::String) + render(viewfile; layout = layout, context = context, vars...) |> Genie.Renderer.WebRenderable catch ex isa(ex, KeyError) && Genie.Renderer.changebuilds() # it's a view error so don't reuse them - rethrow(ex) end end @@ -543,7 +544,11 @@ end Renders a template file. """ function template(path::String; partial::Bool = true, context::Module = @__MODULE__) :: String - Base.invokelatest(get_template(path, partial = partial, context = context))::String + try + get_template(path, partial = partial, context = context) + catch + Base.invokelatest(get_template(path, partial = partial, context = context))::String + end end @@ -600,11 +605,9 @@ end function parsetags(code::String) :: String - code = replace(code, "<%"=>"""""") + replace( + replace(code, "<%"=>"""""") end @@ -689,15 +692,6 @@ macro foreach(f, arr) end -macro condblock(expr) - expr.args[2] = quote - join([$([arg for arg in expr.args[2].args if !isa(arg, LineNumberNode)]...),]) - end - - expr -end - - ### === ### ### EXCEPTIONS ### diff --git a/src/renderers/Js.jl b/src/renderers/Js.jl index 9d5470533..23ff46d1b 100644 --- a/src/renderers/Js.jl +++ b/src/renderers/Js.jl @@ -89,7 +89,7 @@ end function render(::Type{MIME"application/javascript"}, data::String; context::Module = @__MODULE__, vars...) :: Genie.Renderer.WebRenderable try - Genie.Renderer.WebRenderable(Base.invokelatest(render(data; context = context, vars...))::String, :javascript) + Genie.Renderer.WebRenderable(render(data; context = context, vars...), :javascript) catch ex isa(ex, KeyError) && Genie.Renderer.changebuilds() # it's a view error so don't reuse them rethrow(ex) @@ -99,7 +99,7 @@ end function render(::Type{MIME"application/javascript"}, viewfile::Genie.Renderer.FilePath; context::Module = @__MODULE__, vars...) :: Genie.Renderer.WebRenderable try - Genie.Renderer.WebRenderable(Base.invokelatest(render(viewfile; context = context, vars...))::String, :javascript) + Genie.Renderer.WebRenderable(render(viewfile; context = context, vars...), :javascript) catch ex isa(ex, KeyError) && Genie.Renderer.changebuilds() # it's a view error so don't reuse them rethrow(ex) diff --git a/src/renderers/Json.jl b/src/renderers/Json.jl index e3af32b54..67e322548 100644 --- a/src/renderers/Json.jl +++ b/src/renderers/Json.jl @@ -25,17 +25,17 @@ end function Genie.Renderer.render(::Type{MIME"application/json"}, datafile::Genie.Renderer.FilePath; context::Module = @__MODULE__, vars...) :: Genie.Renderer.WebRenderable - Genie.Renderer.WebRenderable(Base.invokelatest(render(datafile; context = context, vars...))::String, :json) + Genie.Renderer.WebRenderable(render(datafile; context = context, vars...), :json) end function Genie.Renderer.render(::Type{MIME"application/json"}, data::String; context::Module = @__MODULE__, vars...) :: Genie.Renderer.WebRenderable - Genie.Renderer.WebRenderable(Base.invokelatest(render(data; context = context, vars...))::String, :json) + Genie.Renderer.WebRenderable(render(data; context = context, vars...), :json) end function Genie.Renderer.render(::Type{MIME"application/json"}, data::Any) :: Genie.Renderer.WebRenderable - Genie.Renderer.WebRenderable(Base.invokelatest(render(data))::String, :json) + Genie.Renderer.WebRenderable(render(data), :json) end diff --git a/test/runtests.jl b/test/runtests.jl index 3003833b6..e314ab837 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,8 +5,6 @@ using Pkg using Test, TestSetExtensions, SafeTestsets using Genie -isdir(joinpath(Genie.config.path_build, Genie.Renderer.BUILD_NAME)) && rm(joinpath(Genie.config.path_build, Genie.Renderer.BUILD_NAME), force = true, recursive = true) - @testset ExtendedTestSet "Genie tests" begin @includetests ARGS end \ No newline at end of file diff --git a/test/tests_flax_control_flow_rendering.jl b/test/tests_flax_control_flow_rendering.jl index 75920cb1f..cf78ce9c1 100644 --- a/test/tests_flax_control_flow_rendering.jl +++ b/test/tests_flax_control_flow_rendering.jl @@ -6,10 +6,10 @@ view = raw"""
- <% if true %> + <% if true; [ %>

Hello

Welcome

- <% end %> + <% ]end %>
""" @test String(html(view).body) == raw"

Hello

Welcome

" @@ -21,10 +21,10 @@ view = raw"""
- <% if false %> + <% if false; [ %>

Hello

Welcome

- <% end %> + <% ]end %>
""" @test String(html(view).body) == raw"""
""" diff --git a/test/tests_fullstack_app.jl b/test/tests_fullstack_app.jl index d9a01179f..c6657adca 100644 --- a/test/tests_fullstack_app.jl +++ b/test/tests_fullstack_app.jl @@ -12,7 +12,7 @@ cd(workdir) Genie.newapp("fullstack_test", fullstack = true, testmode = true) - Genie.newcontroller("Foo", pluralize = false) + Genie.Generator.newcontroller("Foo", pluralize = false) @test isfile(joinpath("app", "resources", "foo", "FooController.jl")) == true mkpath(joinpath("app", "resources", "foo", "views")) diff --git a/test/tests_genie_generators.jl b/test/tests_genie_generators.jl index a75c5df23..f0d6f7fd9 100644 --- a/test/tests_genie_generators.jl +++ b/test/tests_genie_generators.jl @@ -93,7 +93,7 @@ workdir = Base.Filesystem.mktempdir() cd(workdir) - Genie.newcontroller("Yazoo") + Genie.Generator.newcontroller("Yazoo") @test isdir(joinpath(workdir, "app", "resources", "yazoo")) == true @test isfile(joinpath(workdir, "app", "resources", "yazoo", "YazooController.jl")) == true