diff --git a/lib/mix/tasks/frontend.build.css.compile.ex b/lib/mix/tasks/frontend.build.css.compile.ex index 2a33e5e..af468db 100644 --- a/lib/mix/tasks/frontend.build.css.compile.ex +++ b/lib/mix/tasks/frontend.build.css.compile.ex @@ -6,12 +6,11 @@ defmodule Mix.Tasks.Frontend.Build.Css.Compile do def bin(), do: node_bin("node-sass") - def out_path(:prod), do: "#{tmp_path()}/compiled/css" - def out_path(_), do: "#{dist_path()}/css" + def out_path(), do: "#{tmp_path()}/compiled/css" def args(), do: [ "-o", - out_path(Mix.env()), + out_path(), "--source-map", "true", "--include-path", diff --git a/lib/mix/tasks/frontend.build.css.copy.ex b/lib/mix/tasks/frontend.build.css.copy.ex new file mode 100644 index 0000000..35119a0 --- /dev/null +++ b/lib/mix/tasks/frontend.build.css.copy.ex @@ -0,0 +1,20 @@ +defmodule Mix.Tasks.Frontend.Build.Css.Copy do + use Mix.Task + import MebeWeb.{TaskUtils, FrontendConfs} + + @shortdoc "Copy compiled CSS to target dir" + + def do_copy() do + # Ensure target path exists + out_path = "#{dist_path()}/css" + File.mkdir_p!(out_path) + + File.cp_r!(Mix.Tasks.Frontend.Build.Css.Compile.out_path(), out_path) + end + + def run(_) do + run_task("frontend.build.css.compile") + + do_copy() + end +end diff --git a/lib/mix/tasks/frontend.build.css.ex b/lib/mix/tasks/frontend.build.css.ex index f973ee2..babe6cc 100644 --- a/lib/mix/tasks/frontend.build.css.ex +++ b/lib/mix/tasks/frontend.build.css.ex @@ -7,7 +7,7 @@ defmodule Mix.Tasks.Frontend.Build.Css do def run(_) do task = case Mix.env() do :prod -> "frontend.build.css.minify" - _ -> "frontend.build.css.compile" + _ -> "frontend.build.css.copy" end run_task(task) diff --git a/lib/mix/tasks/frontend.build.css.minify.ex b/lib/mix/tasks/frontend.build.css.minify.ex index 40dc217..e67c312 100644 --- a/lib/mix/tasks/frontend.build.css.minify.ex +++ b/lib/mix/tasks/frontend.build.css.minify.ex @@ -8,7 +8,7 @@ defmodule Mix.Tasks.Frontend.Build.Css.Minify do def run(_) do run_task("frontend.build.css.compile") - in_path = "#{tmp_path()}/compiled/css" + in_path = Mix.Tasks.Frontend.Build.Css.Compile.out_path() in_file = "#{in_path}/app.css" out_path = "#{dist_path()}/css" out_file = "#{out_path}/app.css" diff --git a/lib/mix/tasks/frontend.build.js.bundle.ex b/lib/mix/tasks/frontend.build.js.bundle.ex index a9dd74f..63f39b1 100644 --- a/lib/mix/tasks/frontend.build.js.bundle.ex +++ b/lib/mix/tasks/frontend.build.js.bundle.ex @@ -6,17 +6,16 @@ defmodule Mix.Tasks.Frontend.Build.Js.Bundle do def bin(), do: node_bin("rollup") - def out_path(:prod), do: "#{tmp_path()}/bundled/js" - def out_path(_), do: "#{dist_path()}/js" + def out_path(), do: "#{tmp_path()}/bundled/js" def args() do - op = out_path(Mix.env()) + op = out_path() [ "--config", "rollup.config.js", "--input", - "#{tmp_path()}/transpiled/js/app.js", + "#{Mix.Tasks.Frontend.Build.Js.Transpile.out_path()}/app.js", "--output", "#{op}/app.js", "--format", @@ -26,9 +25,13 @@ defmodule Mix.Tasks.Frontend.Build.Js.Bundle do ] end + def do_bundle() do + bin() |> exec(args()) |> listen() + end + def run(_) do run_task("frontend.build.js.transpile") - bin() |> exec(args()) |> listen() + do_bundle() end end diff --git a/lib/mix/tasks/frontend.build.js.copy.ex b/lib/mix/tasks/frontend.build.js.copy.ex new file mode 100644 index 0000000..ee83467 --- /dev/null +++ b/lib/mix/tasks/frontend.build.js.copy.ex @@ -0,0 +1,20 @@ +defmodule Mix.Tasks.Frontend.Build.Js.Copy do + use Mix.Task + import MebeWeb.{TaskUtils, FrontendConfs} + + @shortdoc "Copy bundled JS to target dir" + + def do_copy() do + # Ensure target path exists + out_path = "#{dist_path()}/js" + File.mkdir_p!(out_path) + + File.cp_r!(Mix.Tasks.Frontend.Build.Js.Bundle.out_path(), out_path) + end + + def run(_) do + run_task("frontend.build.js.bundle") + + do_copy() + end +end diff --git a/lib/mix/tasks/frontend.build.js.ex b/lib/mix/tasks/frontend.build.js.ex index 313e2aa..f1a18cd 100644 --- a/lib/mix/tasks/frontend.build.js.ex +++ b/lib/mix/tasks/frontend.build.js.ex @@ -7,7 +7,7 @@ defmodule Mix.Tasks.Frontend.Build.Js do def run(_) do task = case Mix.env() do :prod -> "frontend.build.js.minify" - _ -> "frontend.build.js.bundle" + _ -> "frontend.build.js.copy" end run_task(task) diff --git a/lib/mix/tasks/frontend.build.js.minify.ex b/lib/mix/tasks/frontend.build.js.minify.ex index 0832174..32a8a00 100644 --- a/lib/mix/tasks/frontend.build.js.minify.ex +++ b/lib/mix/tasks/frontend.build.js.minify.ex @@ -8,7 +8,7 @@ defmodule Mix.Tasks.Frontend.Build.Js.Minify do def run(_) do run_task("frontend.build.js.bundle") - in_path = "#{tmp_path()}/bundled/js" + in_path = Mix.Tasks.Frontend.Build.Js.Bundle.out_path() in_file = "#{in_path}/app.js" out_path = "#{dist_path()}/js" out_file = "#{out_path}/app.js" diff --git a/lib/mix/tasks/frontend.build.js.transpile.ex b/lib/mix/tasks/frontend.build.js.transpile.ex index 9cddc4f..2b8a59c 100644 --- a/lib/mix/tasks/frontend.build.js.transpile.ex +++ b/lib/mix/tasks/frontend.build.js.transpile.ex @@ -6,10 +6,12 @@ defmodule Mix.Tasks.Frontend.Build.Js.Transpile do def bin(), do: node_bin("babel") + def out_path(), do: "#{tmp_path()}/transpiled/js" + def args(), do: [ "#{src_path()}/js", "--out-dir", - "#{tmp_path()}/transpiled/js", + out_path(), "--source-maps", "inline" ] diff --git a/lib/mix/tasks/frontend.watch.ex b/lib/mix/tasks/frontend.watch.ex index dcfdac8..bfd1fc1 100644 --- a/lib/mix/tasks/frontend.watch.ex +++ b/lib/mix/tasks/frontend.watch.ex @@ -1,9 +1,11 @@ defmodule Mix.Tasks.Frontend.Watch do use Mix.Task - import MebeWeb.{TaskUtils, FrontendConfs} + import MebeWeb.{TaskUtils} alias Mix.Tasks.Frontend.Build.Js.Transpile, as: TranspileJS alias Mix.Tasks.Frontend.Build.Js.Bundle, as: BundleJS + alias Mix.Tasks.Frontend.Build.Js.Copy, as: CopyJS alias Mix.Tasks.Frontend.Build.Css.Compile, as: CompileCSS + alias Mix.Tasks.Frontend.Build.Css.Copy, as: CopyCSS @shortdoc "Watch frontend and rebuild when necessary" @@ -16,9 +18,16 @@ defmodule Mix.Tasks.Frontend.Watch do TranspileJS.args() ++ ["-w"] ), - exec( - BundleJS.bin(), - BundleJS.args() ++ ["-w"] + watch( + "JSBundle", + TranspileJS.out_path(), + fn _, _ -> Task.start_link(BundleJS, :do_bundle, []) end + ), + + watch( + "JSCopy", + BundleJS.out_path(), + fn _, _ -> CopyJS.do_copy() end ), exec( @@ -27,7 +36,13 @@ defmodule Mix.Tasks.Frontend.Watch do "-w", CompileCSS.scss_file() ] + ), + + watch( + "CSSCopy", + CompileCSS.out_path(), + fn _, _ -> CopyCSS.do_copy() end ) - ] |> watch() + ] |> listen(watch: true) end end diff --git a/lib/mix/tasks/utils.ex b/lib/mix/tasks/utils.ex index 09a6f3d..fb52e74 100644 --- a/lib/mix/tasks/utils.ex +++ b/lib/mix/tasks/utils.ex @@ -9,9 +9,9 @@ defmodule MebeWeb.TaskUtils do @default_task_timeout 60000 - defmodule Program do + defmodule ProgramSpec do @moduledoc """ - Program to execute with arguments. Name is used for prefixing logs. + Program that is executed with arguments. Name is used for prefixing logs. """ defstruct [ name: "", @@ -20,6 +20,22 @@ defmodule MebeWeb.TaskUtils do ] end + defmodule WatchSpec do + @moduledoc """ + Watch specification, target to watch and callback to execute on events. + Name is used for prefixing logs. + + Callback must have arity 2, gets filename/path and list of events as arguments. + """ + defstruct [ + name: "", + path: "", + callback: nil, + pid: nil, + name_atom: nil + ] + end + @doc """ Get configuration value. """ @@ -56,19 +72,13 @@ defmodule MebeWeb.TaskUtils do Tasks should be tuples {task_name, args} or binaries (no args). """ - def run_tasks(tasks, timeout \\ 60000) do - run_and_log = fn task, args -> - Logger.info("[Started] #{task}") - Mix.Task.run(task, args) - Logger.info("[Finished] #{task}") - end - + def run_tasks(tasks, timeout \\ @default_task_timeout) do tasks |> Enum.map(fn task when is_binary(task) -> - fn -> run_and_log.(task, []) end + fn -> Mix.Task.run(task, []) end {task, args} -> - fn -> run_and_log.(task, args) end + fn -> Mix.Task.run(task, args) end end) |> run_funs(timeout) end @@ -80,7 +90,7 @@ defmodule MebeWeb.TaskUtils do Functions can either be anonymous functions or tuples of {module, fun, args}. """ - def run_funs(funs, timeout \\ 60000) when is_list(funs) do + def run_funs(funs, timeout \\ @default_task_timeout) when is_list(funs) do funs |> Enum.map(fn fun when is_function(fun) -> @@ -103,6 +113,8 @@ defmodule MebeWeb.TaskUtils do - name: Use as name for logging, otherwise name of binary is used. - cd: Directory to change to before executing. + + Returns ProgramSpec for the started program. """ def exec(executable, args, opts \\ []) do name = Keyword.get( @@ -122,9 +134,9 @@ defmodule MebeWeb.TaskUtils do cd -> Keyword.put(options, :cd, cd) end - Logger.debug("[Spawned] #{name}") + Logger.debug("[Spawned] Program #{name}") - %Program{ + %ProgramSpec{ name: name, pending_output: "", port: Port.open( @@ -135,84 +147,117 @@ defmodule MebeWeb.TaskUtils do end @doc """ - Listen to messages from programs and print them to the screen. + Start watching a path. Name is used for prefixing logs. - Also listens to input from user and returns if input is given. + Path can point to a file or a directory in which case all subdirs will be watched. + + Returns a WatchSpec. """ - def listen(programs, task \\ nil, opts \\ []) + def watch(name, path, fun) do + name_atom = String.to_atom(name) + {:ok, pid} = :fs.start_link(name_atom, String.to_charlist(path)) + :fs.subscribe(name_atom) - def listen([], _, _), do: nil + Logger.debug("[Spawned] Watch #{name}") - def listen(%Program{} = program, task, opts) do - listen([program], task, opts) + %WatchSpec{ + name: name, + path: path, + callback: fun, + pid: pid, + name_atom: name_atom + } end - def listen(programs, task, opts) do + @doc """ + Listen to messages from specs and print them to the screen. + + If watch: true is given in the options, will listen for user's enter key and + kill programs if enter is pressed. + """ + def listen(specs, opts \\ []) + + # If there are no specs, stop running + def listen([], _), do: :ok + + def listen(spec, opts) when not is_list(spec) do + listen([spec], opts) + end + + def listen(specs, opts) when is_list(specs) do # Start another task to ask for user input if we are in watch mode task = with \ true <- Keyword.get(opts, :watch, false), - nil <- task, + nil <- Keyword.get(opts, :task), {:ok, task} <- Task.start_link(__MODULE__, :wait_for_input, [self()]) do + Logger.info("Programs/watches started, press ENTER to exit.") task end - programs = receive do + specs = receive do + # User pressed enter :user_input_received -> + Logger.info("ENTER received, killing tasks.") + Enum.each(specs, &kill/1) [] + # Program sent output with end of line {port, {:data, {:eol, msg}}} -> - program = Enum.find(programs, get_port_checker(port)) + program = Enum.find(specs, program_checker(port)) msg = :unicode.characters_to_binary(msg, :unicode) prefix = "[#{program.name}] #{program.pending_output}" Logger.debug(prefix <> msg) - programs - |> Enum.reject(get_port_checker(port)) + specs + |> Enum.reject(program_checker(port)) |> Enum.concat([ %{program | pending_output: ""} ]) + # Program sent output without end of line {port, {:data, {:noeol, msg}}} -> - program = Enum.find(programs, get_port_checker(port)) + program = Enum.find(specs, program_checker(port)) msg = :unicode.characters_to_binary(msg, :unicode) - programs - |> Enum.reject(get_port_checker(port)) + specs + |> Enum.reject(program_checker(port)) |> Enum.concat([ %{program | pending_output: "#{program.pending_output}#{msg}"} ]) # Port was closed normally after being told to close {port, :closed} -> - handle_closed(programs, port) + handle_closed(specs, port) # Port closed because the program closed by itself {port, {:exit_status, 0}} -> - handle_closed(programs, port) + handle_closed(specs, port) # Program closed with error status {port, {:exit_status, status}} -> - program = Enum.find(programs, get_port_checker(port)) + program = Enum.find(specs, program_checker(port)) Logger.error("Program #{program.name} returned status #{status}.") raise "Failed status #{status} from #{program.name}!" # Port crashed {:EXIT, port, _} -> - handle_closed(programs, port) + handle_closed(specs, port) + + # FS watch sent file event + {_, {:fs, :file_event}, {file, events}} -> + handle_events(specs, file, events) end - if not Enum.empty?(programs) do - listen(programs, task, opts) - end + listen(specs, Keyword.put(opts, :task, task)) end @doc """ Kill a running program returned by exec(). """ - def kill(%Program{name: name, port: port}) do + def kill(%ProgramSpec{name: name, port: port}) do if name != nil do Logger.debug("[Killing] #{name}") end @@ -221,21 +266,11 @@ defmodule MebeWeb.TaskUtils do end @doc """ - Print output from given programs to screen until user input is given. - - When user input is given, kill programs and return. + Kill a running watch. """ - def watch(%Program{} = program), do: watch([program]) - - def watch(programs) when is_list(programs) do - Logger.info("Programs started, press ENTER to exit.") - - listen(programs, nil, watch: true) - - Logger.info("ENTER received, killing tasks.") - - Enum.each(programs, &kill/1) - :ok + def kill(%WatchSpec{name: name, pid: pid}) do + Logger.debug("[Killing] #{name}") + Process.exit(pid, :kill) end @doc """ @@ -291,23 +326,57 @@ defmodule MebeWeb.TaskUtils do defp size_with_unit(size, unit), do: "#{size} #{unit}" - defp get_port_checker(port) do - fn %Program{port: program_port} -> - program_port == port + # Utility to find program in spec list based on port + defp program_checker(port) do + fn + %ProgramSpec{port: program_port} -> + program_port == port + + %WatchSpec{} -> + false end end - defp handle_closed(programs, port) do - case Enum.find(programs, get_port_checker(port)) do - %Program{} = program -> + # Utility to find watch in spec list based on path + defp watch_checker(path) do + fn + %ProgramSpec{} -> + false + + %WatchSpec{path: watch_path} -> + # If given path is relative to (under) the watch path or is the same + # path completely, it's a match. + path != watch_path and Path.relative_to(path, watch_path) != path + end + end + + defp handle_closed(specs, port) do + case Enum.find(specs, program_checker(port)) do + %ProgramSpec{} = program -> Logger.debug("[Stopped] #{program.name}") - programs - |> Enum.reject(get_port_checker(port)) + specs + |> Enum.reject(program_checker(port)) nil -> # Program was already removed - programs + specs end end + + defp handle_events(specs, file, events) do + file = to_string(file) + case Enum.find(specs, watch_checker(file)) do + %WatchSpec{name: name, callback: callback} -> + Logger.debug("[#{name}] Changed #{inspect(events)}: #{file}") + + callback.(file, events) + + nil -> + # Watch was maybe removed for some reason + Logger.debug("[Error] Watch sent event but path was not in specs list: #{inspect(events)} #{file}") + end + + specs + end end diff --git a/mix.exs b/mix.exs index fdb47bf..008834c 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule MebeWeb.Mixfile do use Mix.Project - def project do + def project() do [app: :mebe_web, version: "1.1.0", elixir: "~> 1.4.0", @@ -15,9 +15,13 @@ defmodule MebeWeb.Mixfile do # Configuration for the OTP application # # Type `mix help compile.app` for more information - def application do - [mod: {MebeWeb, []}, - applications: [:phoenix, :cowboy, :logger, :phoenix_html, :earmark, :calendar, :tzdata]] + def application() do + [ + mod: {MebeWeb, []}, + extra_applications: [ + :logger + ] + ] end # Specifies which paths to compile per environment @@ -27,7 +31,7 @@ defmodule MebeWeb.Mixfile do # Specifies your project dependencies # # Type `mix help deps` for examples and options - defp deps do + defp deps() do [ {:phoenix, "~> 1.2.1"}, {:phoenix_live_reload, "~> 1.0.7", only: :dev}, @@ -35,7 +39,8 @@ defmodule MebeWeb.Mixfile do {:cowboy, "~> 1.0.4"}, {:earmark, "~> 1.0.3"}, {:slugger, github: "h4cc/slugger", ref: "ef864669cdaae18d475600589c19c74e92ef67b4"}, - {:calendar, "~> 0.17.1"} + {:calendar, "~> 0.17.1"}, + {:fs, "~> 2.12.0", override: true, only: :dev} ] end end diff --git a/mix.lock b/mix.lock index 3a27afc..1c8eb0a 100644 --- a/mix.lock +++ b/mix.lock @@ -1,31 +1,22 @@ -%{"bbmustache": {:hex, :bbmustache, "1.0.4"}, - "calendar": {:hex, :calendar, "0.17.1", "5c7dfffde2b68011c2d6832ff1a15496292de965a3b57b3fad32405f1176f024", [:mix], [{:tzdata, "~> 0.5.8 or ~> 0.1.201603", [hex: :tzdata, optional: false]}]}, - "certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []}, - "cf": {:hex, :cf, "0.2.1"}, - "conform": {:hex, :conform, "1.0.0-rc8"}, +%{"calendar": {:hex, :calendar, "0.17.2", "d6b7bccc29c72203b076d4e488d967780bf2d123a96fafdbf45746fdc2fa342c", [:mix], [{:tzdata, "~> 0.5.8 or ~> 0.1.201603", [hex: :tzdata, optional: false]}]}, + "certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []}, "cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [:make, :rebar], [{:cowlib, "~> 1.0.0", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, optional: false]}]}, "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []}, "earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], []}, - "erlware_commons": {:hex, :erlware_commons, "0.18.0"}, - "exrm": {:hex, :exrm, "1.0.0-rc8"}, "fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], []}, - "getopt": {:hex, :getopt, "0.8.2"}, - "hackney": {:hex, :hackney, "1.6.5", "8c025ee397ac94a184b0743c73b33b96465e85f90a02e210e86df6cbafaa5065", [:rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, + "fwatch": {:hex, :fwatch, "0.5.0", "c61d9c1653ef5958770165315552e560c01202edd21ec05be9ba737ed44166e0", [:mix], [{:earmark, ">= 0.0.0", [hex: :earmark, optional: false]}, {:fs, "~> 0.9.1", [hex: :fs, optional: false]}]}, + "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, + "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, - "neotoma": {:hex, :neotoma, "1.7.3"}, - "phoenix": {:hex, :phoenix, "1.2.1", "6dc592249ab73c67575769765b66ad164ad25d83defa3492dc6ae269bd2a68ab", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, optional: false]}, {:plug, "~> 1.1", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}]}, - "phoenix_html": {:hex, :phoenix_html, "2.9.2", "371160b30cf4e10443b015efce6f03e1f19aae98ff6487620477b13a5b2ef660", [:mix], [{:plug, "~> 1.0", [hex: :plug, optional: false]}]}, - "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.7", "167ab0942e88d1d4a597996cf7dd8d2b014cc14d3f9472b58858cde8dd9ac2e4", [:mix], [{:fs, "~> 2.12.0", [hex: :fs, optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, optional: false]}]}, + "phoenix": {:hex, :phoenix, "1.2.3", "b68dd6a7e6ff3eef38ad59771007d2f3f344988ea6e658e9b2c6ffb2ef494810", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, optional: false]}, {:plug, "~> 1.4 or ~> 1.3.3 or ~> 1.2.4 or ~> 1.1.8 or ~> 1.0.5", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}]}, + "phoenix_html": {:hex, :phoenix_html, "2.9.3", "1b5a2122cbf743aa242f54dced8a4f1cc778b8bd304f4b4c0043a6250c58e258", [:mix], [{:plug, "~> 1.0", [hex: :plug, optional: false]}]}, + "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.8", "4333f9c74190f485a74866beff2f9304f069d53f047f5fbb0fb8d1ee4c495f73", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, optional: false]}]}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.1", "c10ddf6237007c804bf2b8f3c4d5b99009b42eca3a0dfac04ea2d8001186056a", [:mix], []}, - "plug": {:hex, :plug, "1.3.0", "6e2b01afc5db3fd011ca4a16efd9cb424528c157c30a44a0186bcc92c7b2e8f3", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, + "plug": {:hex, :plug, "1.3.4", "b4ef3a383f991bfa594552ded44934f2a9853407899d47ecc0481777fb1906f6", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, - "providers": {:hex, :providers, "1.6.0"}, - "ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], []}, - "relx": {:hex, :relx, "3.17.0"}, + "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}, "slugger": {:git, "https://github.com/h4cc/slugger.git", "ef864669cdaae18d475600589c19c74e92ef67b4", [ref: "ef864669cdaae18d475600589c19c74e92ef67b4"]}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5"}, - "tzdata": {:hex, :tzdata, "0.5.10", "087e8dfe8c0283473115ad8ca6974b898ecb55ca5c725427a142a79593391e90", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, optional: false]}]}} + "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, optional: false]}]}} diff --git a/package.json b/package.json index aa24b15..ba5dfae 100644 --- a/package.json +++ b/package.json @@ -6,19 +6,19 @@ "description": "Minimalistic Elixir Blog Engine", "private": true, "devDependencies": { - "babel-cli": "~6.22.2", - "babel-core": "~6.22.1", - "babel-polyfill": "~6.22.0", - "babel-preset-es2015": "~6.22.0", + "babel-cli": "~6.24.0", + "babel-core": "~6.24.0", + "babel-polyfill": "~6.23.0", + "babel-preset-es2015": "~6.24.0", "babel-preset-es2016": "~6.22.0", "babel-preset-es2017": "~6.22.0", "bootstrap-sass": "~3.3.7", "cssnano": "~3.10.0", "cssnano-cli": "~1.0.5", - "node-sass": "~4.3.0", - "rollup": "~0.41.4", + "node-sass": "~4.5.0", + "rollup": "~0.41.6", "rollup-plugin-sourcemaps": "~0.4.1", "rollup-watch": "~3.2.2", - "uglify-js": "~2.7.5" + "uglify-js": "~2.8.13" } }