Подписка на блог

Ещё есть Тумблер и ЖЖ.

В  Телеграме пишу обо всяком и собираю по крупицам годноту, которая потом появляется в блоге.

А в  Твиттере иногда репощу всякие смехуечки и пишу о том, как всё плохо.

Все остальные соцсеточки только для того, чтобы пошарить ссылку на новый пост.

Игорь Адаменко

Годнота — 26

Сегодня про техасский английский, структуры данных, Толкина и советский научпоп.

Статьи

Видео

Однажды в Википедии

  • Хет-трик.
    Вдруг вы тоже не знаете, почему он так называется.

Кино

  • Скрюченный домишко.
    Если не читали этот рассказ Агаты Кристи, то можно посмотреть. Единственное «но» — сюжет развивается слишком быстро, и можно не успеть распробовать. Но это не делает фильм менее интересным.

Интересное из Телеграма



Прошлые подборки по тегу — годнота. А собираю я их в Телеграме.

lint-staged + JetBrains IDE

OK, we need some English here.

When you use lint-tools like ESLint or Stylelint you also want to get auto-fix of small mistakes like spaces, new lines, case, etc. And you usually need to do it before commit.

There is an awesome tool for this — lint-staged. It can run linters on git staged files. But it’s completely useless for JetBrains IDEs like WebStorm, PhpStorm, etc, because they don’t use ’staged’ in git. The IDEs manipulate staged parts by themselves. There is a ticket in JetBrains YouTrack, but these guys haven’t fixed it yet. And it looks like they don’t want to fix it at all.

I voted for this bug half of year ago because I couldn’t run lint-staged (they also have an issue about it). After that, I have been receiving mail from YouTrack every week, and I feel that I need to write about a solution that I found.

How to do black magic

Disclaimer: this solution is a dirty workaround that you don’t want to see in your repo, but it’s only one way that I can offer you.

First of all, create an example project in your IDE with npm and linters that you need. Then install pre-commit-hook plugin in your IDE. And now you need to add some bash-magic.

Create a folder ’lint’ and add files js and scss there:

js:

#!/usr/bin/env bash

set -o errexit

fix=$([ -z $1 ] && echo '' || echo '--fix')
files=${1:-"example"}

eslint $fix --cache -c .eslintrc.json --ext .js $files

scss:

#!/usr/bin/env bash

set -o errexit

fix=$([ -z $1 ] && echo '' || echo '--fix')
files=${1:-"example/**/*.scss"}

stylelint $fix "$files" --syntax scss --cache --config .stylelintrc.json

Here you see two interesting parts. First, a dynamic key fix that we set only when there are some files passed as the first argument. We need it because sometimes we want just lint, without fixing (e. g. on CI).

Second, a dynamic value of files. We also set it only when we have them as the first argument. Otherwise we lint all files.

Now create another one file in ’lint’ folder — each-file:

#!/usr/bin/env bash

set -o errexit

function getGlob {
  # linters want to get glob instead of just a list of files
  local IFS=",";

  if [ "$#" -gt 1 ]; then
    echo "{$*}"
  else
    echo "$*"
  fi
}

scssFiles=()
jsFiles=()
isError=0

for file in "$@"; do
  # skip removed files
  if [ ! -f "$file" ]; then
    continue
  fi

  if [[ "$file" =~ .*$(pwd)\/example\/.*\.js ]]; then
    jsFiles+=("$file")
  elif [[ "$file" =~ .*$(pwd)\/example\/.*\.scss ]]; then
    scssFiles+=("$file")
  fi
done

if [ -n "$scssFiles" ]; then
  ./lint/scss $(getGlob "${scssFiles[@]}") || isError=$?
fi

if [ -n "$jsFiles" ]; then
  ./lint/js $(getGlob "${jsFiles[@]}") || isError=$?
fi

exit $isError

This uber-file runs linters for passed files (and do some magic for creating globs, but nevermind).

Now we need to create a file for pre-commit-hook that we installed before. Let’s call it pre-commit-hook.sh and save into ’lint’ folder:

#!/usr/bin/env bash

export PATH=./node_modules/.bin:/usr/local/bin:$PATH

./lint/each-file "$@"

