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

Compile exercises directly with scalac instead of sbt #31

Merged
merged 7 commits into from
May 12, 2022

Conversation

jcranky
Copy link
Contributor

@jcranky jcranky commented May 9, 2022

Improve execution speed by replacing sbt compilation with using scalac directly.

sbt is still used to built the application that converts compilation and test results into exercism's interface format, but it is executed only once, when building the docker image.

sbt, scala and scalatest versions are also updated in some cases, and those should be safe updates.

Finally, one more consequence of this PR is that build.sbt files are not needed for the scala exercises anymore and it should be safe to remove those files, together with their correspondent project folders.

closes #13

@jcranky jcranky requested a review from a team as a code owner May 9, 2022 21:39
Copy link
Member

@ErikSchierboom ErikSchierboom left a comment

Choose a reason for hiding this comment

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

Improve execution speed by replacing sbt compilation with using scalac directly.

This is fabulous! Execution time goes from around 8 seconds to 2.5 seconds.

sbt is still used to built the application that converts compilation and test results into exercism's interface format, but it is executed only once, when building the docker image.

Great

sbt, scala and scalatest versions are also updated in some cases, and those should be safe updates.

👍 We should also update the exercises in the Scala repo to match.

Finally, one more consequence of this PR is that build.sbt files are not needed for the scala exercises anymore and it should be safe to remove those files, together with their correspondent project folders.

You mean for the test exercises? If so, I think I would like them to still be there, to better reflect the actual exercise a test runner would run on.

Comment on lines -16 to -17
sbt test

Copy link
Member

Choose a reason for hiding this comment

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

Could you restore these two lines? These actually run the tests for the Scala test runner project.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sbt assembly in the Dockerfile already run the tests, so this line causes the tests to be run twice when runnning run-tests-in-docker.sh.

I have a more generic question: are run.sh and run-tests.sh supposed to work outside a docker image? If so, both are broken in this PR and I'll investigate. That being said, those files don't seem to work for me outside docker on the main branch as well.

Copy link
Member

Choose a reason for hiding this comment

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

sbt assembly in the Dockerfile already run the tests, so this line causes the tests to be run twice when runnning run-tests-in-docker.sh.

Ah, I would not have guessed that sbt assembly runs the tests too. Then it is fine to omit it here.

I have a more generic question: are run.sh and run-tests.sh supposed to work outside a docker image? If so, both are broken in this PR and I'll investigate. That being said, those files don't seem to work for me outside docker on the main branch as well.

Ehm, not necessarily. For some tracks, they can. I wouldn't be opposed to a PR that makes them work outside the docker image, but only if it can be done in a somewhat sane way :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would say let's leave it as is for now, then 🤐

bin/run.sh Outdated
Comment on lines 40 to 41
# ensure scala binaries are available in the PATH
export PATH="$PATH:/opt/test-runner/scala-2.13.8/bin"
Copy link
Member

Choose a reason for hiding this comment

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

I think it would make sense to have this be set in the Dockerfile using the ENV command. See https://stackoverflow.com/a/38742545/2071395

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, WAY better, thanks. Will change 😄


