Skip to content

Commit b70ff5d

Browse files
authored
Merge branch 'main' into add-gleam-compiler
2 parents 220a0d7 + ea2ae22 commit b70ff5d

File tree

111 files changed

+3166
-1333
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3166
-1333
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ permissions:
2121

2222
jobs:
2323
test_linux:
24-
name: Ubuntu 24.04, Erlang/OTP ${{ matrix.otp_version }}${{ matrix.deterministic && ' (deterministic)' || '' }}
24+
name: Ubuntu 24.04, Erlang/OTP ${{ matrix.otp_version }}${{ matrix.deterministic && ' (deterministic)' || '' }}${{ matrix.coverage && ' (coverage)' || '' }}
2525
strategy:
2626
fail-fast: false
2727
matrix:
2828
include:
2929
- otp_version: "27.1"
3030
deterministic: true
31+
- otp_version: "27.1"
32+
erlc_opts: "warnings_as_errors"
33+
coverage: true
3134
- otp_version: "27.1"
3235
otp_latest: true
3336
erlc_opts: "warnings_as_errors"
@@ -68,6 +71,11 @@ jobs:
6871
- name: Elixir test suite
6972
run: make test_elixir
7073
continue-on-error: ${{ matrix.development }}
74+
env:
75+
COVER: "${{ matrix.coverage }}"
76+
- name: "Calculate Coverage"
77+
run: make cover | tee "$GITHUB_STEP_SUMMARY"
78+
if: "${{ matrix.coverage }}"
7179
- name: Build docs (ExDoc main)
7280
if: ${{ matrix.otp_latest }}
7381
run: |
@@ -85,6 +93,12 @@ jobs:
8593
# Recompile System without .git
8694
cd lib/elixir && ../../bin/elixirc -o ebin lib/system.ex && cd -
8795
taskset 1 make check_reproducible
96+
- name: "Upload Coverage Artifact"
97+
if: "${{ matrix.coverage }}"
98+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
99+
with:
100+
name: TestCoverage
101+
path: cover/*
88102

89103
test_windows:
90104
name: Windows Server 2019, Erlang/OTP ${{ matrix.otp_version }}

.github/workflows/release.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ jobs:
127127

128128
steps:
129129
- name: "Download build"
130-
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
130+
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
131131
with:
132132
name: build-${{ matrix.flavor }}-elixir-otp-${{ matrix.otp }}
133133

@@ -201,7 +201,7 @@ jobs:
201201

202202
- name: "Download Build Artifacts"
203203
id: download-build-artifacts
204-
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
204+
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
205205
with:
206206
pattern: "{sign-*-elixir-otp-*,Docs}"
207207
merge-multiple: true
@@ -267,7 +267,7 @@ jobs:
267267
contents: write
268268

269269
steps:
270-
- uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
270+
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
271271
with:
272272
pattern: "{sign-*-elixir-otp-*,Docs,SBoM,Attestations}"
273273
merge-multiple: true
@@ -312,7 +312,7 @@ jobs:
312312
FASTLY_KEY: ${{ secrets.HEX_FASTLY_KEY }}
313313
OTP_GENERIC_VERSION: "25"
314314
steps:
315-
- uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
315+
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
316316
with:
317317
pattern: "{sign-*-elixir-otp-*,Docs}"
318318
merge-multiple: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
/.eunit
1616
.elixir.plt
1717
erl_crash.dump
18+
/cover/

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ https://elixir-lang.org/blog/2025/02/26/elixir-openchain-certification/
117117
* [Kernel] Support `min/2` and `max/2` as guards
118118
* [Macro] Print debugging results from `Macro.dbg/1` as they happen, instead of once at the end
119119
* [Protocol] Type checking of protocols dispatch and implementations
120-
* [Protocol] Add `Protocol.impl_for/2` and `Protocol.impl_for!/2`
121120

122121
#### ExUnit
123122

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ GIT_TAG = $(strip $(shell head="$(call GIT_REVISION)"; git tag --points-at $$hea
2626
SOURCE_DATE_EPOCH_PATH = lib/elixir/tmp/ebin_reproducible
2727
SOURCE_DATE_EPOCH_FILE = $(SOURCE_DATE_EPOCH_PATH)/SOURCE_DATE_EPOCH
2828

29-
.PHONY: install install_man build_plt clean_plt dialyze test check_reproducible clean clean_elixir clean_man format docs Docs.zip Precompiled.zip zips
29+
.PHONY: cover install install_man build_plt clean_plt dialyze test check_reproducible clean clean_elixir clean_man format docs Docs.zip Precompiled.zip zips
3030
.NOTPARALLEL:
3131

3232
#==> Functions
@@ -53,6 +53,10 @@ lib/$(1)/ebin/Elixir.$(2).beam: $(wildcard lib/$(1)/lib/*.ex) $(wildcard lib/$(1
5353
test_$(1): test_formatted $(1)
5454
@ echo "==> $(1) (ex_unit)"
5555
$(Q) cd lib/$(1) && ../../bin/elixir -r "test/test_helper.exs" -pr "test/**/$(TEST_FILES)";
56+
57+
cover/ex_unit_$(1).coverdata:
58+
$(Q) COVER="1" $(MAKE) test_$(1)
59+
cover/combined.coverdata: cover/ex_unit_$(1).coverdata
5660
endef
5761

