Skip to content

Commit fcfa58a

Browse files
lukaszsamsonscohen
andauthored
Fix windows ci (#851)
* Reenable CI on Windows * Replaced hard coded paths with calls to Path.join * Testing the approach of updating expectations manually * Fixed test also applied a fix from another branch to see if the tests pass * Fixed straggler path that breaks in windows * Changed error message so we can see what's going on in windows * Normalized parent and child to ensure subdirectory? succeeds * Change to figure out why inputs aren't matching * formatted * One more time... * Converted the uri to a path to get system separators * Trying with paths again * normalized both sides... * fixed formatting * fix formatter tests on windows * rename function * remove not needed functions --------- Co-authored-by: Steve Cohen <scohen@scohen.org>
1 parent 23de15f commit fcfa58a

File tree

7 files changed

+134
-82
lines changed

7 files changed

+134
-82
lines changed

.github/workflows/ci.yml

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,50 +49,48 @@ jobs:
4949
mix deps.get --only test
5050
- run: mix test
5151

52-
# TODO reenable when https://github.com/erlef/setup-beam/issues/167 is fixed
53-
# currently windows builds are failing with 403s on setup_beam action
54-
# mix_test_windows:
55-
# name: mix test windows (Elixir ${{matrix.elixir}} | Erlang/OTP ${{matrix.otp}})
56-
# runs-on: windows-2019
57-
# strategy:
58-
# fail-fast: false
59-
# matrix:
60-
# include:
61-
# - elixir: 1.12.x
62-
# otp: 22.x
63-
# - elixir: 1.12.x
64-
# otp: 23.x
65-
# - elixir: 1.13.x
66-
# otp: 22.x
67-
# - elixir: 1.13.x
68-
# otp: 23.x
69-
# - elixir: 1.13.x
70-
# otp: 24.x
71-
# - elixir: 1.13.x
72-
# otp: 25.x
73-
# - elixir: 1.14.x
74-
# otp: 23.x
75-
# - elixir: 1.14.x
76-
# otp: 24.x
77-
# - elixir: 1.14.x
78-
# otp: 25.x
79-
# env:
80-
# MIX_ENV: test
81-
# steps:
82-
# - name: Set git to use original line ending
83-
# run: |
84-
# git config --global core.autocrlf false
85-
# - uses: actions/checkout@v3
86-
# - uses: erlef/setup-beam@v1
87-
# with:
88-
# otp-version: ${{matrix.otp}}
89-
# elixir-version: ${{matrix.elixir}}
90-
# - name: Install Dependencies
91-
# run: |
92-
# mix local.hex --force
93-
# mix local.rebar --force
94-
# mix deps.get --only test
95-
# - run: mix test
52+
mix_test_windows:
53+
name: mix test windows (Elixir ${{matrix.elixir}} | Erlang/OTP ${{matrix.otp}})
54+
runs-on: windows-2019
55+
strategy:
56+
fail-fast: false
57+
matrix:
58+
include:
59+
- elixir: 1.12.x
60+
otp: 22.x
61+
- elixir: 1.12.x
62+
otp: 23.x
63+
- elixir: 1.13.x
64+
otp: 22.x
65+
- elixir: 1.13.x
66+
otp: 23.x
67+
- elixir: 1.13.x
68+
otp: 24.x
69+
- elixir: 1.13.x
70+
otp: 25.x
71+
- elixir: 1.14.x
72+
otp: 23.x
73+
- elixir: 1.14.x
74+
otp: 24.x
75+
- elixir: 1.14.x
76+
otp: 25.x
77+
env:
78+
MIX_ENV: test
79+
steps:
80+
- name: Set git to use original line ending
81+
run: |
82+
git config --global core.autocrlf false
83+
- uses: actions/checkout@v3
84+
- uses: erlef/setup-beam@v1
85+
with:
86+
otp-version: ${{matrix.otp}}
87+
elixir-version: ${{matrix.elixir}}
88+
- name: Install Dependencies
89+
run: |
90+
mix local.hex --force
91+
mix local.rebar --force
92+
mix deps.get --only test
93+
- run: mix test
9694

9795
static_analysis:
9896
name: static analysis (Elixir ${{matrix.elixir}} | Erlang/OTP ${{matrix.otp}})

apps/language_server/lib/language_server/experimental/code_mod/format.ex

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.Format do
33
alias ElixirLS.LanguageServer.Experimental.SourceFile
44
alias ElixirLS.LanguageServer.Experimental.SourceFile.Conversions
55
alias ElixirLS.LanguageServer.Experimental.Protocol.Types.TextEdit
6+
alias ElixirLS.LanguageServer.SourceFile.Path, as: SourceFilePath
67

78
require Logger
89
@type formatter_function :: (String.t() -> any) | nil
@@ -102,8 +103,8 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.Format do
102103
:ok
103104
else
104105
message =
105-
"Cannot format file from current directory " <>
106-
"(Currently in #{Path.relative_to(cwd, project_path)})"
106+
"Cannot format '#{document.path}' from current directory " <>
107+
"(Currently in #{project_path})"
107108

108109
{:error, message}
109110
end
@@ -112,31 +113,35 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.Format do
112113
defp check_inputs_apply(%SourceFile{} = document, project_path, inputs)
113114
when is_list(inputs) do
114115
formatter_dir = dominating_formatter_exs_dir(document, project_path)
116+
# document.path is native, convert to universal separators
117+
document_path = Path.absname(document.path)
115118

116119
inputs_apply? =
117120
Enum.any?(inputs, fn input_glob ->
118121
glob =
119122
if Path.type(input_glob) == :relative do
120-
Path.join(formatter_dir, input_glob)
123+
formatter_dir
124+
|> Path.join(input_glob)
121125
else
122126
input_glob
123127
end
124128

125-
PathGlobVendored.match?(document.path, glob, match_dot: true)
129+
PathGlobVendored.match?(document_path, glob, match_dot: true)
126130
end)
127131

128132
if inputs_apply? do
129133
:ok
130134
else
131-
{:error, :input_mismatch}
135+
{:error, {:input_mismatch, "#{document_path} is not matched by #{inspect(inputs)}"}}
132136
end
133137
end
134138

135139
defp check_inputs_apply(_, _, _), do: :ok
136140

137141
defp subdirectory?(child, parent: parent) do
138142
normalized_parent = Path.absname(parent)
139-
String.starts_with?(child, normalized_parent)
143+
normalized_child = Path.absname(child)
144+
String.starts_with?(normalized_child, normalized_parent)
140145
end
141146

142147
# Finds the directory with the .formatter.exs that's the nearest parent to the

apps/language_server/lib/language_server/source_file/path.ex

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ defmodule ElixirLS.LanguageServer.SourceFile.Path do
4141
uri |> from_uri |> Path.absname()
4242
end
4343

44+
def absolute(path) do
45+
path |> Path.expand() |> convert_separators_to_native()
46+
end
47+
4448
def to_uri(path) do
4549
path =
4650
path
@@ -83,6 +87,13 @@ defmodule ElixirLS.LanguageServer.SourceFile.Path do
8387
|> URI.to_string()
8488
end
8589

90+
def windows? do
91+
case os_type() do
92+
{:win32, _} -> true
93+
_ -> false
94+
end
95+
end
96+
8697
defp convert_separators_to_native(path) do
8798
if windows?() do
8899
# convert path separators from URI to Windows
@@ -101,13 +112,6 @@ defmodule ElixirLS.LanguageServer.SourceFile.Path do
101112
end
102113
end
103114

104-
defp windows? do
105-
case os_type() do
106-
{:win32, _} -> true
107-
_ -> false
108-
end
109-
end
110-
111115
# this is here to be mocked in tests
112116
defp os_type do
113117
:os.type()

apps/language_server/test/experimental/code_mod/format_test.exs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
defmodule ElixirLS.Experimental.FormatTest do
22
alias ElixirLS.LanguageServer.Experimental.CodeMod.Format
33
alias ElixirLS.LanguageServer.Experimental.SourceFile
4+
alias ElixirLS.LanguageServer.SourceFile.Path, as: SourceFilePath
45

56
use ElixirLS.Test.CodeMod.Case
67

@@ -13,7 +14,9 @@ defmodule ElixirLS.Experimental.FormatTest do
1314
end
1415

1516
def source_file(text) do
16-
SourceFile.new("file://#{__ENV__.file}", text, 1)
17+
__ENV__.file
18+
|> SourceFilePath.to_uri()
19+
|> SourceFile.new(text, 1)
1720
end
1821

1922
def unformatted do

apps/language_server/test/experimental/project_test.exs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
defmodule ElixirLS.Experimental.ProjectTest do
22
alias ElixirLS.LanguageServer.Experimental.Project
33
alias ElixirLS.LanguageServer.SourceFile
4+
alias ElixirLS.LanguageServer.Test.Paths
45

56
use ExUnit.Case, async: false
67
use Patch
@@ -30,11 +31,13 @@ defmodule ElixirLS.Experimental.ProjectTest do
3031
end
3132

3233
def root_uri do
33-
"file:///tmp/my_project"
34+
System.tmp_dir!()
35+
|> Path.join("my_project")
36+
|> SourceFile.Path.to_uri()
3437
end
3538

3639
def with_a_root_uri(_) do
37-
{:ok, root_uri: "file:///tmp/my_project"}
40+
{:ok, root_uri: root_uri()}
3841
end
3942

4043
setup do
@@ -240,35 +243,40 @@ defmodule ElixirLS.Experimental.ProjectTest do
240243
String.ends_with?(path, "mix.exs")
241244
end)
242245