mv -f "${original_tests_file}" "${tests_file}"
# compile source and tests
scalac -classpath "${test_runner_jar}" -d "${workdir_target}" "${workdir}"/src/main/scala/* "${workdir}"/src/test/scala/* &> "${build_log_file}"
Copy link
Member

Choose a reason for hiding this comment

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

Would this work for exercises that use one or more libraries? E.g. lens-person https://github.com/exercism/scala/blob/main/exercises/practice/lens-person/build.sbt#L8-L9

If it doesn't work, we should do a quick check to see which exercises use libraries and then we can decide what to do (nothing blocking).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those will only work if those libraries are added to the scala-test-runner dependencies, so that they are added to the fat jar built in the Dockerfile with sbt assembly. In other words, we can make it work 😄

Does that work with the current code? Given the fact that the docker images are run with network disabled, I assume not, but maybe I missed some piece of the puzzle.

Copy link
Member

Choose a reason for hiding this comment

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

Those will only work if those libraries are added to the scala-test-runner dependencies, so that they are added to the fat jar built in the Dockerfile with sbt assembly. In other words, we can make it work 😄

Great! I've just ran a little bash command to try and see which libraries are being used, and this is what I found:

"com.github.julien-truffaut" %% "monocle-core" % "2.0.0",
"com.github.julien-truffaut" %% "monocle-macro" % "2.0.0"
"org.scalaz" %% "scalaz-core" % "7.2.28"
"org.scala-lang.modules" %% "scala-parser-combinators" % "2.1.0"
"org.scalacheck" %% "scalacheck" % "1.14.1" % "test"
"org.scalatestplus" %% "scalacheck-1-15" % "3.2.9.0" % "test"

If we could ensure that all these libraries work in the test runner, we should be good for now. Would you be interested in doing a follow-up PR to add this? If so, I'd suggest adding new test cases to the tests dir to verify that they can use these libraries successfully.

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 can do that. Can you point me to the specific tests we need to support? I would like to have a look at the code and also understand why those libraries are needed in the first place 😄

Copy link
Member

Choose a reason for hiding this comment

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

Sure.

monocle-core, monocle-macro and scalaz-core are used in lens-person: https://github.com/exercism/scala/blob/main/exercises/practice/lens-person/build.sbt

scala-parser-combinators is used in alphametics, wordy, forth, matching-brackets and sgf-parsing

scalacheck is used in simple-linked-list

Comment on lines 1 to 3
scalaVersion := "2.12.8"

libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
Copy link
Member

Choose a reason for hiding this comment

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

I'd argue that this file should still be there (albeit updated to version 2.13.6 that exercises in the Scala repo use), as that better reflects the expected files of an exercise.

Copy link
Contributor Author

@jcranky jcranky May 10, 2022

Choose a reason for hiding this comment

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

You mean leaving them there as sort of a piece of documentation? Because other than that, they wouldn't be used.

Copy link
Member

Choose a reason for hiding this comment

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

It is not really documentation, but more like: this is an actual exercise's contents, which matches what the test runner will receive when we run it in production. So it is more about asserting that the test runner works with the actual exercise files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All right, adding those files back 😄

Copy link
Contributor Author

@jcranky jcranky May 11, 2022

Choose a reason for hiding this comment

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

Actually... I see the build.sbt file in there, but not project/build.properties. Did I miss something?

@@ -1 +0,0 @@
sbt.version=1.4.5
Copy link
Member

Choose a reason for hiding this comment

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

See above comment

{"message":"/tmp/exercise/src/test/scala/ExampleEmptyFileTest.scala:7: error: not found: value Leap\n Leap.leapYear(2015) should be (false)\n ^\n/tmp/exercise/src/test/scala/ExampleEmptyFileTest.scala:12: error: not found: value Leap\n Leap.leapYear(1996) should be (true)\n ^\n/tmp/exercise/src/test/scala/ExampleEmptyFileTest.scala:17: error: not found: value Leap\n Leap.leapYear(2100) should be (false)\n ^\n/tmp/exercise/src/test/scala/ExampleEmptyFileTest.scala:22: error: not found: value Leap\n Leap.leapYear(2000) should be (true)\n ^\n4 errors\n","version":2,"status":"error"}
Copy link
Member

Choose a reason for hiding this comment

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

Maybe there could be a post-processing step to change /tmp/exercise to /solution?

Copy link
Contributor Author

@jcranky jcranky May 10, 2022

Choose a reason for hiding this comment

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

Being a bit lazy, would directly creating a /solution folder and working from there inside the docker image also be acceptable? 😸

Copy link
Member

Choose a reason for hiding this comment

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

No, sorry, as the /solution folder is automatically being mapped.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I missed that. Will add the post-processing.

Copy link
Member

@ErikSchierboom ErikSchierboom left a comment

Choose a reason for hiding this comment

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

This is fantastic. I'm gonna merge this and then enable the test runner. This will make the Scala track so much better.
Thank you so much for doing this.


mv -f "${original_tests_file}" "${tests_file}"
# compile source and tests
scalac -classpath "${test_runner_jar}" -d "${workdir_target}" "${workdir}"/src/main/scala/* "${workdir}"/src/test/scala/* &> "${build_log_file}"
Copy link
Member

Choose a reason for hiding this comment

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

Sure.

monocle-core, monocle-macro and scalaz-core are used in lens-person: https://github.com/exercism/scala/blob/main/exercises/practice/lens-person/build.sbt

scala-parser-combinators is used in alphametics, wordy, forth, matching-brackets and sgf-parsing

scalacheck is used in simple-linked-list

@ErikSchierboom
Copy link
Member

@jcranky Ah, the tests are not failing. Could you look into that?

@ErikSchierboom
Copy link
Member

@jcranky I've fixed the issue. Some of the tests were outdated.

I'd like to get this merged. There are two open issues:

  1. Support the libraries mentioned above
  2. I don't much care for the test name grade-school-error. What is the actual error that is being tested by this case?

For both, follow-up PRs would be great.

@ErikSchierboom ErikSchierboom added the x:rep/large Large amount of reputation label May 12, 2022
@ErikSchierboom ErikSchierboom merged commit 06428d8 into exercism:main May 12, 2022
@ErikSchierboom
Copy link
Member

Merged! Thanks. I'll do a follow-up PR to enable the test runner.

@ErikSchierboom
Copy link
Member

@jcranky I've just enabled the test runner, and seems to be working!

@jcranky
Copy link
Contributor Author

jcranky commented May 12, 2022

@jcranky I've fixed the issue. Some of the tests were outdated.

I'd like to get this merged. There are two open issues:

1. Support the libraries mentioned above

2. I don't much care for the test name `grade-school-error`. What is the actual error that is being tested by this case?

For both, follow-up PRs would be great.

I'll work on that 😄

@jcranky jcranky deleted the compile-exercises-without-sbt branch May 12, 2022 16:58
@jcranky
Copy link
Contributor Author

jcranky commented May 12, 2022

@ErikSchierboom I'm actually not sure it is working 😢
At least for the exercises I submitted previously to Exercism, they seem to stay stuck on this:

image

@jcranky
Copy link
Contributor Author

jcranky commented May 14, 2022

Looking a bit more into the issue I'm having, and it might not be related to this PR. Seems like I'm having some CORS issue:

image

Should I report this somewhere else?

@iHiD
Copy link
Member

iHiD commented May 16, 2022

Those CORS issues are when your browser is trying to connect to bugnsag to log a bug with us. So I think there's some issue before that. If you could report whatever the issue you're having is at at exercism/exercism, we'll take a look.

@ErikSchierboom
Copy link
Member

@jcranky Did you update your exercise to the latest version?

@jcranky
Copy link
Contributor Author

jcranky commented May 18, 2022

@iHiD I have no idea what the issue is, I just don't see the code get compile, nor tests run, and get stuck at that screen I shared above.

@ErikSchierboom What does that mean? I didn't change anything, just tried to open the "Tests" tab.

fwiw, this is what I'm doing, step by step:

  1. In Firefox (I tried Chrome, with a similar issue), I open https://exercism.org/tracks/scala/
  2. I click on the Space Age exercise (the problem is actually the same for all exercises)
  3. I already had a solution submitted in the past, so I click on "Your Iterations"
  4. On the right side of the screen, I click on "Tests"
  5. And this is where I get the "We're testing your code to check it works" message, which stays there forever

@ErikSchierboom
Copy link
Member

Do you see something like this when you go to https://exercism.org/tracks/scala/exercises/space-age? If so, could you click on it and update the exercise first?

image

@jcranky
Copy link
Contributor Author

jcranky commented May 19, 2022

Nope:
image

@ErikSchierboom
Copy link
Member

Hmmm, weird. I'll look into it

@ErikSchierboom
Copy link
Member

@jcranky Could you try to click on the "Run tests" in the Online Editor? You need to add a space somewhere to get it enabled.

@jcranky
Copy link
Contributor Author

jcranky commented May 20, 2022

@ErikSchierboom Just tried doing that for a couple of different exercises and I can confirm that running tests from within the online editor works.

@ErikSchierboom
Copy link
Member

@jcranky Ah right, then I know what the issue is. The problem is that the website now thinks that there is a test runner, but there wasn't at the time the solution was submitted. We're not automatically scheduling old solutions. We have a fix in mind, but have not yet gotten around to implementing it.

exercism/exercism#6064 is used to track this.

@jcranky
Copy link
Contributor Author

jcranky commented May 25, 2022

I see, thanks :)
I just submitted a solution to an exercise I didn't complete before, and it worked quite well 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
x:rep/large Large amount of reputation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimize speed
3 participants