Compare commits

...
18 Commits
Author SHA1 Message Date
José Valim 9fd85b06dc Release v1.15.0 2023-06-19 13:37:46 +02:00
José Valim ec81110b3e Improve Logger docs 2023-06-18 17:12:23 +02:00
José Valim 094a76d514 Update release instructions 2023-06-18 10:44:40 +02:00
sabiwara 7d737bc5ec Fix slicing MapSet with stepped range (#12667) 2023-06-14 12:04:51 +02:00
José Valim 3eb074282a Return the value on each step of dbg+pry+pipe integration, closes #12657 2023-06-13 17:11:34 +02:00
José Valim b8732bd248 Improve error message for invalid module attribute usage, closes #12656 2023-06-13 16:54:33 +02:00
José Valim 2252a8ff55 Fix erts handling when loading apps 2023-06-13 15:29:17 +02:00
José Valim 9a9cf419a1 Release v1.15.0-rc.2 2023-06-12 15:10:17 +02:00
Wojtek Mach 0f92512030 Bump Ubuntu version for builds.hex.pm.yml (#12652)
We need nsis 3.08 (not 3.06)
2023-06-12 13:05:11 +02:00
nico piderman e0806f9d6c Mark test cases as invalid when an exit occurs during setup_all (#12651) 2023-06-12 12:54:05 +02:00
Wojtek Mach 5db9d55926 Add offline Windows installer to releases (#12640) 2023-06-12 12:54:05 +02:00
José Valim 3cb3d41368 Keep capture operator on container cursor to quoted 2023-06-12 10:44:16 +02:00
José Valim a3a081c949 Keep erts when pruning load paths (#12642) 2023-06-11 11:27:07 +02:00
José Valim 207350fb44 Improve heredoc warning 2023-06-08 16:15:03 +02:00
José Valim 6f7a68c9e3 Support mix xref graph at umbrella roots, closes #12629 2023-06-07 14:13:11 +02:00
José Valim 0936fb45d5 Mark functions as generated in Docs chunk 2023-06-07 13:14:17 +02:00
José Valim bccfca4ffe Purge Hex before running Mix tests 2023-06-03 20:59:52 +02:00
José Valim 417255fe1b Branch out v1.15 2023-06-03 20:24:12 +02:00
35 changed files with 523 additions and 143 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ jobs:
- otp: 26
otp_version: '26.0'
build_docs: build_docs
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
+5 -3
View File
@@ -15,7 +15,7 @@ permissions:
jobs:
create_draft_release:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
@@ -40,7 +40,7 @@ jobs:
- otp: 26
otp_version: '26.0'
build_docs: build_docs
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
@@ -56,7 +56,9 @@ jobs:
run: |
gh release upload --clobber "${{ github.ref_name }}" \
elixir-otp-${{ matrix.otp }}.zip \
elixir-otp-${{ matrix.otp }}.zip.sha{1,256}sum
elixir-otp-${{ matrix.otp }}.zip.sha{1,256}sum \
elixir-otp-${{ matrix.otp }}.exe \
elixir-otp-${{ matrix.otp }}.exe.sha{1,256}sum
- name: Upload Docs to GitHub
if: ${{ matrix.build_docs }}
env:
@@ -22,6 +22,20 @@ runs:
shasum -a 1 elixir-otp-${{ inputs.otp }}.zip > elixir-otp-${{ inputs.otp }}.zip.sha1sum
shasum -a 256 elixir-otp-${{ inputs.otp }}.zip > elixir-otp-${{ inputs.otp }}.zip.sha256sum
echo "$PWD/bin" >> $GITHUB_PATH
- name: Install NSIS
shell: bash
run: |
sudo apt update
sudo apt install -y nsis
- name: Build Elixir Windows Installer
shell: bash
run: |
export OTP_VERSION=${{ inputs.otp_version }}
export ELIXIR_ZIP=$PWD/elixir-otp-${{ inputs.otp }}.zip
(cd lib/elixir/scripts/windows_installer && ./build.sh)
mv lib/elixir/scripts/windows_installer/tmp/elixir-otp-${{ inputs.otp }}.exe .
shasum -a 1 elixir-otp-${{ inputs.otp }}.exe > elixir-otp-${{ inputs.otp }}.exe.sha1sum
shasum -a 256 elixir-otp-${{ inputs.otp }}.exe > elixir-otp-${{ inputs.otp }}.exe.sha256sum
- name: Get latest stable ExDoc version
if: ${{ inputs.build_docs }}
shell: bash
+19 -50
View File
@@ -68,7 +68,7 @@ In Elixir v1.15, the new reports will look like:
error: undefined function foo/0 (there is no such import)
my_file.exs:1
** (CompileError) nofile: cannot compile file (errors have been logged)
** (CompileError) my_file.exs: cannot compile file (errors have been logged)
A new function, called `Code.with_diagnostics/2`, has been added so this
information can be leveraged by editors, allowing them to point to several
@@ -100,61 +100,16 @@ config :logger, :default_formatter,
format: "$time $message $metadata"
```
If you use `Logger.Backends.Console` or other backends, they are
still fully supported and functional. If you implement your own
backends, you want to consider migrating to
If you use `Logger.Backends.Console` with a custom device or other
backends, they are still fully supported and functional. If you
implement your own backends, you want to consider migrating to
[`:logger_backends`](https://github.com/elixir-lang/logger_backends)
in the long term.
See the new `Logger` documentation for more information on the
new features and on compatibility.
## v1.15.0-rc.1 (2022-05-29)
### 1. Enhancements
#### Elixir
* [File] Support distributed `File.Stream`
* [Module] Add `Module.get_last_attribute/3`
* [Task] Reduce footprint of tasks by avoiding unecessary work during spawning
#### ExUnit
* [ExUnit.Case] Add `ExUnit.Case.get_last_registered_test/1`
### 2. Bug fixes
#### Elixir
* [Code] Ensure `:on_undefined_variable` option works as advertised (regression)
* [Code] Format paths in `Code.with_diagnostic/2` as relative paths (regression)
* [Kernel] Raise when macros are given to dialyzer
* [Kernel] Support bitstring specifiers as map keys in pattern (regression)
* [Module] Ensure that `Module.get_attribute/3` returns `nil` and not the given default value when an attribute has been explicitly set as `nil`
* [Task] Do not double log Task failure reports
#### ExUnit
* [ExUnit.CaptureLog] Allow capturing deprecated log level (regression)
* [ExUnit.DocTest] Ensure proper line is returned when failing to parse doctest results
#### IEx
* [IEx] Fix IO operations not returning when booting IEx (regression)
#### Mix
* [mix deps] Ensure dependencies with `included_applications` can be loaded (regression)
* [mix format] Ensure proper formatter options are returned for files (regression)
### 3. Soft deprecations
#### Elixir
* [Kernel] Require pin variable when accessing variable inside binary size in match
## v1.15.0-rc.0 (2022-05-22)
## v1.15.0 (2023-06-19)
### 1. Enhancements
@@ -175,6 +130,7 @@ new features and on compatibility.
* [Date] Add `Date.before?/2` and `Date.after?/2`
* [DateTime] Add `DateTime.before?/2` and `DateTime.after?/2`
* [DateTime] Support precision in `DateTime.utc_now/2`
* [File] Support distributed `File.Stream`
* [Inspect] `Inspect` now renders `'charlists'` as `~c"charlists"` by default
* [Kernel] Break down `case` and `cond` inside `dbg/2`
* [Kernel] Add `t:nonempty_binary/0` and `t:nonempty_bitstring/0`
@@ -195,6 +151,8 @@ new features and on compatibility.
* [NaiveDateTime] Add `NaiveDateTime.beginning_of_day/1` and `NaiveDateTime.end_of_day/1`
* [NaiveDateTime] Add `NaiveDateTime.before?/2` and `NaiveDateTime.after?/2`
* [NaiveDateTime] Support precision in `NaiveDateTime.utc_now/2`
* [Module] Mark functions as generated in "Docs" chunk
* [Module] Add `Module.get_last_attribute/3`
* [OptionParser] Support `:return_separator` option
* [Process] Add `Process.alias/0,1` and `Process.unalias/1`
* [Range] Add `Range.split/2`
@@ -204,6 +162,7 @@ new features and on compatibility.
* [System] Support `:lines` in `System.cmd/3` to capture output line by line
* [Task] Remove head of line blocking on `Task.yield_many/2`
* [Task] Enable selective receive optimizations in Erlang/OTP 26+
* [Task] Reduce tasks footprint by avoiding unecessary work during spawning
* [Task.Supervisor] Do not copy args on temporary `Task.Supervisor.start_child/2`
* [Time] Add `Time.before?/2` and `Time.after?/2`
* [URI] Add `URI.append_path/2`
@@ -212,7 +171,9 @@ new features and on compatibility.
* [ExUnit] Add more color configuration to ExUnit CLI formatter
* [ExUnit.Callbacks] Accept `{module, function}` tuples in ExUnit `setup` callbacks
* [ExUnit.Case] Add `ExUnit.Case.get_last_registered_test/1`
* [ExUnit.Doctest] Add `ExUnit.DocTest.doctest_file/2`
* [ExUnit.Doctest] Include `doctest_data` in doctest tags
* [ExUnit.Formatter] When comparing two anonymous functions, defined at the same place but capturing a different environment, we will now also diff the environments
#### IEx
@@ -267,16 +228,22 @@ new features and on compatibility.
* [Kernel] Expand macros on the left side of -> in `try/rescue`
* [Kernel] Raise on misplaced `...` inside typespecs
* [Kernel] Do not import `behaviour_info` and `module_info` functions from Erlang modules
* [Kernel] Raise when macros are given to dialyzer
* [Kernel.ParallelCompiler] Make sure compiler doesn't crash when there are stray messages in the inbox
* [Kernel.ParallelCompiler] Track compile and runtime warnings separately
* [Module] Ensure that `Module.get_attribute/3` returns `nil` and not the given default value when an attribute has been explicitly set as `nil`
* [System] Fix race condition when a script would terminate before `System.stop/1` executes
* [Task] Do not double log Task failure reports
* [URI] Make sure `URI.merge/2` works accordingly with relative paths
#### ExUnit
* [ExUnit] Fix crash when `@tag capture_log: true` was set to true and the Logger application was shut down in the middle of the test
* [ExUnit] Do not merge context as tags inside the runner to reduce memory usage when emitting events to formatters
* [ExUnit] Mark test cases as invalid when an exit occurs during `setup_all`
* [ExUnit] Do not expand or collect vars from quote in ExUnit assertions
* [ExUnit.DocTest] Ensure proper line is returned when failing to parse doctest results
* [ExUnit.Doctest] Fix line information when a doctest with multiple assertions fails
#### IEx
@@ -288,6 +255,7 @@ new features and on compatibility.
* [mix compile] Include `cwd` in compiler cache key
* [mix release] Fix Windows service when invoking `erlsrv.exe` in path with spaces
* [mix xref] Raise early if `mix xref` is used at the umbrella root
### 3. Soft deprecations (no warnings emitted)
@@ -295,6 +263,7 @@ new features and on compatibility.
* [File] `File.cp/3` and `File.cp_r/3` with a function as third argument
is deprecated in favor of a keyword list
* [Kernel] Require pin variable when accessing variable inside binary size in match
* [Kernel.ParallelCompiler] Require the `:return_diagnostics` option to be
set to true when compiling or requiring code
+1 -1
View File
@@ -2,7 +2,7 @@ PREFIX ?= /usr/local
TEST_FILES ?= "*_test.exs"
SHARE_PREFIX ?= $(PREFIX)/share
MAN_PREFIX ?= $(SHARE_PREFIX)/man
#CANONICAL := MAJOR.MINOR/
CANONICAL := 1.15/
CANONICAL ?= main/
DOCS_FORMAT ?= html
ELIXIRC := bin/elixirc --ignore-module-conflict $(ELIXIRC_OPTS)
+1 -1
View File
@@ -14,7 +14,7 @@
6. Copy the relevant bits from /CHANGELOG.md to the GitHub release and publish it
7. Add the release to `elixir.csv` with the minimum supported OTP version (all releases), update `erlang.csv` to the latest supported OTP version, and `_data/elixir-versions.yml` (except for RCs) files in `elixir-lang/elixir-lang.github.com`
7. Update `_data/elixir-versions.yml` (except for RCs) in `elixir-lang/elixir-lang.github.com`
## Creating a new vMAJOR.MINOR branch (after first rc)
+2 -3
View File
@@ -6,12 +6,11 @@ Elixir applies bug fixes only to the latest minor branch. Security patches are a
Elixir version | Support
:------------- | :-----------------------------
1.15 | Development
1.14 | Bug fixes and security patches
1.15 | Bug fixes and security patches
1.14 | Security patches only
1.13 | Security patches only
1.12 | Security patches only
1.11 | Security patches only
1.10 | Security patches only
## Announcements
+1 -1
View File
@@ -1 +1 @@
1.15.0-rc.1
1.15.0
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/sh
set -e
ELIXIR_VERSION=1.15.0-rc.1
ELIXIR_VERSION=1.15.0
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.0-rc.1
set ELIXIR_VERSION=1.15.0
setlocal enabledelayedexpansion
if ""%1""=="""" if ""%2""=="""" goto documentation
-4
View File
@@ -3,10 +3,6 @@ defmodule Code.Fragment do
This module provides conveniences for analyzing fragments of
textual code and extract available information whenever possible.
Most of the functions in this module provide a best-effort
and may not be accurate under all circumstances. Read each
documentation for more information.
This module should be considered experimental.
"""
+8 -6
View File
@@ -3009,13 +3009,16 @@ defmodule Enum do
if first < count and amount > 0 do
amount = Kernel.min(amount, count - first)
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
amount = amount_with_step(amount, step)
fun.(first, amount, step)
else
[]
end
end
defp amount_with_step(amount, 1), do: amount
defp amount_with_step(amount, step), do: div(amount - 1, step) + 1
@doc """
Returns a subset list of the given `enumerable`, from `start_index` (zero-based)
with `amount` number of elements if available.
@@ -4440,7 +4443,7 @@ defmodule Enum do
if start >= 0 do
amount = Kernel.min(amount, count - start)
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
amount = amount_with_step(amount, step)
fun.(start, amount, step)
else
[]
@@ -4448,7 +4451,7 @@ defmodule Enum do
end
defp slice_forward(list, start, amount, step) when is_list(list) do
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
amount = amount_with_step(amount, step)
slice_list(list, start, amount, step)
end
@@ -4458,7 +4461,7 @@ defmodule Enum do
[]
{:ok, count, fun} when is_function(fun, 1) ->
amount = Kernel.min(amount, count - start)
amount = Kernel.min(amount, count - start) |> amount_with_step(step)
enumerable |> fun.() |> slice_exact(start, amount, step, count)
# TODO: Deprecate me in Elixir v1.18.
@@ -4473,8 +4476,7 @@ defmodule Enum do
end
{:ok, count, fun} when is_function(fun, 3) ->
amount = Kernel.min(amount, count - start)
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
amount = Kernel.min(amount, count - start) |> amount_with_step(step)
fun.(start, amount, step)
{:error, module} ->
+4 -2
View File
@@ -3555,10 +3555,12 @@ defmodule Kernel do
not bootstrapped?(Macro) ->
nil
not function? and __CALLER__.context == :match ->
not function? and (__CALLER__.context == :match or __CALLER__.context == :guard) ->
raise ArgumentError,
"""
invalid write attribute syntax. If you want to define an attribute, don't do this:
invalid usage of module attributes. Module attributes cannot be used inside \
pattern matching (and guards) outside of a function. If you are trying to \
define an attribute, do not do this:
@foo = :value
@@ -8,12 +8,11 @@ Elixir applies bug fixes only to the latest minor branch. Security patches are a
Elixir version | Support
:------------- | :-----------------------------
1.15 | Development
1.14 | Bug fixes and security patches
1.15 | Bug fixes and security patches
1.14 | Security patches only
1.13 | Security patches only
1.12 | Security patches only
1.11 | Security patches only
1.10 | Security patches only
New releases are announced in the read-only [announcements mailing list](https://groups.google.com/group/elixir-lang-ann). All security releases [will be tagged with `[security]`](https://groups.google.com/forum/#!searchin/elixir-lang-ann/%5Bsecurity%5D%7Csort:date).
@@ -0,0 +1 @@
tmp/
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
# Usage:
#
# With Elixir archive:
#
# ELIXIR_ZIP=Precompiled.zip OTP_VERSION=25.3.2.2 ./build.sh
#
# With Elixir version:
#
# ELIXIR_VERSION=1.14.5 OTP_VERSION=25.3.2.2 ./build.sh
set -euo pipefail
OTP_VERSION="${OTP_VERSION:-26.0}"
otp_release=`echo "${OTP_VERSION}" | cut -d. -f1`
mkdir -p tmp
ELIXIR_VERSION="${ELIXIR_VERSION:-}"
if [ -n "${ELIXIR_VERSION}" ]; then
ELIXIR_ZIP="tmp/elixir-${ELIXIR_VERSION}-otp-${otp_release}.zip"
if [ ! -f "${ELIXIR_ZIP}" ]; then
url="https://github.com/elixir-lang/elixir/releases/download/v${ELIXIR_VERSION}/elixir-otp-${otp_release}.zip"
echo "downloading ${url}"
curl --fail -L -o "${ELIXIR_ZIP}" "${url}"
fi
basename=elixir-${ELIXIR_VERSION}-otp-${otp_release}
else
basename=elixir-otp-${otp_release}
fi
if [ ! -d "tmp/${basename}" ]; then
unzip -d "tmp/${basename}" "${ELIXIR_ZIP}"
fi
# brew install makensis
# apt install -y nsis
# choco install -y nsis
export PATH="/c/Program Files (x86)/NSIS:${PATH}"
makensis \
-X"OutFile tmp\\${basename}.exe" \
-DOTP_VERSION=${OTP_VERSION} \
-DOTP_RELEASE="${otp_release}" \
-DELIXIR_DIR=tmp\\${basename} \
installer.nsi
echo "Installer path: tmp/${basename}.exe"
@@ -0,0 +1,209 @@
!include "MUI2.nsh"
!include "StrFunc.nsh"
${Using:StrFunc} StrStr
${Using:StrFunc} UnStrStr
${Using:StrFunc} UnStrRep
Name "Elixir"
ManifestDPIAware true
Unicode True
InstallDir "$PROGRAMFILES64\Elixir"
!define MUI_ICON "assets\drop.ico"
; Install Page: Install Erlang/OTP
Page custom CheckOTPPageShow CheckOTPPageLeave
var Dialog
var DownloadOTPLink
var InstalledERTSVersion
var InstalledOTPRelease
var OTPPath
Function CheckOTPPageShow
!insertmacro MUI_HEADER_TEXT "Checking Erlang/OTP" ""
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
EnumRegKey $0 HKLM "SOFTWARE\WOW6432NODE\Ericsson\Erlang" 0
ReadRegStr $1 HKLM "SOFTWARE\WOW6432NODE\Ericsson\Erlang\$0" ""
StrCpy $InstalledERTSVersion $0
StrCpy $OTPPath $1
${If} $1 == ""
${NSD_CreateLabel} 0 0 100% 20u "Couldn't find existing Erlang/OTP installation. Click the link below to download and install it before proceeding."
${NSD_CreateLink} 0 25u 100% 20u "Download Erlang/OTP ${OTP_RELEASE}"
Pop $DownloadOTPLink
${NSD_OnClick} $DownloadOTPLink OpenOTPDownloads
${Else}
nsExec::ExecToStack `$OTPPath\bin\erl.exe -noinput -eval "\
io:put_chars(erlang:system_info(otp_release)),\
halt()."`
Pop $0
Pop $1
${If} $0 == 0
StrCpy $InstalledOTPRelease $1
${If} $InstalledOTPRelease == ${OTP_RELEASE}
${NSD_CreateLabel} 0 0 100% 20u "Found existing Erlang/OTP $InstalledOTPRelease installation at $OTPPath. Please proceed."
${ElseIf} $2 < ${OTP_RELEASE}
${NSD_CreateLabel} 0 0 100% 30u "Found existing Erlang/OTP $InstalledOTPRelease installation at $OTPPath but this Elixir installer was precompiled for Erlang/OTP ${OTP_RELEASE}. \
We recommend checking if there is an Elixir version precompiled for Erlang/OTP $InstalledOTPRelease. Otherwise, proceed."
${Else}
SetErrorlevel 5
MessageBox MB_ICONSTOP "Found existing Erlang/OTP $InstalledOTPRelease installation at $OTPPath but this Elixir version was precompiled for Erlang/OTP ${OTP_RELEASE}. \
Please upgrade your Erlang/OTP version or choose an Elixir installer matching your Erlang/OTP version"
Quit
${EndIf}
${Else}
SetErrorlevel 5
MessageBox MB_ICONSTOP "Found existing Erlang/OTP installation at $OTPPath but checking it exited with $0: $1"
Quit
${EndIf}
${EndIf}
nsDialogs::Show
FunctionEnd
Function OpenOTPDownloads
ExecShell "open" "https://www.erlang.org/downloads/${OTP_RELEASE}"
FunctionEnd
Function CheckOTPPageLeave
FunctionEnd
; Install Page: Files
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
; Install Page: Finish
Page custom FinishPageShow FinishPageLeave
var AddOTPToPathCheckbox
var AddElixirToPathCheckbox
Function FinishPageShow
!insertmacro MUI_HEADER_TEXT "Finish Setup" ""
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateCheckbox} 0 0 195u 10u "&Add $INSTDIR\bin to %PATH%"
Pop $AddElixirToPathCheckbox
SendMessage $AddElixirToPathCheckbox ${BM_SETCHECK} ${BST_CHECKED} 0
EnumRegKey $0 HKLM "SOFTWARE\WOW6432NODE\Ericsson\Erlang" 0
ReadRegStr $0 HKLM "SOFTWARE\WOW6432NODE\Ericsson\Erlang\$0" ""
StrCpy $OTPPath $0
${If} $0 != ""
${NSD_CreateCheckbox} 0 20u 195u 10u "&Add $0\bin to %PATH%"
Pop $AddOTPToPathCheckbox
SendMessage $AddOTPToPathCheckbox ${BM_SETCHECK} ${BST_CHECKED} 0
${EndIf}
nsDialogs::Show
FunctionEnd
Function FinishPageLeave
${NSD_GetState} $AddOTPToPathCheckbox $0
${If} $0 <> ${BST_UNCHECKED}
ReadRegStr $0 HKCU "Environment" "Path"
${StrStr} $1 "$0" "$OTPPath\bin"
${If} $1 == ""
WriteRegExpandStr HKCU "Environment" "Path" "$OTPPath\bin;$0"
${Else}
MessageBox MB_OK "$OTPPath\bin already in %PATH%"
${EndIf}
${EndIf}
${NSD_GetState} $AddElixirToPathCheckbox $0
${If} $0 <> ${BST_UNCHECKED}
ReadRegStr $0 HKCU "Environment" "Path"
${StrStr} $1 "$0" "$INSTDIR\bin"
${If} $1 == ""
WriteRegExpandStr HKCU "Environment" "Path" "$INSTDIR\bin;$0"
${Else}
MessageBox MB_OK "$INSTDIR\bin already in %PATH%"
${EndIf}
${EndIf}
FunctionEnd
Section "Install Elixir" SectionElixir
SetOutPath "$INSTDIR"
File /r "${ELIXIR_DIR}\"
WriteUninstaller "Uninstall.exe"
SectionEnd
; Uninstall Page: Files
!insertmacro MUI_UNPAGE_DIRECTORY
!insertmacro MUI_UNPAGE_INSTFILES
Section "Uninstall"
RMDir /r "$INSTDIR"
SectionEnd
; Uninstall Page: Finish
var RemoveOTPFromPathCheckbox
var RemoveElixirFromPathCheckbox
Function un.FinishPageShow
!insertmacro MUI_HEADER_TEXT "Finish Setup" ""
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
ReadRegStr $0 HKCU "Environment" "Path"
${UnStrStr} $1 "$0" "$INSTDIR\bin"
${If} $1 != ""
${NSD_CreateCheckbox} 0 0 195u 10u "&Remove $INSTDIR\bin from %PATH%"
Pop $RemoveElixirFromPathCheckbox
SendMessage $RemoveElixirFromPathCheckbox ${BM_SETCHECK} ${BST_CHECKED} 0
${EndIf}
EnumRegKey $1 HKLM "SOFTWARE\WOW6432NODE\Ericsson\Erlang" 0
ReadRegStr $1 HKLM "SOFTWARE\WOW6432NODE\Ericsson\Erlang\$1" ""
StrCpy $OTPPath $1
${UnStrStr} $1 "$0" "$OTPPath\bin"
${If} $1 != ""
${NSD_CreateCheckbox} 0 20u 195u 10u "&Remove $OTPPath\bin from %PATH%"
Pop $RemoveOTPFromPathCheckbox
SendMessage $RemoveOTPFromPathCheckbox ${BM_SETCHECK} ${BST_CHECKED} 0
${EndIf}
nsDialogs::Show
FunctionEnd
Function un.FinishPageLeave
ReadRegStr $0 HKCU "Environment" "Path"
${NSD_GetState} $RemoveOTPFromPathCheckbox $1
${If} $1 <> ${BST_UNCHECKED}
${UnStrRep} $0 "$0" "$OTPPath\bin;" ""
${EndIf}
${NSD_GetState} $RemoveElixirFromPathCheckbox $1
${If} $1 <> ${BST_UNCHECKED}
${UnStrRep} $0 "$0" "$INSTDIR\bin;" ""
${EndIf}
WriteRegExpandStr HKCU "Environment" "Path" "$0"
FunctionEnd
UninstPage custom un.FinishPageShow un.FinishPageLeave
!insertmacro MUI_LANGUAGE "English"
+5 -2
View File
@@ -510,12 +510,15 @@ get_moduledoc_meta(Set) ->
get_docs(Set, Module, Definitions, Kind) ->
[{Key,
erl_anno:new(Line),
maybe_generated(erl_anno:new(Line), Ctx),
[signature_to_binary(Module, Name, Signature)],
doc_value(Doc, Name),
Meta
} || {Name, Arity} <- Definitions,
{Key, _Ctx, Line, Signature, Doc, Meta} <- ets:lookup(Set, {Kind, Name, Arity})].
{Key, Ctx, Line, Signature, Doc, Meta} <- ets:lookup(Set, {Kind, Name, Arity})].
maybe_generated(Ann, nil) -> Ann;
maybe_generated(Ann, _Ctx) -> erl_anno:set_generated(true, Ann).
get_callback_docs(Set, Callbacks) ->
[{Key,
+3 -3
View File
@@ -1030,8 +1030,8 @@ extract_heredoc_with_interpolation(Line, Column, Scope, Interpol, T, H) ->
end;
error ->
Message = "heredoc allows only zero or more whitespace characters followed by a new line after ",
{error, {Line, Column, io_lib:format(Message, []), [H, H, H]}}
Message = "heredoc allows only whitespace characters followed by a new line after opening ",
{error, {Line, Column + 3, io_lib:format(Message, []), [H, H, H]}}
end.
extract_heredoc_header("\r\n" ++ Rest) ->
@@ -1796,7 +1796,7 @@ prune_tokens([{OpType, _, _} | _] = Tokens, [], Terminators)
OpType =:= in_match_op; OpType =:= type_op; OpType =:= dual_op; OpType =:= mult_op;
OpType =:= power_op; OpType =:= concat_op; OpType =:= range_op; OpType =:= xor_op;
OpType =:= pipe_op; OpType =:= stab_op; OpType =:= when_op; OpType =:= assoc_op;
OpType =:= rel_op; OpType =:= ternary_op ->
OpType =:= rel_op; OpType =:= ternary_op; OpType =:= capture_op ->
{Tokens, Terminators};
%%% or we traverse until the end.
prune_tokens([_ | Tokens], Opener, Terminators) ->
@@ -1098,6 +1098,8 @@ defmodule CodeFragmentTest do
test "keeps operators" do
assert cc2q("1 + 2") == s2q("1 + __cursor__()")
assert cc2q("&foo") == s2q("&__cursor__()")
assert cc2q("&foo/") == s2q("&foo/__cursor__()")
end
test "keeps function calls without parens" do
@@ -1200,11 +1202,6 @@ defmodule CodeFragmentTest do
assert cc2q("(fn x, y -> x + y end") == s2q("(__cursor__())")
end
test "removes captures" do
assert cc2q("[& &1") == s2q("[__cursor__()]")
assert cc2q("[&(&1") == s2q("[__cursor__()]")
end
test "removes closed terminators" do
assert cc2q("foo([1, 2, 3]") == s2q("foo(__cursor__())")
assert cc2q("foo({1, 2, 3}") == s2q("foo(__cursor__())")
+10
View File
@@ -1102,6 +1102,16 @@ defmodule EnumTest do
[2, 1, 3]
end
test "slice on MapSets" do
assert MapSet.new(1..10) |> Enum.slice(0, 2) |> Enum.count() == 2
assert MapSet.new(1..3) |> Enum.slice(0, 10) |> Enum.count() == 3
assert MapSet.new(1..10) |> Enum.slice(0..1) |> Enum.count() == 2
assert MapSet.new(1..3) |> Enum.slice(0..10) |> Enum.count() == 3
assert MapSet.new(1..10) |> Enum.slice(0..4//2) |> Enum.count() == 3
assert MapSet.new(1..10) |> Enum.slice(0..5//2) |> Enum.count() == 3
end
test "sort/1" do
assert Enum.sort([5, 3, 2, 4, 1]) == [1, 2, 3, 4, 5]
end
@@ -381,4 +381,30 @@ defmodule Kernel.DocsTest do
{{:fuz, 0}, :none}
] = Enum.sort(function_docs)
end
test "generated functions are annotated as such" do
write_beam(
defmodule ToBeUsed do
defmacro __using__(_) do
quote do
@doc "Hello"
def foo, do: :bar
end
end
end
)
write_beam(
defmodule WillBeUsing do
use ToBeUsed
end
)
{:docs_v1, _, _, _, _, _, docs} = Code.fetch_docs(WillBeUsing)
assert [
{{:function, :foo, 0}, [generated: true, location: 399], ["foo()"],
%{"en" => "Hello"}, %{}}
] = docs
end
end
@@ -538,7 +538,7 @@ defmodule Kernel.ParserTest do
describe "syntax errors" do
test "invalid heredoc start" do
assert_syntax_error(
~r/nofile:1:1: heredoc allows only zero or more whitespace characters followed by a new line after \"\"\"/,
~r/nofile:1:4: heredoc allows only whitespace characters followed by a new line after opening \"\"\"/,
~c"\"\"\"bar\n\"\"\""
)
end
+15 -1
View File
@@ -831,11 +831,25 @@ defmodule KernelTest do
end
test "matching attribute" do
assert_raise ArgumentError, ~r"invalid write attribute syntax", fn ->
assert_raise ArgumentError, ~r"invalid usage of module attributes", fn ->
defmodule MatchAttributeInModule do
@foo = 42
end
end
assert_raise ArgumentError, ~r"invalid usage of module attributes", fn ->
defmodule MatchAttributeInModule do
@foo 16
<<_::@foo>> = "ab"
end
end
assert_raise ArgumentError, ~r"invalid usage of module attributes", fn ->
defmodule MatchAttributeInModule do
@foo 16
<<_::size(@foo)>> = "ab"
end
end
end
end
+2 -1
View File
@@ -293,8 +293,9 @@ defmodule ExUnit.Runner do
{test_module, invalid_tests, []}
{:DOWN, ^module_ref, :process, ^module_pid, error} ->
invalid_tests = Enum.map(tests, &%{&1 | state: {:invalid, test_module}})
test_module = %{test_module | state: failed({:EXIT, module_pid}, error, [])}
{test_module, [], []}
{test_module, invalid_tests, []}
end
timeout = get_timeout(config, %{})
@@ -124,6 +124,22 @@ defmodule ExUnit.CallbacksTest do
"** (MatchError) no match of right hand side value: :error"
end
test "doesn't choke on setup_all exits" do
defmodule SetupAllExitTest do
use ExUnit.Case
setup_all _ do
Process.exit(self(), :error)
end
test "ok" do
assert true
end
end
assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures, 1 invalid"
end
test "doesn't choke on dead supervisor" do
defmodule StartSupervisedErrorTest do
use ExUnit.Case
+2
View File
@@ -689,6 +689,8 @@ defmodule IEx.Pry do
[asts_string, :faint, " #=> ", :reset, inspect(value, options), "\n\n"]
|> IO.ANSI.format()
|> IO.write()
value
end
defp chunk_pipeline_asts_by_line(asts, %Macro.Env{line: env_line}) do
+25 -18
View File
@@ -210,7 +210,7 @@ defmodule Logger do
metadata: [:error_code, :file]
Or to configure default handler, for instance, to log into a file with
built-in support for log rotation:
built-in support for log rotation and compression:
config :logger, :default_handler,
config: [
@@ -218,9 +218,18 @@ defmodule Logger do
filesync_repeat_interval: 5000,
file_check: 5000,
max_no_bytes: 10_000_000,
max_no_files: 5
max_no_files: 5,
compress_on_rotate: true
]
See [`:logger_std_h`](`:logger_std_h`) for all relevant configuration,
including overload protection. Or set `:default_handler` to false to
disable the default logging altogether:
config :logger, :default_handler, false
How to add new handlers is covered in later sections.
> #### Keywords or maps {: .tip}
>
> While Erlang's logger expects `:config` to be a map, Elixir's Logger
@@ -231,14 +240,6 @@ defmodule Logger do
> When reading the handler configuration using Erlang's APIs,
> the configuration will always be read (and written) as a map.
See [`:logger_std_h`](`:logger_std_h`) for all relevant configuration,
including overload protection. Or set `:default_handler` to false to
disable the default logging altogether:
config :logger, :default_handler, false
How to add new handlers is covered in later sections.
### Compile configuration
The following configuration must be set via config files (such as
@@ -329,16 +330,19 @@ defmodule Logger do
default handler, but you can use Erlang's [`:logger`](`:logger`) module
to add other handlers too.
Erlang/OTP handlers must be listed under your own application. For example,
to setup an additional handler that writes to disk:
Erlang/OTP handlers must be listed under your own application.
For example, to setup an additional handler, so you write to
console and file:
config :my_app, :logger, [
{:handler, :disk_log, :logger_disk_log_h, %{
{:handler, :file_log, :logger_std_h, %{
config: %{
file: 'system.log',
file: ~c"system.log",
filesync_repeat_interval: 5000,
file_check: 5000,
max_no_bytes: 10_000_000,
max_no_files: 5
max_no_files: 5,
compress_on_rotate: true
},
formatter: Logger.Formatter.new()
}}
@@ -355,9 +359,12 @@ defmodule Logger do
flexibility but they should avoid performing any long running action in
such handlers, as it may slow down the action being executed considerably.
At the moment, there is no built-in overload protection for Erlang handlers,
so it is your responsibility to implement it. Alternatively, you can use the
[`:logger_backends`](https://github.com/elixir-lang/logger_backends)
project.
so it is your responsibility to implement it.
Alternatively, you can use the
[`:logger_backends`](https://github.com/elixir-lang/logger_backends) project.
It sets up a log handler with overload protection and allows incoming events
to be dispatched to multiple backends.
## Backends and backwards compatibility
+6 -2
View File
@@ -136,8 +136,12 @@ defmodule Mix.AppLoader do
end
# We have processed all apps.
defp traverse_apps([], _seen, _deps_children, _builtin_paths, _lib_path) do
[]
defp traverse_apps([], seen, _deps_children, builtin_paths, _lib_path) do
# We want to keep erts in the load path but it doesn't require to be loaded.
case builtin_paths do
%{erts: path} when not is_map_key(seen, :erts) -> [{:erts, path}]
%{} -> []
end
end
defp app_children(app) do
+1 -1
View File
@@ -31,7 +31,7 @@ defmodule Mix.Tasks.Compile.All do
{loaded_paths, loaded_modules} =
Mix.AppLoader.load_apps(apps, deps, config, {[], []}, fn {app, path}, {paths, mods} ->
paths = if path, do: [path | paths], else: paths
mods = if app_cache, do: [{app, Application.spec(app, :modules)} | mods], else: mods
mods = if app_cache, do: [{app, Application.spec(app, :modules) || []} | mods], else: mods
{paths, mods}
end)
+31 -14
View File
@@ -38,8 +38,9 @@ defmodule Mix.Tasks.Xref do
$ mix xref trace lib/my_app/router.ex --label compile
If you have an umbrella application, we also recommend using the
`--include-siblings` flag to see the dependencies on other
umbrella applications.
`--include-siblings` flag to see the dependencies from sibling
applications. The `trace` command is not currently supported at the
umbrella root.
### Example
@@ -222,6 +223,12 @@ defmodule Mix.Tasks.Xref do
lib/a.ex
└── lib/b.ex (compile)
If you have an umbrella application, we also recommend using the
`--include-siblings` flag to see the dependencies from sibling
applications. When invoked at the umbrella root, the `graph`
command will list all files from all umbrella children, without
any namespacing.
### Dependency types
Elixir tracks three types of dependencies between modules: compile,
@@ -289,12 +296,6 @@ defmodule Mix.Tasks.Xref do
@impl true
def run(args) do
if Mix.Project.umbrella?() do
Mix.raise(
"mix xref is not supported in the umbrella root. Please run it inside the umbrella applications instead"
)
end
Mix.Task.run("compile", args)
Mix.Task.reenable("xref")
@@ -302,9 +303,11 @@ defmodule Mix.Tasks.Xref do
case args do
["callers", module] ->
no_umbrella!("callers")
handle_callers(module, opts)
["trace", file] ->
no_umbrella!("trace")
handle_trace(file, opts)
["graph"] ->
@@ -327,6 +330,14 @@ defmodule Mix.Tasks.Xref do
end
end
defp no_umbrella!(task) do
if Mix.Project.umbrella?() do
Mix.raise(
"mix xref #{task} is not supported in the umbrella root. Please run it inside the umbrella applications instead"
)
end
end
@doc """
Returns a list of information of all the runtime function calls in the project.
@@ -1058,12 +1069,18 @@ defmodule Mix.Tasks.Xref do
defp manifests(opts) do
siblings =
if opts[:include_siblings] do
for %{scm: Mix.SCM.Path, opts: opts} <- Mix.Dep.cached(),
opts[:in_umbrella],
do: Path.join([opts[:build], ".mix", @manifest])
else
[]
cond do
Mix.Project.umbrella?() ->
for %{opts: opts} <- Mix.Dep.Umbrella.cached(),
do: Path.join([opts[:build], ".mix", @manifest])
opts[:include_siblings] ->
for %{scm: Mix.SCM.Path, opts: opts} <- Mix.Dep.cached(),
opts[:in_umbrella],
do: Path.join([opts[:build], ".mix", @manifest])
true ->
[]
end
[Path.join(Mix.Project.manifest_path(), @manifest) | siblings]
+4
View File
@@ -335,6 +335,10 @@ defmodule Mix.Tasks.CompileTest do
in_fixture("no_mixfile", fn ->
assert Mix.Task.run("compile", []) == {:ok, []}
assert :code.where_is_file(~c"parsetools.app") == :non_existing
# Make sure erts is also kept but not loaded
assert {:docs_v1, _, _, _, _, _, _} = Code.fetch_docs(:zlib)
assert Application.spec(:erts, :vsn) == nil
end)
end
+37
View File
@@ -915,6 +915,43 @@ defmodule Mix.Tasks.XrefTest do
end)
end
test "generates reports from the umbrella root" do
Mix.Project.pop()
in_fixture("umbrella_dep/deps/umbrella", fn ->
Mix.Project.in_project(:umbrella, ".", fn _ ->
File.write!("apps/bar/lib/bar.ex", """
defmodule Bar do
def bar do
Foo.foo()
end
end
""")
Mix.Task.run("compile")
Mix.shell().flush()
Mix.Tasks.Xref.run(["graph", "--format", "stats", "--include-siblings"])
assert receive_until_no_messages([]) == """
Tracked files: 2 (nodes)
Compile dependencies: 0 (edges)
Exports dependencies: 0 (edges)
Runtime dependencies: 1 (edges)
Cycles: 0
Top 2 files with most outgoing dependencies:
* lib/bar.ex (1)
* lib/foo.ex (0)
Top 2 files with most incoming dependencies:
* lib/foo.ex (1)
* lib/bar.ex (0)
"""
end)
end)
end
test "generates reports considering siblings inside umbrellas" do
Mix.Project.pop()
+21 -18
View File
@@ -1,3 +1,16 @@
home = Path.expand("../tmp/.home", __DIR__)
File.mkdir_p!(home)
System.put_env("HOME", home)
mix = Path.expand("../tmp/.mix", __DIR__)
File.mkdir_p!(mix)
System.put_env("MIX_HOME", mix)
System.delete_env("XDG_DATA_HOME")
System.delete_env("XDG_CONFIG_HOME")
## Setup Mix
Mix.start()
Mix.shell(Mix.Shell.Process)
Application.put_env(:mix, :colors, enabled: false)
@@ -5,6 +18,8 @@ Application.put_env(:mix, :colors, enabled: false)
Logger.remove_backend(:console)
Application.put_env(:logger, :backends, [])
## Setup ExUnit
os_exclude = if match?({:win32, _}, :os.type()), do: [unix: true], else: [windows: true]
epmd_exclude = if match?({:win32, _}, :os.type()), do: [epmd: true], else: []
git_exclude = if Mix.SCM.Git.git_version() <= {1, 7, 4}, do: [git_sparse: true], else: []
@@ -212,18 +227,7 @@ defmodule MixTest.Case do
end
end
## Set up globals
home = MixTest.Case.tmp_path(".home")
File.mkdir_p!(home)
System.put_env("HOME", home)
mix = MixTest.Case.tmp_path(".mix")
File.mkdir_p!(mix)
System.put_env("MIX_HOME", mix)
System.delete_env("XDG_DATA_HOME")
System.delete_env("XDG_CONFIG_HOME")
## Set up Rebar fixtures
rebar3_source = System.get_env("REBAR3") || Path.expand("fixtures/rebar3", __DIR__)
[major, minor | _] = String.split(System.version(), ".")
@@ -231,8 +235,6 @@ rebar3_target = Path.join([mix, "elixir", "#{major}-#{minor}", "rebar3"])
File.mkdir_p!(Path.dirname(rebar3_target))
File.cp!(rebar3_source, rebar3_target)
## Copy fixtures to tmp
fixtures = ~w(rebar_dep rebar_override)
Enum.each(fixtures, fn fixture ->
@@ -242,12 +244,13 @@ Enum.each(fixtures, fn fixture ->
File.cp_r!(source, dest)
end)
## Generate Git repo fixtures
## Set up Git fixtures
System.cmd("git", ~w[config --global user.email mix@example.com])
System.cmd("git", ~w[config --global user.name mix-repo])
System.cmd("git", ~w[config --global init.defaultBranch not-main])
# Git repo
### Git repo
target = Path.expand("fixtures/git_repo", __DIR__)
unless File.dir?(target) do
@@ -329,7 +332,7 @@ unless File.dir?(target) do
end)
end
# Deps on Git repo
### Deps on Git repo
target = Path.expand("fixtures/deps_on_git_repo", __DIR__)
unless File.dir?(target) do
@@ -423,7 +426,7 @@ Enum.each([:invalidapp, :invalidvsn, :noappfile, :nosemver, :ok], fn dep ->
File.mkdir_p!(Path.expand("fixtures/deps_status/deps/#{dep}/.git", __DIR__))
end)
# Archive ebin
### Archive ebin
target = Path.expand("fixtures/archive", __DIR__)
unless File.dir?(Path.join(target, "ebin")) do