243-
assert {:ok, %Project{} = project} =
244-
Project.change_project_directory(ctx.project, "sub_dir/new/dir")
246+
sub_dir = Path.join(~w(sub_dir new dir))
247+
assert {:ok, %Project{} = project} = Project.change_project_directory(ctx.project, sub_dir)
248+
249+
assert Project.project_path(project) ==
250+
[File.cwd!(), "sub_dir", "new", "dir"]
251+
|> Path.join()
252+
|> Paths.to_native_separators()
245253

246-
assert Project.project_path(project) == "#{File.cwd!()}/sub_dir/new/dir"
247254
assert project.mix_project?
248255
end
249256

250257
test "only sets the project directory if the root uri is set" do
251258
project = Project.new(nil)
259+
sub_dir = Path.join(~w(sub_dir new dir))
252260

253-
assert {:ok, project} = Project.change_project_directory(project, "sub_dir/new/dir")
261+
assert {:ok, project} = Project.change_project_directory(project, sub_dir)
254262
assert project.root_uri == nil
255263
assert Project.project_path(project) == nil
256264
end
257265

258266
test "defaults to the root uri's directory", ctx do
259267
assert {:ok, project} = Project.change_project_directory(ctx.project, nil)
260268
root_path = SourceFile.Path.absolute_from_uri(project.root_uri)
261-
assert Project.project_path(project) == root_path
269+
assert Project.project_path(project) == Paths.to_native_separators(root_path)
262270
end
263271