It’s pretty simple and just passes all arguments to each-file.

And now the final step. We need to install lint-staged and husky, and write some npm scripts. Install them and add this to your package.json:

"scripts": {
  "lint": "[[ -f 'pre-commit-hook.sh' ]] || lint-staged",
  "lint-js": "bash ./lint/js",
  "lint-scss": "bash ./lint/scss",
  "precommit": "npm run lint"
},
"lint-staged": {
  "*": ["bash ./lint/each-file", "git add"]
}

And this to your .gitignore:

# Pre-commit hook
pre-commit-hook.sh

Now your project is ready to work with linters and lint-staged. If you or someone from your team uses any JetBrains IDE — just copy-paste pre-commit-hook.sh from ’lint’ folder to project root locally and IDE will run pre-commit-hook plugin for each commit.

So, if you commits using JetBrains IDE, pre-commit-hook plugin will run linters for changed files (because it will get only them from IDE). If somebody commits using CLI, lint-staged will run linters for staged files.

Examples

Let’s imagine that we have folder ’example’ with two files: example-1.scss and example-2.scss with this code (we use two files instead of one only for checking that linter works fine with both):

// try to commit this file with lint mistakes that can be fixed by Stylelint

.example {
  color: #F00;
}

Stylelint must fix uppercase of color and replace ’#F00’ to ’#f00’ if everything works fine.

Now, we have two ways how to test it.

You use JetBrains IDE

Copy file pre-commit-hook.sh from ’lint’ folder to project root. Then try to commit file using IDE:

Note: option ’Run Git hooks’ must be checked.

Press ’Commit’ and let the plugin work:

After that let’s check committed files:

The color was fixed!

You use console or any other tool for git

Note: you must remove pre-commit-hook.sh from project root if it’s there.

Just add files to stage and commit them as usual:

And now let’s check that changes are here and files have been committed with them:

It works.

Conclusion

I hope that someday JetBrains will fix it and we can throw off all of this horrible code away. But today it works so, and I’ve created a repo with a template and some examples. Check this out, it must be more useful than this article:

github.com/igoradamenko/lint-staged-jetbrains-ide-example

It’s my first article in English, so if you see some mistakes, please drop me a line about them.

16 февраля   jetbrains   lint-staged   precommit   webstorm   workarounds

Недиван

Людвиг запускает крутую рассылку о дизайне себя. Всё как я люблю.

Пишу об этом здесь, потому что помогал ему с запуском, писал роботов для работы с сервисом подписки и системой оплаты, помогал с вёрсткой писем и страниц с описанием. Так что айда заценить, как всё круто получилось:

ldwg.ru/nedivan/

14 февраля   людвиг

npm.plugin.zsh v1.1

Обновил свой плагин для zsh, который добавляет кучу разных сокращений для npm, о котором я когда-то рассказывал.

Теперь он при запуске nrsh! удаляет не только npm-shrinkwrap.json, но и package-lock.json. Давно пора было это допилить, но я чего-то медлил.

Помимо этого добавились ещё два сочетания:

  • nrpl! делает то же самое, что и nrsh!, а нужен потому, что возможно уже сейчас есть те, кто не знают, что npm-shrinkwrap.json существовал;
  • ns для npm search.

О том, как обновить (или установить, если вы вдруг почему-то ещё не) написано в репозитории.

13 февраля   npm   zsh   гитхаб

Про логирование времени работы над задачей

Когда работаешь удалённо сложно оценивать время своей работы. У ребят в офисе с этим проблем никаких нет. Они пришли в девять, ушли в пять. Значит восемь часов поработали. А когда ты сидишь дома или ходишь по кафе и коворкингам, относишься к этому по-другому, и потому легко попасть в огромную яму переработок из-за неправильного логирования.

Раньше я рассуждал просто. Моя работа заключается в том, чтобы писать код. Значит, когда я пишу код, я работаю. Получается, что мне нужно логировать время написания кода. После месяца таких логирований возникал вопрос: почему по цифрам получается, что вместо 40 часов в неделю я работал 25-30?

Первый же вывод, к которому легче всего прийти, — я весь месяц работал меньше положенного. Значит следующий месяц надо работать более активно! Но после месяца такой «активной» работы получалось, что работа-то сделана, а с самочувствием что-то явно не так. А ещё все лампочки горят красным, и работа как-то всё медленнее и медленнее работается.

