Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow reading multiple file solutions and exemploids #298

Merged
merged 13 commits into from
Jun 12, 2022

Conversation

jiegillet
Copy link
Contributor

Closes #276.

The analyzer can now accept multiple file exemploids (as long as they are listed in the config file) and multiple file solutions (even if they are not mentioned in the config file).
This gives more freedom to exercise builders, but also allows students to structure their solution as they please (especially CLI users) while still benefiting from the analyzer advice.

The compiler warning module has been changed to handle multiple file compilation.

@jiegillet jiegillet added x:module/analyzer Work on Analyzers x:size/large Large amount of work labels Jun 7, 2022
@@ -0,0 +1,5 @@
defmodule SquareRoot.Cheating do
def calculate(n) do
Float.pow(n / 1, 0.5) |> floor()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worked straight away, which I was quite happy about.

fn path, {:ok, code} ->
case File.read(path) do
{:ok, file} when is_nil(code) -> {:cont, {:ok, file}}
{:ok, file} -> {:cont, {:ok, code <> "\n" <> file}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line brings the coverage down a bit, I can't test it because we don't have a multiple file exemploid.

Copy link
Member

@angelikatyborska angelikatyborska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few nitpicks about code style, but the functionality works as expected 🎉. Great addition!

end

exemploid_path =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The singular variable names confuse me now... may I suggest renaming?

  • solution_path -> solution_files
  • editor_path -> editor_files
  • exemploid_path- > exemploid_files
  • code_path -> all_compiled_files or all_analyzable_files or all_files_for_analysis? "code" is very vague 🤔 (I know, you didn't choose this name initially)

Maybe the keys in the Source struct should be renamed too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I got lazy there :D
I left code_string and code_ast in Source as they are, still vague but not really confusing in context.

lib/elixir_analyzer.ex Outdated Show resolved Hide resolved
Comment on lines 172 to 175
params.path
|> Path.join("lib")
|> ls_r()
|> Enum.filter(&String.ends_with?(&1, ".ex"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially read ls_r as "list files right" and didn't get it for a while... maybe the function could be named ls_recursive?

On the other hand, I wonder if this function can be replaced by:

Path.join([params.path, "lib", "**", "*.ex"]) |> Path.wildcard()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's nice!

Comment on lines +274 to +278
{:ok, nil},
fn path, {:ok, code} ->
case File.read(path) do
{:ok, file} when is_nil(code) -> {:cont, {:ok, file}}
{:ok, file} -> {:cont, {:ok, code <> "\n" <> file}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that the case is_nil(code) is only there because of the first iteration and initial value of the accumulator. What if we did something like this, appending new lines instead of prepending? We would end up with one extra newline at the very end, but it shouldn't matter, right? (suggested code not tested)

Suggested change
{:ok, nil},
fn path, {:ok, code} ->
case File.read(path) do
{:ok, file} when is_nil(code) -> {:cont, {:ok, file}}
{:ok, file} -> {:cont, {:ok, code <> "\n" <> file}}
{:ok, ""},
fn path, {:ok, code} ->
case File.read(path) do
{:ok, file} -> {:cont, {:ok, code <> file <> "\n"}}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It almost doesn't matter, but in some unlikely cases it makes a line in an error message off-by-one (see CI fail before reverted commit). Line number kind of loses meaning when you have multiple files, but after reflection, I'd still like to keep the nil.

Copy link
Contributor Author

@jiegillet jiegillet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review, I'm excited about this feature!

It's interesting how every little tiny change breaks a test in a ~99% coverage codebase. It's annoying for changes in error messages, but it makes refactoring much safer.

Comment on lines 172 to 175
params.path
|> Path.join("lib")
|> ls_r()
|> Enum.filter(&String.ends_with?(&1, ".ex"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's nice!

end

exemploid_path =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I got lazy there :D
I left code_string and code_ast in Source as they are, still vague but not really confusing in context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
x:module/analyzer Work on Analyzers x:size/large Large amount of work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TakeANumberDeluxe always returns compliation warnings about unknown module State
2 participants