264272
test "defaults to the root uri's directory if the project directory is empty", ctx do
265273
assert {:ok, project} = Project.change_project_directory(ctx.project, "")
266274
root_path = SourceFile.Path.absolute_from_uri(project.root_uri)
267-
assert Project.project_path(project) == root_path
275+
assert Project.project_path(project) == Paths.to_native_separators(root_path)
268276
end
269277

270278
test "normalizes the project directory", ctx do
271-
subdirectory = "sub_dir/../sub_dir/new/../new/dir"
279+
subdirectory = Path.join(~w(sub_dir .. sub_dir new .. new dir))
272280

273281
patch(File, :exists?, fn path, _ ->
274282
String.ends_with?(path, "mix.exs")
@@ -277,29 +285,41 @@ defmodule ElixirLS.Experimental.ProjectTest do
277285
assert {:ok, %Project{} = project} =
278286
Project.change_project_directory(ctx.project, subdirectory)
279287

280-
assert Project.project_path(project) == "#{File.cwd!()}/sub_dir/new/dir"
288+
assert sub_dir = Path.join([File.cwd!(), "sub_dir", "new", "dir"])
289+
assert Project.project_path(project) == Paths.to_native_separators(sub_dir)
281290
assert project.mix_project?
282-
assert Project.mix_exs_path(project) == "#{File.cwd!()}/sub_dir/new/dir/mix.exs"
291+
292+
assert Project.mix_exs_path(project) ==
293+
sub_dir
294+
|> Path.join("mix.exs")
295+
|> Paths.to_native_separators()
283296
end
284297

285298
test "sets mix project to false if the mix.exs doesn't exist", ctx do
286299
patch(File, :exists?, fn file_name ->
287300
!String.ends_with?(file_name, "mix.exs")
288301
end)
289302

290-
assert {:ok, %Project{} = project} =
291-
Project.change_project_directory(ctx.project, "sub_dir/new/dir")
303+
sub_dir = Path.join(~w(sub_dir new dir))
304+
assert {:ok, %Project{} = project} = Project.change_project_directory(ctx.project, sub_dir)
305+
306+
assert Project.project_path(project) ==
307+
File.cwd!()
308+
|> Path.join(sub_dir)
309+
|> Paths.to_native_separators()
292310

293-
assert Project.project_path(project) == "#{File.cwd!()}/sub_dir/new/dir"
294311
refute project.mix_project?
295312
end
296313

297314
test "asks for a restart if the project directory was set and the new one isn't the same",
298315
ctx do
299-
{:ok, project} = Project.change_project_directory(ctx.project, "sub_dir/foo")
316+
foo_sub_dir = Path.join(~w(sub_dir foo))
317+
{:ok, project} = Project.change_project_directory(ctx.project, foo_sub_dir)
318+
319+
new_dir_sub_dir = Path.join(~w(sub_dir new dir))
300320

301321
assert {:restart, :warning, message} =
302-
Project.change_project_directory(project, "sub_dir/new/dir")
322+
Project.change_project_directory(project, new_dir_sub_dir)
303323

304324
assert message =~ "Project directory change detected"
305325
end
@@ -308,7 +328,8 @@ defmodule ElixirLS.Experimental.ProjectTest do
308328
{:ok, project} = Project.change_project_directory(ctx.project, "sub_dir/foo")
309329

310330
patch(File, :dir?, false)
311-
new_directory = "sub_dir/new/dir"
331+
332+
new_directory = Path.join(~w(sub_dir new dir))
312333
expected_message_directory = Path.join(File.cwd!(), new_directory)
313334

314335
assert {:error, message} = Project.change_project_directory(project, new_directory)
@@ -317,8 +338,9 @@ defmodule ElixirLS.Experimental.ProjectTest do
317338

318339
test "rejects a change if the project directory isn't a subdirectory of the project root",
319340
ctx do
320-
assert {:error, message} =
321-
Project.change_project_directory(ctx.project, "../../../../not-a-subdir")
341+
not_in_project = Path.join(~w(.. .. .. .. not-a-subdir))
342+
343+
assert {:error, message} = Project.change_project_directory(ctx.project, not_in_project)
322344

323345
assert message =~ "is not a subdirectory of"
324346
end

0 commit comments

Comments
 (0)