Читателю со стороны, конечно, очевидно, что дело в неправильном логировании. Но если подходить к работе ответственно, самостоятельно в это сложно поверить. Ведь ты по-честному логируешь время, которое потратил на задачу, и по ощущениям ты не можешь потратить на неё больше. «Но у других ведь получается?»

За ответом можно сходить в храм под названием «Наука». Вот что рассказывает Барбара Окли в первом же видео курса Learning How to Learn (в недавней годноте была ссылка на конспект курса):

Что вы делаете, когда не получается до чего-то «додуматься»? Для зомби всё просто: они просто продолжают биться головой о стену. Но живой мозг куда сложнее. Однако, если вы поймёте хотя бы основы того, как он работает, то сможете учиться с большей лёгкостью и с меньшим разочарованием.

Исследователи выяснили, что у нас есть два абсолютно разных «режима мышления». Назовём их сфокусированный и расслабленный.

Все знакомы со сфокусированным режимом. Это когда мы концентрируемся на чём-то, что пытаемся выучить или понять. Но мало кто знает, в чём суть расслабленного режима.

Используем аналогию с пинболом, чтобы разобраться.

Если вы помните, пинбол работает так: вы оттягиваете поршень, затем отпускаете его, он бьёт по шарику, и тот движется внутри автомата, сталкиваясь с резиновыми препятствиями и тем самым накапливая вам очки. Это похоже на то, как работает мозг. В сфокусированном режиме резиновые препятствия стоят очень близко друг к другу, и шарик может двигаться по одной и той же «тропинке», безрезультатно пытаясь вырваться за пределы. А за пределами этих препятствий (может даже совсем в другом углу «автомата») вполне может быть «правильная тропинка», которая приведёт вас к решению текущей задачи. И что же делать в таком случае?

Чтобы добраться до этой «правильной тропинки» вам нужен иной способ мышления — расслабленный. В нём препятствия стоят на большем расстоянии друг от друга, и потому шарик может спокойно двигаться от одного к другому, затрагивая максимально возможное количество оных, и таким образом создавая новые нейронные связи, которых так не хватало в сфокусированном режиме.

Важно понимать, что вы не можете находиться в обоих режимах сразу. Это как монета, которая может быть повёрнута к вам только одной стороной: или сфокусированной, или расслабленной.

Это был мой вольный перевод-пересказ первой лекции, которая доступна без подписки на курс. Лучше посмотрите оригинал, если понимаете английский.

Вернёмся к проблеме. Скорее всего вы тоже часто замечали за собой, что решения творческих задач часто приходят в тот момент, когда вы максимально расслаблены: лежите в ванной, стоите у окна с кружкой чая, сидите в кресле с котом, гуляете вечером на улице. Я обожаю эти моменты, и всегда удивляюсь тому, насколько мозг круто работает. Но это какие-то особенно пиковые состояния, во время которых приходят самые светлые и гениальные идеи. На деле же есть ещё сотни микро-состояний расслабленности, когда вы просто отвлекаетесь от текущей проблемы и идёте заваривать чай, нарезать бутерброды, открывать окно, заказывать очередной кофе у бариста. Или когда просто пару минут залипаете куда-то в стену, потому что внезапно отвели глаза от экрана и «потерялись».

Получается, что учитывая время работы, стоит не забывать и о времени отдыха, потому что это и есть то самое расслабленное состояние, в котором рождаются новые идеи. Если вернуться назад и вспомнить о ребятах из офиса, то они редко сидят на месте по паре часов (как это часто бывает, когда вокруг никого), а постоянно куда-то ходят, с кем-то общаются, обсуждают не относящиеся к работе темы и так далее.

Если вы не забываете о том, что работа — это не только активная часть, но и пассивная (отдых), то скорее всего вам не понадобится часто перезагружаться, и в следующий раз при оценке задач вы не будете думать, что если у вас есть 8 рабочих часов, то это время для непрерывной работы, в которой нет места отдыху.

Нужно логировать всё, что помогает решить задачу. В том числе и отдых.

Ctrl + ↓ Ранее