Compare commits

...
18 Commits
Author SHA1 Message Date
José Valim c521bdb91a Release v1.15.4 2023-07-18 11:38:35 +02:00
José Valim bdbdf52122 Disable consolidation on archive.install 2023-07-17 19:14:29 +02:00
José Valim 7ff97fb930 Compute remove entries per dependency, closes #12801 2023-07-17 09:40:31 +02:00
Santiago Ferreira af378de03f Remove duplicated async: true option from example (#12798) 2023-07-17 00:13:06 +02:00
Jean Klingler 82c264bc36 Remove erlang doc duplicates in IEx (#12797) 2023-07-17 00:12:51 +02:00
José Valim 4fbed9fe12 Consider significant chunks from Erlang/OTP 26 2023-07-17 00:12:24 +02:00
Ievgen Pyrogov 1dbf121a78 Update io.ex (#12800)
Fix newlines in documentation for IO module
2023-07-17 00:12:24 +02:00
José Valim 694b9b0218 Release v1.15.3 2023-07-15 09:50:33 +02:00
José Valim 0a3df5068c Remove unsupport --no-deps-loading 2023-07-15 09:38:48 +02:00
José Valim 9e177fd592 Ensure load path is enabled on __mix_recompile__? 2023-07-15 09:23:32 +02:00
Thibaut Barrère 8422af4a2e Clarify upgrade path for Regex.regex? (#12785) (#12786) 2023-07-12 18:05:00 +02:00
José Valim b79c5a3b4c Consider optional apps in Mix.ensure_application! 2023-07-12 09:27:40 +02:00
José Valim 3bb0a8379d Disable tail call optimization on file root entries 2023-07-07 13:37:57 +02:00
Łukasz Samson fe0d57c4da Allow to opt out of starting apps in Mix.install (#12766) 2023-07-07 08:39:53 +02:00
José Valim 727a958c48 Clarify --no-pry vs --dbg pry 2023-07-06 12:36:21 +02:00
José Valim aa93d654ab Propagate diagnostics from inner compiler process 2023-07-06 09:42:54 +02:00
José Valim f5b71a79b2 Improve error message when IEx cannot boot 2023-07-03 16:33:43 +02:00
José Valim 173fc52610 Fix IEx --remsh on Erlang/OTP 25-
Closes #12746.
2023-07-03 16:33:43 +02:00
25 changed files with 229 additions and 130 deletions
+36
View File
@@ -117,6 +117,42 @@ in the long term.
See the new `Logger` documentation for more information on the
new features and on compatibility.
## v1.15.4 (2023-07-18)
### 1. Bug fixes
#### Mix
* [mix archive.build] Disable protocol consolidation when building archiveson archive.install
* [mix compile] Track removed files per local dependency (this addresses a bug where files depending on modules from path dependencies always recompiled)
* [mix release] Do not strip relevant chunks from Erlang/OTP 26
## v1.15.3 (2023-07-15)
### 1. Enhancements
#### Elixir
* [Kernel] Improve better stacktraces when executing unnested Elixir code in a file
#### Mix
* [Mix] Allow to opt out of starting apps in `Mix.install/2`
### 2. Bug fixes
#### Elixir
* [Code] Ensure `with_diagnostics` propagate warnings from inner Erlang passes
#### IEx
* [IEx] Fix `--remsh` on Erlang/OTP 25 and earlier
#### Mix
* [mix compile.elixir] Ensure `__mix_recompile__?` callbacks are properly invoked
## v1.15.2 (2023-07-01)
### 1. Bug fixes
+1 -1
View File
@@ -1 +1 @@
1.15.2
1.15.4
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/sh
set -e
ELIXIR_VERSION=1.15.2
ELIXIR_VERSION=1.15.4
if [ $# -eq 0 ] || { [ $# -eq 1 ] && { [ "$1" = "--help" ] || [ "$1" = "-h" ]; }; }; then
cat <<USAGE >&2
+1 -1
View File
@@ -1,6 +1,6 @@
@if defined ELIXIR_CLI_ECHO (@echo on) else (@echo off)
set ELIXIR_VERSION=1.15.2
set ELIXIR_VERSION=1.15.4
setlocal enabledelayedexpansion
if ""%1""=="""" if ""%2""=="""" goto documentation
+3 -3
View File
@@ -593,11 +593,11 @@ defmodule IO do
Another example where you might want to collect a user input
every new line and break on an empty line, followed by removing
redundant new line characters (`"\n"`):
redundant new line characters (`"\\n"`):
IO.stream(:stdio, :line)
|> Enum.take_while(&(&1 != "\n"))
|> Enum.map(&String.replace(&1, "\n", ""))
|> Enum.take_while(&(&1 != "\\n"))
|> Enum.map(&String.replace(&1, "\\n", ""))
"""
@spec stream(device, :line | pos_integer) :: Enumerable.t()
-11
View File
@@ -4903,17 +4903,6 @@ defmodule Kernel do
{expanded, nil}
end
# We do this so that the block is not tail-call optimized and stacktraces
# are not messed up. Basically, we just insert something between the return
# value of the block and what is returned by defmodule. Using just ":ok" or
# similar doesn't work because it's likely optimized away by the compiler.
block =
quote do
result = unquote(block)
:elixir_utils.noop()
result
end
escaped =
case env do
%{function: nil, lexical_tracker: pid} when is_pid(pid) ->
+1 -1
View File
@@ -295,7 +295,7 @@ defmodule Regex do
end
@doc false
@deprecated "Use Kernel.is_struct/2 or pattern match on %Regex{} instead"
@deprecated "Use Kernel.is_struct(term, Regex) or pattern match on %Regex{} instead"
def regex?(term)
def regex?(%Regex{}), do: true
def regex?(_), do: false
@@ -81,7 +81,7 @@ Version | Deprecated feature | Replaced by (ava
:-------| :-------------------------------------------------- | :---------------------------------------------------------------
[v1.15] | `Calendar.ISO.day_of_week/3` | `Calendar.ISO.day_of_week/4` (v1.11)
[v1.15] | `Exception.exception?/1` | `Kernel.is_exception/1` (v1.11)
[v1.15] | `Regex.regex?/1` | `Kernel.is_struct/2` (v1.11)
[v1.15] | `Regex.regex?/1` | `Kernel.is_struct/2` (`Kernel.is_struct(term, Regex)`) (v1.11)
[v1.15] | `Logger.warn/2` | `Logger.warning/2` (v1.11)
[v1.14] | `use Bitwise` | `import Bitwise` (v1.0)
[v1.14] | `~~~/1` | `bnot/2` (v1.0)
+14 -12
View File
@@ -16,7 +16,7 @@ quoted(Forms, File, Callback) ->
elixir_lexical:run(
Env,
fun (LexicalEnv) -> eval_or_compile(Forms, [], LexicalEnv) end,
fun (LexicalEnv) -> maybe_fast_compile(Forms, [], LexicalEnv) end,
fun (#{lexical_tracker := Pid}) -> Callback(File, Pid) end
),
@@ -32,7 +32,7 @@ file(File, Callback) ->
%% Evaluates the given code through the Erlang compiler.
%% It may end-up evaluating the code if it is deemed a
%% more efficient strategy depending on the code snippet.
eval_or_compile(Forms, Args, E) ->
maybe_fast_compile(Forms, Args, E) ->
case (?key(E, module) == nil) andalso allows_fast_compilation(Forms) andalso
(not elixir_config:is_bootstrap()) of
true -> fast_compile(Forms, E);
@@ -40,8 +40,9 @@ eval_or_compile(Forms, Args, E) ->
end,
ok.
compile(Quoted, ArgsList, E) ->
{Expanded, SE, EE} = elixir_expand:expand(Quoted, elixir_env:env_to_ex(E), E),
compile(Quoted, ArgsList, #{line := Line} = E) ->
Block = no_tail_optimize([{line, Line}], Quoted),
{Expanded, SE, EE} = elixir_expand:expand(Block, elixir_env:env_to_ex(E), E),
elixir_env:check_unused_vars(SE, EE),
{Module, Fun, Purgeable} =
@@ -55,7 +56,7 @@ spawned_compile(ExExprs, #{line := Line, file := File} = E) ->
{ErlExprs, _} = elixir_erl_pass:translate(ExExprs, erl_anno:new(Line), S),
Module = retrieve_compiler_module(),
Fun = code_fun(?key(E, module)),
Fun = code_fun(?key(E, module)),
Forms = code_mod(Fun, ErlExprs, Line, File, Module, Vars),
{Module, Binary} = elixir_erl_compiler:noenv_forms(Forms, File, [nowarn_nomatch, no_bool_opt, no_ssa_opt]),
@@ -106,15 +107,9 @@ allows_fast_compilation(_) ->
fast_compile({'__block__', _, Exprs}, E) ->
lists:foldl(fun(Expr, _) -> fast_compile(Expr, E) end, nil, Exprs);
fast_compile({defmodule, Meta, [Mod, [{do, TailBlock}]]}, NoLineE) ->
fast_compile({defmodule, Meta, [Mod, [{do, Block}]]}, NoLineE) ->
E = NoLineE#{line := ?line(Meta)},
Block = {'__block__', Meta, [
{'=', Meta, [{result, Meta, ?MODULE}, TailBlock]},
{{'.', Meta, [elixir_utils, noop]}, Meta, []},
{result, Meta, ?MODULE}
]},
Expanded = case Mod of
{'__aliases__', _, _} ->
case elixir_aliases:expand_or_concat(Mod, E) of
@@ -129,6 +124,13 @@ fast_compile({defmodule, Meta, [Mod, [{do, TailBlock}]]}, NoLineE) ->
ContextModules = [Expanded | ?key(E, context_modules)],
elixir_module:compile(Expanded, Block, [], false, E#{context_modules := ContextModules}).
no_tail_optimize(Meta, Block) ->
{'__block__', Meta, [
{'=', Meta, [{result, Meta, ?MODULE}, Block]},
{{'.', Meta, [elixir_utils, noop]}, Meta, []},
{result, Meta, ?MODULE}
]}.
%% Bootstrapper
bootstrap() ->
+21 -4
View File
@@ -5,25 +5,42 @@
spawn(Fun) ->
CompilerInfo = get(elixir_compiler_info),
CodeDiagnostics =
case get(elixir_code_diagnostics) of
undefined -> undefined;
{_Tail, Log} -> {[], Log}
end,
{_, Ref} =
spawn_monitor(fun() ->
put(elixir_compiler_info, CompilerInfo),
put(elixir_code_diagnostics, CodeDiagnostics),
try Fun() of
Result -> exit({ok, Result})
Result -> exit({ok, Result, get(elixir_code_diagnostics)})
catch
Kind:Reason:Stack ->
exit({Kind, Reason, Stack})
exit({Kind, Reason, Stack, get(elixir_code_diagnostics)})
end
end),
receive
{'DOWN', Ref, process, _, {ok, Result}} ->
{'DOWN', Ref, process, _, {ok, Result, Diagnostics}} ->
copy_diagnostics(Diagnostics),
Result;
{'DOWN', Ref, process, _, {Kind, Reason, Stack}} ->
{'DOWN', Ref, process, _, {Kind, Reason, Stack, Diagnostics}} ->
copy_diagnostics(Diagnostics),
erlang:raise(Kind, Reason, Stack)
end.
copy_diagnostics(undefined) ->
ok;
copy_diagnostics({Head, _}) ->
case get(elixir_code_diagnostics) of
undefined -> ok;
{Tail, Log} -> put(elixir_code_diagnostics, {Head ++ Tail, Log})
end.
forms(Forms, File, Opts) ->
compile(Forms, File, Opts ++ compile:env_compiler_options()).
+8 -10
View File
@@ -508,19 +508,17 @@ beam_location(ModuleAsCharlist) ->
checker_info() ->
case get(elixir_checker_info) of
undefined -> undefined;
_ ->
Log =
case erlang:get(elixir_code_diagnostics) of
{_, false} -> false;
_ -> true
end,
{'Elixir.Module.ParallelChecker':get(), Log}
_ -> 'Elixir.Module.ParallelChecker':get()
end.
spawn_parallel_checker(undefined, _Module, _ModuleMap) ->
nil;
spawn_parallel_checker({CheckerInfo, Log}, Module, ModuleMap) ->
ok;
spawn_parallel_checker(CheckerInfo, Module, ModuleMap) ->
Log =
case erlang:get(elixir_code_diagnostics) of
{_, false} -> false;
_ -> true
end,
'Elixir.Module.ParallelChecker':spawn(CheckerInfo, Module, ModuleMap, Log).
make_module_available(Module, Binary) ->
+36 -1
View File
@@ -90,6 +90,28 @@ defmodule CodeTest do
Code.eval_quoted(quoted, [])
end)
end
test "captures unknown local calls" do
sample = """
defmodule CodeTest.UnknownLocalCall do
def perform do
foo()
end
end
"""
assert {:rescued, [%{message: message}]} =
Code.with_diagnostics(fn ->
try do
quoted = Code.string_to_quoted!(sample, columns: true)
Code.eval_quoted(quoted, [])
rescue
_ -> :rescued
end
end)
assert message =~ "undefined function foo/0"
end
end
describe "eval_string/1,2,3" do
@@ -325,7 +347,12 @@ defmodule CodeTest do
assert env.versioned_vars == %{}
assert_receive {:trace, {:on_module, _, _}, %{module: CodeTest.TracingPruning} = trace_env}
assert trace_env.versioned_vars == %{{:result, Kernel} => 5, {:x, nil} => 1, {:y, nil} => 4}
assert trace_env.versioned_vars == %{
{:result, :elixir_compiler} => 5,
{:x, nil} => 1,
{:y, nil} => 4
}
end
test "with defguard" do
@@ -474,6 +501,14 @@ defmodule CodeTest do
:code.purge(CompileCrossSample)
:code.delete(CompileCrossSample)
end
test "disables tail call optimization at the root" do
try do
Code.compile_string("List.flatten(123)")
rescue
_ -> assert Enum.any?(__STACKTRACE__, &match?({_, :__FILE__, 1, _}, &1))
end
end
end
test "format_string/2 returns empty iodata for empty string" do
+1 -1
View File
@@ -130,7 +130,7 @@ defmodule ExUnit.CaseTemplate do
The second argument passed to `use MyCase` gets forwarded to `using/2` too:
defmodule SomeTestCase do
use MyCase, async: true, import_helpers: true, async: true
use MyCase, async: true, import_helpers: true
test "the truth" do
# truth/0 comes from MyApp.TestHelpers:
+16 -9
View File
@@ -582,9 +582,6 @@ defmodule IEx do
@doc """
Pries into the process environment.
When you start `iex`, IEx will set this function to be the
default `dbg/2` backend unless the `--no-pry` flag is given.
This function is useful for debugging a particular chunk of code
when executed by a particular process. The process becomes
the evaluator of IEx commands and is temporarily changed to
@@ -600,6 +597,11 @@ defmodule IEx do
See also `break!/4` for others ways to pry.
> #### `dbg/0` integration
>
> By calling `iex --dbg pry`, `iex` will set this function
> as the default backend for `dbg/0` calls.
## Examples
Let's suppose you want to investigate what is happening
@@ -928,13 +930,18 @@ defmodule IEx do
mfa
end
:ok = :shell.start_interactive(shell)
case :shell.start_interactive(shell) do
:ok ->
receive do
{^ref, shell} -> shell
after
15_000 ->
IO.puts(:stderr, "Could not start IEx CLI due to reason: :boot_timeout")
System.halt(1)
end
receive do
{^ref, shell} -> shell
after
15_000 ->
IO.puts(:stderr, "Could not start the shell after 15 seconds, aborting...")
{:error, reason} ->
IO.puts(:stderr, "Could not start IEx CLI due to reason: #{inspect(reason)}")
System.halt(1)
end
end
+1 -2
View File
@@ -89,8 +89,7 @@ defmodule IEx.CLI do
spawn_link(fn ->
receive do
{:begin, ^ref, other} ->
{:ok, _} = Application.ensure_all_started(:elixir)
System.wait_until_booted()
:elixir.start_cli()
send(other, {:done, ref})
end
end)
+1
View File
@@ -293,6 +293,7 @@ defmodule IEx.Introspection do
module.module_info(:exports)
end
|> Enum.sort()
|> Enum.dedup()
result =
for {^function, arity} <- exports,
+20 -11
View File
@@ -600,26 +600,29 @@ defmodule Mix do
"""
@doc since: "1.15.0"
def ensure_application!(app) when is_atom(app) do
ensure_application!(app, Mix.State.builtin_apps())
ensure_application!(app, Mix.State.builtin_apps(), [])
:ok
end
defp ensure_application!(app, builtin_apps) do
defp ensure_application!(app, builtin_apps, optional) do
case builtin_apps do
%{^app => path} ->
Code.prepend_path(path, cache: true)
Application.load(app)
optional = List.wrap(Application.spec(app, :optional_applications))
Application.spec(app, :applications)
|> List.wrap()
|> Enum.each(&ensure_application!(&1, builtin_apps))
|> Enum.each(&ensure_application!(&1, builtin_apps, optional))
%{} ->
Mix.raise(
"The application \"#{app}\" could not be found. This may happen if your " <>
"Operating System broke Erlang into multiple packages and may be fixed " <>
"by installing the missing \"erlang-dev\" and \"erlang-#{app}\" packages"
)
unless app in optional do
Mix.raise(
"The application \"#{app}\" could not be found. This may happen if your " <>
"Operating System broke Erlang into multiple packages and may be fixed " <>
"by installing the missing \"erlang-dev\" and \"erlang-#{app}\" packages"
)
end
end
end
@@ -674,6 +677,9 @@ defmodule Mix do
* `:lockfile` (since v1.14.0) - path to a lockfile to be used as a basis of
dependency resolution.
* `:start_applications` (since v1.15.3) - if `true`, ensures that installed app
and its dependencies are started after install (Default: `true`)
## Examples
Installing `:decimal` and `:jason`:
@@ -794,6 +800,7 @@ defmodule Mix do
config_path = expand_path(opts[:config_path], deps, :config_path, "config/config.exs")
system_env = Keyword.get(opts, :system_env, [])
consolidate_protocols? = Keyword.get(opts, :consolidate_protocols, true)
start_applications? = Keyword.get(opts, :start_applications, true)
id =
{deps, config, system_env, consolidate_protocols?}
@@ -893,9 +900,11 @@ defmodule Mix do
end
end)
for %{app: app, opts: opts} <- Mix.Dep.cached(),
Keyword.get(opts, :runtime, true) and Keyword.get(opts, :app, true) do
Application.ensure_all_started(app)
if start_applications? do
for %{app: app, opts: opts} <- Mix.Dep.cached(),
Keyword.get(opts, :runtime, true) and Keyword.get(opts, :app, true) do
Application.ensure_all_started(app)
end
end
Mix.State.put(:installed, id)
+56 -55
View File
@@ -1,7 +1,7 @@
defmodule Mix.Compilers.Elixir do
@moduledoc false
@manifest_vsn 19
@manifest_vsn 20
@checkpoint_vsn 2
import Record
@@ -46,6 +46,11 @@ defmodule Mix.Compilers.Elixir do
{all_modules, all_sources, all_local_exports, old_parents, old_cache_key, old_deps_config} =
parse_manifest(manifest, dest)
# Prepend ourselves early because of __mix_recompile__? checks
# and also that, in case of nothing compiled, we already need
# ourselves available in the path.
Code.prepend_path(dest)
# If modules have been added or removed from the Erlang compiler,
# we need to recompile all references to old and new modules.
stale =
@@ -205,10 +210,6 @@ defmodule Mix.Compilers.Elixir do
Code.purge_compiler_modules()
end
else
# Prepend ourselves, even if we did no work, as we may have defined
# future compilers.
Code.prepend_path(dest)
# We need to return ok if deps_changed? or stale_modules changed,
# even if no code was compiled, because we need to propagate the changed
# status to compile.protocols. This will be the case whenever:
@@ -565,72 +566,72 @@ defmodule Mix.Compilers.Elixir do
Enum.any?(enumerable, &Map.has_key?(map, &1))
end
defp stale_local_deps(local_deps, manifest, stale_modules, modified, old_exports) do
defp stale_local_deps(local_deps, manifest, stale_modules, modified, deps_exports) do
base = Path.basename(manifest)
# The stale modules so far will become both stale_modules and stale_exports,
# as any export from a dependency needs to be recompiled.
stale_modules = Map.from_keys(stale_modules, true)
{stale_modules, stale_exports, new_exports} =
for %{opts: opts} <- local_deps,
manifest = Path.join([opts[:build], ".mix", base]),
Mix.Utils.last_modified(manifest) > modified,
reduce: {stale_modules, stale_modules, []} do
{modules, exports, new_exports} ->
{manifest_modules, manifest_sources} = read_manifest(manifest)
for %{app: app, opts: opts} <- local_deps,
manifest = Path.join([opts[:build], ".mix", base]),
Mix.Utils.last_modified(manifest) > modified,
reduce: {stale_modules, stale_modules, deps_exports} do
{modules, exports, deps_exports} ->
{manifest_modules, manifest_sources} = read_manifest(manifest)
dep_modules =
for module(module: module, timestamp: timestamp) <- manifest_modules,
timestamp > modified,
do: module
dep_modules =
for module(module: module, timestamp: timestamp) <- manifest_modules,
timestamp > modified,
do: module
# If any module has a compile time dependency on a changed module
# within the dependency, they will be recompiled. However, export
# and runtime dependencies won't have recompiled so we need to
# propagate them to the parent app.
{dep_modules, _, _} =
fixpoint_runtime_modules(manifest_sources, Map.from_keys(dep_modules, true))
# If any module has a compile time dependency on a changed module
# within the dependency, they will be recompiled. However, export
# and runtime dependencies won't have recompiled so we need to
# propagate them to the parent app.
{dep_modules, _, _} =
fixpoint_runtime_modules(manifest_sources, Map.from_keys(dep_modules, true))
# Update exports
{exports, new_exports} =
for {module, _} <- dep_modules, reduce: {exports, new_exports} do
{exports, new_exports} ->
export = exports_md5(module, false)
old_exports = Map.get(deps_exports, app, %{})
# If the exports are the same, then the API did not change,
# so we do not mark the export as stale. Note this has to
# be very conservative. If the module is not loaded or if
# the exports were not there, we need to consider it a stale
# export.
exports =
if export && old_exports[module] == export,
do: exports,
else: Map.put(exports, module, true)
# Update exports
{exports, new_exports} =
for {module, _} <- dep_modules, reduce: {exports, []} do
{exports, new_exports} ->
export = exports_md5(module, false)
# Then we store the new export if any
new_exports =
if export,
do: [{module, export} | new_exports],
else: new_exports
# If the exports are the same, then the API did not change,
# so we do not mark the export as stale. Note this has to
# be very conservative. If the module is not loaded or if
# the exports were not there, we need to consider it a stale
# export.
exports =
if export && old_exports[module] == export,
do: exports,
else: Map.put(exports, module, true)
{exports, new_exports}
end
# Then we store the new export if any
new_exports =
if export,
do: [{module, export} | new_exports],
else: new_exports
{Map.merge(modules, dep_modules), exports, new_exports}
end
{exports, new_exports}
end
# Any dependency in old export but not in new export
# was removed so we need to mark them as stale too.
new_exports = Map.new(new_exports)
new_exports = Map.new(new_exports)
removed =
for {module, _} <- old_exports,
not is_map_key(new_exports, module),
do: {module, true},
into: %{}
removed =
for {module, _} <- old_exports,
not is_map_key(new_exports, module),
do: {module, true},
into: %{}
{Map.merge(stale_modules, removed), Map.merge(stale_exports, removed), new_exports}
modules = modules |> Map.merge(dep_modules) |> Map.merge(removed)
exports = Map.merge(exports, removed)
deps_exports = Map.put(deps_exports, app, new_exports)
{modules, exports, deps_exports}
end
end
defp fixpoint_runtime_modules(sources, modules) when modules != %{} do
+2 -2
View File
@@ -67,7 +67,7 @@ defmodule Mix.Release do
@default_apps [kernel: :permanent, stdlib: :permanent, elixir: :permanent, sasl: :permanent]
@safe_modes [:permanent, :temporary, :transient]
@unsafe_modes [:load, :none]
@significant_chunks ~w(Atom AtU8 Attr Code StrT ImpT ExpT FunT LitT Line)c
@additional_chunks ~w(Attr)c
@copy_app_dirs ["priv"]
@doc false
@@ -879,7 +879,7 @@ defmodule Mix.Release do
@spec strip_beam(binary(), keyword()) :: {:ok, binary()} | {:error, :beam_lib, term()}
def strip_beam(binary, options \\ []) when is_list(options) do
chunks_to_keep = options[:keep] |> List.wrap() |> Enum.map(&String.to_charlist/1)
all_chunks = Enum.uniq(@significant_chunks ++ chunks_to_keep)
all_chunks = Enum.uniq(@additional_chunks ++ :beam_lib.significant_chunks() ++ chunks_to_keep)
compress? = Keyword.get(options, :compress, false)
case :beam_lib.chunks(binary, all_chunks, [:allow_missing_chunks]) do
+1 -1
View File
@@ -61,7 +61,7 @@ defmodule Mix.Tasks.Archive.Build do
project = Mix.Project.get()
if project && Keyword.get(opts, :compile, true) do
Mix.Task.run(:compile, args)
Mix.Task.run(:compile, ["--no-protocol-consolidation" | args])
end
source =
-1
View File
@@ -17,7 +17,6 @@ defmodule Mix.Tasks.Deps.Loadpaths do
* `--no-archives-check` - does not check archives
* `--no-compile` - does not compile even if files require compilation
* `--no-deps-check` - does not check or compile deps, only load available ones
* `--no-deps-loading` - does not add deps loadpaths to the code path
* `--no-elixir-version-check` - does not check Elixir version
* `--no-optional-deps` - does not compile or load optional deps
-1
View File
@@ -20,7 +20,6 @@ defmodule Mix.Tasks.Loadpaths do
* `--no-archives-check` - does not check archives
* `--no-compile` - does not compile dependencies, only check and load them
* `--no-deps-check` - does not check dependencies, only load available ones
* `--no-deps-loading` - does not add deps loadpaths to the code path
* `--no-elixir-version-check` - does not check Elixir version
* `--no-optional-deps` - does not compile or load optional deps
+1
View File
@@ -32,6 +32,7 @@ defmodule Mix.Tasks.ArchiveTest do
message = "Generated archive \"archive-0.1.0.ez\" with MIX_ENV=dev"
assert_received {:mix_shell, :info, [^message]}
assert File.regular?(~c"archive-0.1.0.ez")
assert to_charlist(Mix.Project.consolidation_path()) not in :code.get_path()
assert_archive_content_default()
refute has_in_zip_file?(~c"archive-0.1.0.ez", ~c"archive-0.1.0/priv/.dot_file")
@@ -1263,6 +1263,11 @@ defmodule Mix.Tasks.Compile.ElixirTest do
assert_received {:mix_shell, :info, ["Compiled lib/b.ex"]}
assert_received {:mix_shell, :info, ["Compiled lib/c.ex"]}
# Mix recompile should work even if the compile path
# was removed and the module purged
Code.delete_path(Mix.Project.compile_path())
purge([A])
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
assert_received {:mix_shell, :info, ["Compiling 1 file (.ex)"]}
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
+2 -1
View File
@@ -453,7 +453,8 @@ defmodule Mix.UmbrellaTest do
assert_received {:mix_shell, :info, ["Compiled lib/bar.ex"]}
# Recompiles if export dependency is removed
File.rm!("../foo/lib/foo.ex")
File.write!("../foo/lib/foo.ex", "")
ensure_touched("../foo/lib/foo.ex", "_build/dev/lib/bar/.mix/compile.elixir")
Mix.Task.clear()
ExUnit.CaptureIO.capture_io(:stderr, fn ->