5862
define WRITE_SOURCE_DATE_EPOCH
@@ -175,6 +179,7 @@ clean: clean_man
175179
rm -rf lib/mix/test/fixtures/git_sparse_repo/
176180
rm -rf lib/mix/test/fixtures/archive/ebin/
177181
rm -f erl_crash.dump
182+
rm -rf cover
178183

179184
clean_elixir:
180185
$(Q) rm -f lib/*/ebin/Elixir.*.beam
@@ -287,6 +292,15 @@ test_stdlib: compile
287292
cd lib/elixir && ../../bin/elixir --sname primary -r "test/elixir/test_helper.exs" -pr "test/elixir/**/$(TEST_FILES)"; \
288293
fi
289294

295+
cover/ex_unit_elixir.coverdata:
296+
$(Q) COVER="1" $(MAKE) test_stdlib
297+
cover/combined.coverdata: cover/ex_unit_elixir.coverdata
298+
299+
cover/combined.coverdata:
300+
bin/elixir ./lib/elixir/scripts/cover.exs
301+
302+
cover: cover/combined.coverdata
303+
290304
#==> Dialyzer tasks
291305

292306
DIALYZER_OPTS = --no_check_plt --fullpath -Werror_handling -Wunmatched_returns -Wunderspecs

README.md

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
</h1>
1313

