Для перехода на scala 2.13 я решил обновить сразу все зависимости, это оказалось не сложно, опишу свой опыт тут.

Про догфудинг в опенсорсе: Компилятор rust написан на rust. Компилятор go написан на go. И т.д. А теперь, мой петпроджект, который умеет обновлять зависимости в билд файлах, обновил свои зависимости сам себе.

Пулл реквест с переводом jadd на scala 2.13

Всё обновление свелось к одной команде (на самом деле не совсем так. Плагины sbt обновлял вручную)

jadd show -f jadd-no-versions | jadd install --scala-version 2.13 -r /dev/stdin

diff

Почему у меня часть зависимостей внутри ++= Seq(), а другие добавлены по одной через +=? Это для тестов. Мне важно умееть автоматически обновлять версии зависимостей в обоих случаях.

Что бы проще было понять что делают эти команды, приведу пример для питона

# sed удаляет версии
pip freeze | sed 's/=.*//' | pip install -r /dev/stdin

Печатаем зависимости без версиий и читаем файл requirements из stdin. Если версии нет - берется свежая. Всё просто. pip пояснений не требует, а про jadd расскажу поподробнее.

jadd show смотрит в ваш проект, находит билд файл (build.sbt в моем случае) и печатает зависимости в консоль. -f отвечает за формат вывода. Один из которых - вывод без зависимостей. Команда install дописывает/обновляет зависимости в билд файле. -r это requirements, читается из stdin. В случае, когда install получает артифакт без версии, версия берётся наибольшая. Параметр --scala-version 2.13 указывает для какой версии скалы искать свежие либы, по умолчанию scalaVersion берется из build.sbt

Альтернативный вариант обновления зависимостей в sbt

https://github.com/aiyanbo/sbt-dependency-updates

Этот плагин просто напечатает в консоль список устаревших библиотек, сам подставлять новые версии в build.sbt не будет.

sbt new

Я для себя создал шаблон скала проекта на giter8. Теперь, когда мне нужен новый скала проект я просто печатаю в консоли sbt new d10xa/scala.g8 и проект создается. giter8 позволяет в своих шаблонах использовать плейсхолдер для свежей версии.

# default.properties
scalatest_version=maven(org.scalatest, scalatest_2.13, stable)
# build.sbt
libraryDependencies += "org.scalatest" %% "scalatest" % "$scalatest_version$" % Test

Но к сожалению, если интернет вам доступен только через прокси, такой способ не работает. Команда sbt new повиснет на пару минут и потом напишет, что случился IOException без пояснения.

В шаблоне я указал явные версии зависимостей, которые в любой момент могут устареть. Обновляю их после создания проекта.

jadd show -f jadd-no-versions | jadd i -r /dev/stdin

что мне пришлось менять при переходе на 2.13

  • Самое страшное это отключение coverageReport для coveralls. Потом включу.
  • Отключил правило для wartremover Wart.Any. Он ругался на все F с дырокой которые видел в проекте.
  • .right.get теперь помечен как deprecated. Да, к сожалению я это использовал
  • С переходом на scala 2.13 стало работать правило wartremover, запрещающее implicit conversion toString. Я этому правилу очень рад. Благодаря нему я нашел баг. logger.info(s"SubstituteLoggerFactory used. Can not enable debug mode ${logger.getClass}") getClass возвращает не String -> ошибка компиляции (-Xfatal-warnings)
  • Массивы теперь нужно явно приводить к чему то иммутабельному для передачи в функцию, ожидающую Seq. source.split(‘\n’).toIndexedSeq
  • Замена импорта import scala.collection.JavaConverters._ на import scala.jdk.CollectionConverters._
  • для mapValues на Map, теперь нужно вызывать map.view.mapValues
  • Stream заменен на LazyList
  • StringContext.treatEscapes переименован в StringContext.processEscapes
  • В scalatest org.scalatest.FunSuite deprecated. Замена - org.scalatest.funsuite.AnyFunSuiteLike

Заключение

Переход на scala 2.13 оказался практически безболезненным, за исключением временного отключения coverage report. Библиотеки вручную обновлять ни когда нет желания, а делать это автоматически очень даже приятно. Обновил, запустил sbt test и смотрю на количество ошибок, которые необходимо исправить - красота. Возможно если у jadd появятся пользователи, не считая меня, нужно будет упростить процесс обновления зависимостей до одной команды, например jadd update.

jadd работает не только с sbt, а еще понимает maven и gradle. Пользуйтесь на здоровье.