barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

пятница, 21 февраля 2020 г.

echo и многострочные переменные окружения

Задача

Есть переменная окружения, содержащая текст с несколькими строками. Нужно сделать echo этой переменной так, чтобы не потерялись переводы строк.

Решение

Если делать просто echo $var, переносы строки теряются. А вот если заключить переменную в кавычки:
echo "$var"
,то строки выводятся корректно.

среда, 19 февраля 2020 г.

GitLab CI/CD и Gradle: корректное кэширование и передача результатов запуска между джобами

Кейс

Есть проект, собираемый при помощи Gradle, и CI/CD-пайплайн в GitLab, выполняющий некоторые Gradle-таски на разных stage. Необходимо:

  1. Реализовать кэширование зависимостей, чтобы не выкачивать их заново на каждом stage, а также при каждом новом запуске pipeline
  2. Реализовать кэширование результатов сборки, чтобы последующий stage выполнял не всю сборку "с нуля", а использовал результаты предыдущих stage'й
Решение

Во-первых, настраиваем GRADLE_USER_HOME, чтобы он размещался внутри сборочной директории, и настраиваем кэширование для папки с зависимостями внутри GRADLE_USER_HOME в соответствии с https://docs.gradle.org/6.1.1/userguide/dependency_resolution.html#sec:dependency_cache:
before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle
myjob:
  ...
  cache:
    key: gradle_modules_cache
    paths:
      - .gradle/caches/modules-2
    policy: pull-push
Т.к. это кэш, он будет разделяться не только джобами внутри пайплайна, но и между разными пайплайнами.

Во-вторых, в settings.gradle настраиваем кастомную директорию для билд-кэша (см. https://docs.gradle.org/current/userguide/build_cache.html):
buildCache {
    local {
        directory = new File(rootDir, 'build-cache')
    }
}
и для промежуточных джобов настраиваем публикацию этой директории в качестве артефакта:
  artifacts:
    paths:
      - build-cache/
    expire_in: 1 hour
В последующих джобах прописываем dependencies на предыдущие джобы, чтобы они подхватывали build-cache/ оттуда. Таким образом, build cache будет передаваться между джобами, но не будет передаваться между пайплайнами, что как раз корректно.

Ну и последнее - при вызове gradle используем --build-cache, чтобы собственно включить использования билд-кэша.

Вуаля, в логах сборки видим, что результаты предыдущих джобов подтягиваются из кэша:


вторник, 11 февраля 2020 г.

Windows 10 и несколько мониторов: отображение на таскбаре каждого монитора только находящихся на нем окон

Задача

Есть машина с Windows 10 и несколькими мониторами. Хочется, чтобы на каждом мониторе был таскбар, и на каждом таскбаре отображались иконки только тех окон, которые действительно находятся на этом мониторе.

Решение

Долгие годы для этих целей использовал замечательную программу DisplayFusion, честно купленную на Steam. Но только сегодня выяснил, что подобное поведение можно настроить в Windows "из коробки": идем в Settings -> Taskbat settings и там устанавливаем:

вторник, 4 февраля 2020 г.

Docker Desktop: рассинхронизация времени в контейнерах и у хоста

Проблема

Неожиданно обнаружилось, что все контейнеры, работающие в Docker Desktop, видят время, отстающее от времени хоста аж на 6 с лишним дней.

Решение

Корень проблемы не ясен, но рестарт Docker Desktop помог.