1414
[![CI](https://github.com/elixir-lang/elixir/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/elixir-lang/elixir/actions/workflows/ci.yml?query=branch%3Amain)
15+
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/10187/badge)](https://www.bestpractices.dev/projects/10187)
1516

1617
Elixir is a dynamic, functional language designed for building scalable
1718
and maintainable applications.
@@ -37,15 +38,12 @@ All contributions are required to conform to our [Open Source Policy][11].
3738

3839
For reporting bugs, [visit our issue tracker][2] and follow the steps
3940
for reporting a new issue. **Please disclose security vulnerabilities
40-
privately at <elixir-security@googlegroups.com>**.
41+
privately [in our Security page](https://github.com/elixir-lang/elixir/security)**.
4142

42-
## Issues tracker management
43-
44-
All currently open bugs related to the Elixir repository are listed
45-
in the issues tracker. The Elixir team uses the issues tracker to focus
46-
on *actionable items*, including planned enhancements in the short and
47-
medium term. We also do our best to label entries for clarity and to ease
48-
collaboration.
43+
All currently open bugs related to Elixir are listed in the issues tracker.
44+
The Elixir team uses the issues tracker to focus on *actionable items*,
45+
including planned enhancements in the short and medium term. We also do
46+
our best to label entries for clarity and to ease collaboration.
4947

5048
Our *actionable item policy* has some important consequences, such as:
5149

@@ -57,38 +55,42 @@ Our *actionable item policy* has some important consequences, such as:
5755
elsewhere if appropriate).
5856

5957
* We actively close unrelated and non-actionable issues to keep the
60-
issues tracker tidy. We may get things wrong from time to
61-
time and will gladly revisit issues, reopening when necessary.
62-
63-
Keep the tone positive and be kind! For more information, see the
64-
[Code of Conduct][1].
65-
66-
### Proposing new features
58+
issues tracker tidy. If you believe we got something wrong, drop a
59+
comment and we can always reopen the issue.
6760

68-
For proposing new features, please start a discussion in the
69-
[Elixir Core mailing list][3]. The [language development history and
70-
its focus are described on our website](https://elixir-lang.org/development.html).
71-
72-
Keep in mind that it is your responsibility to argue and explain
73-
why a feature is useful and how it will impact the codebase and
74-
the community. A good proposal includes the problem description
75-
and how the proposed solution compares with existing alternatives
76-
in the Elixir ecosystem (as well as in other languages). To iron
77-
out a proposal before submission, consider using and gathering
78-
feedback from the community spaces [listed on the sidebar of the
79-
Elixir website](https://elixir-lang.org/).
80-
81-
Once a proposal is accepted, it will be added to [the issue tracker][2].
82-
Features and bug fixes that have already been merged and will be included
83-
in the next release are then "closed" and added to the [changelog][7].
61+
By keeping the overall issues tracker tidy and organized, the community
62+
can easily peak at what is coming in new releases and also get involved
63+
by commenting on existing issues and submitting pull requests. Please
64+
remember to keep the tone positive and be kind! For more information,
65+
see the [Code of Conduct][1].
8466

85-
### Discussions, support, and help
67+
## Discussions, support, and help
8668

8769
For general discussions, support, and help, please use the community
8870
spaces [listed on the sidebar of the Elixir website](https://elixir-lang.org/),
8971
such as forums, chat platforms, etc, where the wider community will be available
9072
to help you.
9173

74+
## Proposing new features
75+
76+
We encourage you to first propose new features in the community spaces
77+
listed above. These discussions help refine ideas and gather feedback before
78+
submission. Our website also includes [a general outline of the language
79+
history and its current development focus](https://elixir-lang.org/development.html).
80+
81+
Once you are ready, you can submit your proposal to the [Elixir Core
82+
mailing list][3], either through the web interface or by subscribing to
83+
it at <[email protected]>. Remember to include
84+
a clear problem description, compare the proposed solution to existing
85+
alternatives in the Elixir ecosystem (and in other languages if possible),
86+
and consider the potential impact your changes will have on the codebase and
87+
community.
88+
89+
Once a proposal is accepted, it will be added to [the issue tracker][2].
90+
Features and bug fixes that have already been merged and will be included
91+
in the next release are then "closed" and added to the [changelog][7]
92+
before release.
93+
9294
## Compiling from source
9395

9496
For the many different ways to install Elixir,

lib/eex/lib/eex/compiler.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ defmodule EEx.Compiler do
304304
source: source,
305305
line: line,
306306
quoted: [],
307-
parser_options: parser_options,
307+
parser_options: [indentation: indentation] ++ parser_options,
308308
indentation: indentation
309309
}
310310

lib/eex/test/eex_test.exs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,59 @@ defmodule EExTest do
502502
end
503503
end
504504

505+
test "from Elixir parser" do
506+
line = __ENV__.line + 6
507+
508+
message =
509+
assert_raise TokenMissingError, fn ->
510+
EEx.compile_string(
511+
"""
512+
<li>
513+
<strong>Some:</strong>
514+
<%= true && @some[ %>
515+
</li>
516+
""",
517+
file: __ENV__.file,
518+
line: line,
519+
indentation: 12
520+
)
521+
end
522+
523+
assert message |> Exception.message() |> strip_ansi() =~ """
524+
525+
514 │ true && @some[\s
526+
│ │ └ missing closing delimiter (expected "]")
527+
│ └ unclosed delimiter
528+
"""
529+
end
530+
531+
test "from Elixir parser with line breaks" do
532+
line = __ENV__.line + 6
533+
534+
message =
535+
assert_raise TokenMissingError, fn ->
536+
EEx.compile_string(
537+
"""
538+
<li>
539+
<strong>Some:</strong>
540+
<%= true &&
541+
@some[ %>
542+
</li>
543+
""",
544+
file: __ENV__.file,
545+
line: line,
546+
indentation: 12
547+
)
548+
end
549+
550+
assert message |> Exception.message() |> strip_ansi() =~ """
551+
552+
#{line + 3} │ @some[\s
553+
│ │ └ missing closing delimiter (expected "]")
554+
│ └ unclosed delimiter
555+
"""
556+
end
557+
505558
test "honor line numbers" do
506559
assert_raise EEx.SyntaxError,
507560
"nofile:100:6: expected closing '%>' for EEx expression",
@@ -948,6 +1001,12 @@ defmodule EExTest do
9481001
end
9491002
end
9501003

1004+
@strip_ansi [IO.ANSI.green(), IO.ANSI.red(), IO.ANSI.reset()]
1005+
1006+
defp strip_ansi(doc) do
1007+
String.replace(doc, @strip_ansi, "")
1008+
end
1009+
9511010
defp assert_eval(expected, actual, binding \\ [], opts \\ []) do
9521011
opts = Keyword.merge([file: __ENV__.file, engine: opts[:engine] || EEx.Engine], opts)
9531012
result = EEx.eval_string(actual, binding, opts)

lib/eex/test/test_helper.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
{line_exclude, line_include} =
66
if line = System.get_env("LINE"), do: {[:test], [line: line]}, else: {[], []}
77

8+
Code.require_file("../../elixir/scripts/cover_record.exs", __DIR__)
9+
CoverageRecorder.maybe_record("eex")
10+
811
ExUnit.start(
912
trace: !!System.get_env("TRACE"),
1013
include: line_include,

0 commit comments

Comments
 (0)