mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-02-26 16:05:27 +08:00
Require Elixir 1.14 (#1342)
This commit is contained in:
parent
eac93a47ec
commit
3d5c7c3fad
12 changed files with 52 additions and 128 deletions
2
.github/scripts/app/bootstrap_mac.sh
vendored
2
.github/scripts/app/bootstrap_mac.sh
vendored
|
@ -8,7 +8,7 @@ main() {
|
|||
wxwidgets_ref="v3.1.7"
|
||||
otp_repo="wojtekmach/otp"
|
||||
otp_ref="wm-WX_MACOS_NON_GUI_APP"
|
||||
elixir_vsn="1.13.4"
|
||||
elixir_vsn="1.14.0-rc.0"
|
||||
|
||||
target=$(target)
|
||||
|
||||
|
|
19
.github/workflows/deploy.yaml
vendored
19
.github/workflows/deploy.yaml
vendored
|
@ -4,7 +4,10 @@ on:
|
|||
branches:
|
||||
- main
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
- "v*.*.*"
|
||||
env:
|
||||
otp: "25.0"
|
||||
elixir: "1.14.0-rc.0"
|
||||
jobs:
|
||||
assets:
|
||||
outputs:
|
||||
|
@ -15,24 +18,24 @@ jobs:
|
|||
- name: Install Erlang & Elixir
|
||||
uses: erlef/setup-beam@v1
|
||||
with:
|
||||
otp-version: '24.0'
|
||||
elixir-version: '1.13.4'
|
||||
otp-version: ${{ env.otp }}
|
||||
elixir-version: ${{ env.elixir }}
|
||||
- name: Cache Mix
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
deps
|
||||
_build
|
||||
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
|
||||
key: ${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-${{ hashFiles('**/mix.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-mix-
|
||||
${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-
|
||||
# Note: we need to get Phoenix and LV because package.json points to them directly
|
||||
- name: Install mix dependencies
|
||||
run: mix deps.get
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: "14.x"
|
||||
- name: Cache npm dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
|
@ -59,8 +62,8 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
# The output is set only if there was a commit, otherwise
|
||||
# we pass an empty ref and and the default is used
|
||||
# The output is set only if there was a commit, otherwise
|
||||
# we pass an empty ref and and the default is used
|
||||
ref: ${{ needs.assets.outputs.sha }}
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
|
30
.github/workflows/test.yaml
vendored
30
.github/workflows/test.yaml
vendored
|
@ -4,6 +4,9 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
env:
|
||||
otp: "25.0"
|
||||
elixir: "1.14.0-rc.0"
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -14,21 +17,22 @@ jobs:
|
|||
- name: Install Erlang & Elixir
|
||||
uses: erlef/setup-beam@v1
|
||||
with:
|
||||
otp-version: '24.0'
|
||||
elixir-version: '1.13.4'
|
||||
otp-version: ${{ env.otp }}
|
||||
elixir-version: ${{ env.elixir }}
|
||||
- name: Cache Mix
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
deps
|
||||
_build
|
||||
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
|
||||
key: ${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-${{ hashFiles('**/mix.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-mix-
|
||||
${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-
|
||||
- name: Install mix dependencies
|
||||
run: mix deps.get
|
||||
- name: Check formatting
|
||||
run: mix format --check-formatted
|
||||
# TODO: remove deps.compile on Elixir > 1.14.0-rc.0
|
||||
run: mix do deps.compile, format --check-formatted
|
||||
- name: Check warnings
|
||||
run: mix compile --warnings-as-errors
|
||||
- name: Run tests
|
||||
|
@ -36,7 +40,7 @@ jobs:
|
|||
- name: Install Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: "14.x"
|
||||
- name: Cache npm dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
|
@ -63,11 +67,11 @@ jobs:
|
|||
uses: erlef/setup-beam@v1
|
||||
with:
|
||||
version-type: strict
|
||||
otp-version: '24.2'
|
||||
elixir-version: '1.13.4'
|
||||
otp-version: ${{ env.otp }}
|
||||
elixir-version: ${{ env.elixir }}
|
||||
- name: Start epmd
|
||||
run: cmd /c "START /b epmd"
|
||||
working-directory: ${{ env.INSTALL_DIR_FOR_OTP }}/erts-12.2/bin
|
||||
working-directory: ${{ env.INSTALL_DIR_FOR_OTP }}/erts-13.0/bin
|
||||
# Add tar that supports symlinks, see https://github.com/actions/virtual-environments/issues/4679
|
||||
- name: Add tar.exe
|
||||
run: |
|
||||
|
@ -78,15 +82,11 @@ jobs:
|
|||
path: |
|
||||
deps
|
||||
_build
|
||||
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
|
||||
key: ${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-${{ hashFiles('**/mix.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-mix-
|
||||
${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-
|
||||
- name: Install mix dependencies
|
||||
run: mix deps.get
|
||||
- name: Check formatting
|
||||
run: mix format --check-formatted
|
||||
- name: Check warnings
|
||||
run: mix compile --warnings-as-errors
|
||||
- name: Run tests
|
||||
run: mix test
|
||||
- name: Build the app
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Stage 1
|
||||
# Builds the Livebook release
|
||||
FROM hexpm/elixir:1.13.4-erlang-24.3.4.2-debian-bullseye-20210902-slim AS build
|
||||
FROM hexpm/elixir:1.14.0-rc.0-erlang-24.3.4.2-debian-bullseye-20210902-slim AS build
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
|
@ -38,7 +38,7 @@ RUN mix do compile, release livebook
|
|||
# We use the same base image, because we need Erlang, Elixir and Mix
|
||||
# during runtime to spawn the Livebook standalone runtimes.
|
||||
# Consequently the release doesn't include ERTS as we have it anyway.
|
||||
FROM hexpm/elixir:1.13.4-erlang-24.3.4.2-debian-bullseye-20210902-slim
|
||||
FROM hexpm/elixir:1.14.0-rc.0-erlang-24.3.4.2-debian-bullseye-20210902-slim
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
|
|
|
@ -480,7 +480,7 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
defp valid_alias_rest?(rest), do: valid_alias_piece?(rest)
|
||||
|
||||
defp usable_as_unquoted_module?(mod) do
|
||||
macro_classify_atom(mod) in [:identifier, :unquoted]
|
||||
Macro.classify_atom(mod) in [:identifier, :unquoted]
|
||||
end
|
||||
|
||||
defp get_matching_modules(hint, ctx) do
|
||||
|
@ -641,70 +641,4 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
documentation: {"text/markdown", info.doc}
|
||||
}
|
||||
end
|
||||
|
||||
# ---
|
||||
|
||||
# TODO: use Macro.classify_atom/1 on Elixir 1.14
|
||||
|
||||
def macro_classify_atom(atom) do
|
||||
case macro_inner_classify(atom) do
|
||||
:alias -> :alias
|
||||
:identifier -> :identifier
|
||||
type when type in [:unquoted_operator, :not_callable] -> :unquoted
|
||||
_ -> :quoted
|
||||
end
|
||||
end
|
||||
|
||||
defp macro_inner_classify(atom) when is_atom(atom) do
|
||||
cond do
|
||||
atom in [:%, :%{}, :{}, :<<>>, :..., :.., :., :"..//", :->] ->
|
||||
:not_callable
|
||||
|
||||
atom in [:"::"] ->
|
||||
:quoted_operator
|
||||
|
||||
Macro.operator?(atom, 1) or Macro.operator?(atom, 2) ->
|
||||
:unquoted_operator
|
||||
|
||||
true ->
|
||||
charlist = Atom.to_charlist(atom)
|
||||
|
||||
if macro_valid_alias?(charlist) do
|
||||
:alias
|
||||
else
|
||||
case :elixir_config.identifier_tokenizer().tokenize(charlist) do
|
||||
{kind, _acc, [], _, _, special} ->
|
||||
if kind == :identifier and not :lists.member(?@, special) do
|
||||
:identifier
|
||||
else
|
||||
:not_callable
|
||||
end
|
||||
|
||||
_ ->
|
||||
:other
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp macro_valid_alias?('Elixir' ++ rest), do: macro_valid_alias_piece?(rest)
|
||||
defp macro_valid_alias?(_other), do: false
|
||||
|
||||
defp macro_valid_alias_piece?([?., char | rest]) when char >= ?A and char <= ?Z,
|
||||
do: macro_valid_alias_piece?(macro_trim_leading_while_valid_identifier(rest))
|
||||
|
||||
defp macro_valid_alias_piece?([]), do: true
|
||||
defp macro_valid_alias_piece?(_other), do: false
|
||||
|
||||
defp macro_trim_leading_while_valid_identifier([char | rest])
|
||||
when char >= ?a and char <= ?z
|
||||
when char >= ?A and char <= ?Z
|
||||
when char >= ?0 and char <= ?9
|
||||
when char == ?_ do
|
||||
macro_trim_leading_while_valid_identifier(rest)
|
||||
end
|
||||
|
||||
defp macro_trim_leading_while_valid_identifier(other) do
|
||||
other
|
||||
end
|
||||
end
|
||||
|
|
|
@ -566,8 +566,7 @@ defmodule Livebook.Runtime.ErlDist.RuntimeServer do
|
|||
{:ok, pid} =
|
||||
Task.Supervisor.start_child(state.task_supervisor, fn ->
|
||||
binding = []
|
||||
# TODO: Use Code.env_for_eval and eval_quoted_with_env on Elixir v1.14+
|
||||
env = :elixir.env_for_eval([])
|
||||
env = Code.env_for_eval([])
|
||||
scan_and_ack.(binding, env)
|
||||
end)
|
||||
|
||||
|
|
|
@ -182,8 +182,7 @@ defmodule Livebook.Runtime.Evaluator do
|
|||
"""
|
||||
@spec intellisense_context() :: Livebook.Intellisense.intellisense_context()
|
||||
def intellisense_context() do
|
||||
# TODO: Use Code.env_for_eval and eval_quoted_with_env on Elixir v1.14+
|
||||
env = :elixir.env_for_eval([])
|
||||
env = Code.env_for_eval([])
|
||||
map_binding = fn fun -> fun.([]) end
|
||||
%{env: env, map_binding: map_binding}
|
||||
end
|
||||
|
@ -304,8 +303,7 @@ defmodule Livebook.Runtime.Evaluator do
|
|||
end
|
||||
|
||||
defp initial_context() do
|
||||
# TODO: Use Code.env_for_eval and eval_quoted_with_env on Elixir v1.14+
|
||||
env = :elixir.env_for_eval([])
|
||||
env = Code.env_for_eval([])
|
||||
%{binding: [], env: env, id: random_id()}
|
||||
end
|
||||
|
||||
|
@ -429,11 +427,7 @@ defmodule Livebook.Runtime.Evaluator do
|
|||
defp eval(code, binding, env) do
|
||||
try do
|
||||
quoted = Code.string_to_quoted!(code, file: env.file)
|
||||
# TODO: Use Code.eval_quoted_with_env/3 on Elixir v1.14
|
||||
{value, binding, env} = :elixir.eval_quoted(quoted, binding, env)
|
||||
# TODO: Remove this line on Elixir v1.14 as binding propagates to env correctly
|
||||
{_, binding, env} = :elixir.eval_forms(:ok, binding, env)
|
||||
|
||||
{value, binding, env} = Code.eval_quoted_with_env(quoted, binding, env)
|
||||
{:ok, value, binding, env}
|
||||
catch
|
||||
kind, error ->
|
||||
|
@ -475,7 +469,7 @@ defmodule Livebook.Runtime.Evaluator do
|
|||
|
||||
# Adapted from https://github.com/elixir-lang/elixir/blob/1c1654c88adfdbef38ff07fc30f6fbd34a542c07/lib/iex/lib/iex/evaluator.ex#L355-L372
|
||||
# TODO: Remove else branch once we depend on the versions below
|
||||
if System.otp_release() >= "25" and Version.match?(System.version(), "~> 1.14-dev") do
|
||||
if System.otp_release() >= "25" do
|
||||
defp prune_stacktrace(stack) do
|
||||
stack
|
||||
|> Enum.reverse()
|
||||
|
|
|
@ -466,7 +466,7 @@ defmodule Livebook.Utils do
|
|||
base_url
|
||||
|> URI.parse()
|
||||
|> Map.replace!(:path, "/import")
|
||||
|> append_query("url=#{URI.encode_www_form(url)}")
|
||||
|> URI.append_query("url=#{URI.encode_www_form(url)}")
|
||||
|> URI.to_string()
|
||||
end
|
||||
|
||||
|
@ -484,19 +484,10 @@ defmodule Livebook.Utils do
|
|||
base_url
|
||||
|> URI.parse()
|
||||
|> Map.replace!(:path, "/open")
|
||||
|> append_query("path=#{URI.encode_www_form(path)}")
|
||||
|> URI.append_query("path=#{URI.encode_www_form(path)}")
|
||||
|> URI.to_string()
|
||||
end
|
||||
|
||||
# TODO: On Elixir v1.14, use URI.append_query/2
|
||||
def append_query(%URI{query: query} = uri, query_to_add) when query in [nil, ""] do
|
||||
%{uri | query: query_to_add}
|
||||
end
|
||||
|
||||
def append_query(%URI{} = uri, query) do
|
||||
%{uri | query: uri.query <> "&" <> query}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Formats the given number of bytes into a human-friendly text.
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ defmodule LivebookCLI.Server do
|
|||
defp update_query(url, params) do
|
||||
url
|
||||
|> URI.parse()
|
||||
|> Livebook.Utils.append_query(URI.encode_query(params))
|
||||
|> URI.append_query(URI.encode_query(params))
|
||||
|> URI.to_string()
|
||||
end
|
||||
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -1,7 +1,7 @@
|
|||
defmodule Livebook.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
@elixir_requirement "~> 1.13"
|
||||
@elixir_requirement "~> 1.14.0-rc.0"
|
||||
@version "0.6.3"
|
||||
@description "Interactive and collaborative code notebooks - made with Phoenix LiveView"
|
||||
|
||||
|
|
|
@ -9,11 +9,8 @@ defmodule Livebook.IntellisenseTest do
|
|||
quote do
|
||||
block = unquote(Macro.escape(block))
|
||||
binding = []
|
||||
# TODO: Use Code.env_for_eval and eval_quoted_with_env on Elixir v1.14+
|
||||
env = :elixir.env_for_eval([])
|
||||
{_, binding, env} = :elixir.eval_quoted(block, binding, env)
|
||||
# TODO: Remove this line on Elixir v1.14 as binding propagates to env correctly
|
||||
{_, binding, env} = :elixir.eval_forms(:ok, binding, env)
|
||||
env = Code.env_for_eval([])
|
||||
{value, binding, env} = Code.eval_quoted_with_env(block, binding, env)
|
||||
|
||||
%{
|
||||
env: env,
|
||||
|
@ -162,7 +159,7 @@ defmodule Livebook.IntellisenseTest do
|
|||
label: "Enum",
|
||||
kind: :module,
|
||||
detail: "module",
|
||||
documentation: "Provides a set of algorithms to work with enumerables.",
|
||||
documentation: "Functions for working with collections (known as enumerables).",
|
||||
insert_text: "Enum"
|
||||
},
|
||||
%{
|
||||
|
|
|
@ -97,8 +97,11 @@ defmodule Livebook.Runtime.EvaluatorTest do
|
|||
Evaluator.evaluate_code(evaluator, code, :code_1, nil, file: "file.ex")
|
||||
|
||||
assert_receive {:runtime_evaluation_response, :code_1,
|
||||
{:error, :error, :function_clause, [{List, :first, _arity, _location}]},
|
||||
metadata()}
|
||||
{:error, :error, :function_clause,
|
||||
[
|
||||
{List, :first, _arity, _location1},
|
||||
{:elixir_eval, :__FILE__, 1, _location2}
|
||||
]}, metadata()}
|
||||
end
|
||||
|
||||
test "returns additional metadata when there is a syntax error", %{evaluator: evaluator} do
|
||||
|
@ -138,7 +141,9 @@ defmodule Livebook.Runtime.EvaluatorTest do
|
|||
|
||||
Evaluator.evaluate_code(evaluator, code, :code_1, nil, file: "file.ex")
|
||||
|
||||
expected_stacktrace = [{Code, :validated_eval_string, 3, [file: 'lib/code.ex', line: 404]}]
|
||||
expected_stacktrace = [
|
||||
{:elixir_eval, :__FILE__, 1, [file: 'file.ex', line: 1]}
|
||||
]
|
||||
|
||||
assert_receive {:runtime_evaluation_response, :code_1,
|
||||
{:error, :error, %CompileError{}, ^expected_stacktrace}, %{code_error: nil}}
|
||||
|
@ -169,7 +174,8 @@ defmodule Livebook.Runtime.EvaluatorTest do
|
|||
|
||||
expected_stacktrace = [
|
||||
{Livebook.EvaluatorTest.Stacktrace.Math, :bad_math, 0, [file: 'nofile', line: 3]},
|
||||
{Livebook.EvaluatorTest.Stacktrace.Cat, :meow, 0, [file: 'nofile', line: 10]}
|
||||
{Livebook.EvaluatorTest.Stacktrace.Cat, :meow, 0, [file: 'nofile', line: 10]},
|
||||
{:elixir_eval, :__FILE__, 1, [file: 'nofile', line: 15]}
|
||||
]
|
||||
|
||||
# Note: evaluating module definitions is relatively slow, so we use a higher wait timeout.
|
||||
|
|
Loading…
Reference in a new issue