Ruby, Ruby, Ruby, проекты, проекты, проекты..

Журнал руководящего разработчика
Jan 7

Как мы деплоим проекты (vlad в submodule)

Мы деплоим с помощью vlad-а. Написили git-сабмодуль с настроеным деплоем и подключаем его в каждый проект. Смысл:

  • отсутсвие Vlad-а в основном Gemfile проекта (он часто конфиктует с другими гемами)
  • быстрый запуск деплоя, за счет короткого Gemfile модуля, в нем ведь всего 3 гема подключаются.
  • обычные настройки лежат в проекте, а не раскидываются по форкнутым гемам. Хотя форкнутыйе гем тоже есть - https://github.com/dapi/vlad-unicorn и https://github.com/dapi/vlad-git

Собствено git-сабмодуль: https://github.com/dapi/vlad_deploy

Jan 5

Авторизация битриксовых пользователей на рельсах

https://gist.github.com/1562013 разработчик - Дмитрий Максимов

Jan 5

Принципы хорошего программирования

И на английском и на русском https://github.com/dapi/good_programming

Dec 22

Помощь в рефакторе: глобальная замена строк в проекте

perl -i.bak -p -e 's/UsersController/Users::BaseController/ig' *.rb

Заменит строки по регекспу и сохранит старые файлы с расширением .bak. Так как у нас все файлв и так в git-е, то можно -i.bak заменить на -i

Nov 3

Почему так трудно изменять поведение людей

Не так давно Stanford Persuasive Tech Lab (занимается изучением поведения людей при использовании технологий) опубликовала результаты своего исследования, посвященного выявлению основных причин неудач при попытках людей изменить поведение. Выводы короткие и достаточно универсальные. Думаю, многим будут интересны.

  1. Расчет на силу воли в долгосрочном периоде. (Сила воли – воображаемое и фактически не существующее свойство)
  2. Попытки продвигаться слишком большими шагами. (Лучше стремиться к небольшим последовательным достижениям)
  3. Игнорирование того факта, что окружение влияет на поведение. (Измените окружение – измените жизнь)
  4. Попытки отказаться от старых привычек, вместо того, чтобы приобрести новые.(Фокусируйтесь на действии, а не на отказе от действия)
  5. Возложение ответственности за неудачи на нехватку мотивации. (Решение: Сделайте свое поведение проще для следования ему)
  6. Недооценка силы триггеров (автоматические реакции в ответ на какие-либо события). (В любом поведении есть влияние триггеров)
  7. Вера, что информация приводит к действию. (Мы, люди, не настолько рациональны)
  8. Концентрация на абстрактных целях в большей степени, чем на конкретных результатах.(Абстракция – быть в хорошей физической форме, конкретика – ходить пешком 30 мин. ежедневно)
  9. Попытки изменить поведение навсегда, а не на определенное время. (Конкретный срок работает лучше чем «вечный») 10. Убеждение, что изменение поведения – трудная задача. (Изменить поведение не так трудно, если вы знаете, как это работает)
Oct 21

LESS и SASS

Вчера пол дня потратил на подробное изучение LESS и его отличие от SASS. Во-первых синтаксис SASS мне импонирует больше чем SCSS за его краткость, но большая вложенность это не его конец. В любом случае считаю SASS/SCSS не приниципиальной разницей.

LESS оказался ближе к SCSS чем к SASS. И, в общем, это тоже самое. Отличий не много, но парочка из них принципиально меняют расстановку сил:

1. LESS - может client-side с использованием JS.

Точнее он так и спроектирован, это потом уже к нему прикрутили возможность компиляции на сервере а-ля sass. На первый взгляд какое-то странное свойство. Зачем компилить на стороне клиента, если можно отлично скомпилить на сервере и отдавать уже готовую ужатую CSS? Причина зачем это может понадобится кроется в невзрачных самых послених строках документации.

@height: `document.body.clientHeight`;

Вот такая маленькая одинокая строчка дает возможности о которых только мечтали верстальщики с начала освоения стилей. Вызов из CSS ява-скрипта на стороне клиента и учет фактических параметров браузера при создании стилей. Дальше сами думаейте какие возможности этот открывает.

Нужно ли это вашему проекту это уже вопрос второй. Понятно что все привыкли уже к клиентской неизвестности и верстке в стиле "чтобы более-менее показывалось у всех на всех разрешениях". Но это не повод забывать что теперь такая возможность есть.

2. LESS, в отличии от SASS/SCSS не имеет логики.

В LESS нет if/then, for и т.п. Хотя, учитывая то, что в него легко встраивается JS думаю логику вполне возможно прикрутить. Не пробовал.

3. В LESS проще устроен синтаксис миксинов и есть возможность миксить уже опредленные классы.

Очень понравилось то, что в LESS можно включать в определение свойства уже установленого класса. Собственно класс и является миксином. Это еще одна особенность которой нет в SASS/SCSS. Вы можете включить в LESS обычный CSS файл и использовать его классы для определия своих свойств. Например:

.wrap () {
    text-wrap: wrap;
    white-space: pre-wrap;
    white-space: -moz-pre-wrap;
    word-wrap: break-word;
  }
 pre { .wrap }
Итоги
Лично для меня LESS выглядит более привлекательным из-за своей простоты. Циклы и условия в стилях мне еще никогда не были нужны. Классические утилиты типа "box-shadow, linear-gradient' в LESS есть. Под SASS написано уже множество готовых библиотек (compass, bourbone и т.п.), но под LESS есть тотже Twitter Bootstrap и этого более чем достаточно.
А в общем - на любителя. Но не забывайте про пункт 1 - в этом случае только LESS.

Jun 7

Работа с git

В продолжении этой темы http://dapi.ru/git-branching-tags-git расскажу подробнее как создаются ветки по задачам в нашей команде.

Как показала практика переход на git затруднителен для разработчиков привыкших к subversion (svn), а тот, кто никогда ранее не использовал системы контроля версий осваивается с git-ом за пару дней. Думаю что причина в том, что в svn все действия происходят с удаленным репозиторием, а git никак не привязан у удаленному репу. Сам каталог проекта (с подкаталогом .git в корне) является полноценным репозиторием, с ним и происходит вся работа. При этом на удаленном (тот, что на github) например могут происходить совершенно независимые вещи – ветки переименоваться илди удалиться и ваш локальный репо ничего об этом не будет знать. И не должен. В этом его преимущество – в не зависимости. Да, когда клонируете проект через git clone REPO_NAME git сохраняет в конфиге (.git/config) название склонированного источника и для краткости называет его origin. Это все что вас связывает с удаленным репом. Команды для работы с удаленным репом всего две:

> git pull origin ВЕТКА # влить последние комиты из ветки ВЕТКА репозитория origin в текущую
> git push origin ВЕТКА # затолкнуть последние изменения в текущей ветке в ветку ВЕТКА репозитория origin

На самом деле команда git pull является комбинацией git fetch + git merge но это не столь важно.

0. Настройка git

http://help.github.com/linux-set-up-git/

Также сделайте (ниже написано зачем)

> git config --global push.default current

0.1. Доступа к github

http://help.github.com/set-your-user-name-email-and-github-token/

1. Перед тем как работать с репозиторием убедиться что он чист.

git status должен возвращать что-то типа:

# On branch master
nothing to commit (working directory clean)

Заметьте что мы находимся в ветке (branch) master. Если это не так, нужно в нее перейти:

> git checkout master

Убедимся/Вольем в эту ветку все изменения с сервера (github)

> git pull

Вообще master это ветка с которой начинаются разработка всех задач. В тоже время сами разработчики в master никогда ни чего не заливают (за исключением исключительных ситуаций), а все свои наработки кладут в ветки с понятными названиями вида ИМЯ-НОМЕР_ТИКЕТА-КРАТКОЕ_ОПИСАНИЕ_ТИКЕТА. Например: dapi-123-caching-subcribers. По названию ветки понято, что ее автор dapi и работает он над issue 123, а именно над кешированием подписчиков.

2. Создаем новую ветку: dapi-123-caching-subscribers

> git checkout -b dapi-123-caching-subscribers
Switched to a new branch ' dapi-123-caching-subscribers'

Мы создали новую ветку, которая один в один master.

3. Кодируем.

Кодируем, меняем файлы.

4. Закрепляем изменения.

Когда мы понимаем что, возможно задачу еще до конца не выполнили, но сделали важный участок кода, который уже работает и хотим сохранить свои изменения (на случай чтобы откатиться к ним, при необходимости, позже) делаем так:

> git add ИМЕНА_ФАЙЛОВ

То есть выводим на сцена (другими словами добавляем к текущему комиту) те файлы, изменения в которых хотим запомнить. Ну если хотите запомнить все, пишите:

> git add .

Далее делаем собственно коммит с понятным сообщением (заметьте, это не описание, не название, а именно сообщение другим разработчикам о том что делает этот коммит). Так как мы используем github issues, а они умеют читать ваши commit-messages то в сообщениям мы вставляем информацию помогающую соотносить их с этими issues. например:

> git commit -m "#123 Сделал кеширование"

Где #123 – номер issue. В случае если вы делаете завершающий коммит, сообщение может быть вида “Fix #123” или “Closed #123” (вообще любое из слов close, closes, closed, fixes, fixed) в таком случае issue под номером 123 автоматически закроется. Также вставка номеров задач в коммиты позволяет отображать на странице issues именно тот код, который отвечает за решение определенной задачи. Подробнее о том как github issues читают commit messages тут https://github.com/blog/411-github-issue-tracker

Если это ваши не последние изменния, то вы снова переходите к пункту 3, если последние, то идем дальше.

5. Заливаем изменения на github.

Често говоря это можно делать после каждого комита.

> git push -u

Ключил -u нужен для того чтобы локальная ветка связалась с удаленной ( см .git/config) и при последующем git pull вам не нужно было ее указывать снова.

Конфликт при пушинге означает что вы делаете что-то не то (пушаете не ту ветку не туда)

5.1. Ребейз с master-а

В какой-то момент вы понимаете что ваша ветка далеко убежала от master-а. Да и master уже не тот и появляется желание влить к себе изменения, который в нем произошли. Правильное ощущение, чем чаще его делать тем меньше будет проблем. Делается это так:

> git checkout master
> git pull
> git checkout ВАША)ВЕТКА
> git rebase master

другой вариант:

> git pull --rebase origin master

Ваша рабочая ветка началась с мастера. Место начала называтеся HEAD. При ребейсе вы переносите ваш HEAD на последний комит в master.

Merge conflict

Если в процессе мержинга у вас возник конфликт с которым вы не можете разобраться и хотите вернуть все назад:

> git merge --abort

или

> git reset --hard HEAD

Так же тут хорошие рекомендации на эту тему: http://stackoverflow.com/questions/101752/aborting-a-merge-in-git

Если в результата отката мержинга осталось много untracked files разобраться с ними поможет git clean:

> git clean -f

Лучше сначала запустить ее в сухую с параметром -n чтобы посмотреть что она собирается удалить.

Инфа по очистке http://stackoverflow.com/questions/61212/how-do-you-remove-untracked-files-fr...

6. Задача решена и залита, начинаем решать другую.

Дальше у нас два варианта действий. Или мы начинаем делать новую задачу, для этого снова возвращаемся в master и т.д. все с 1-го пункта. Или вносим изменения в уже существующие задачи (ветки). Тогда вместо мастера берем их. Например нам надо поработать над старой задачей #001 (user authorization)

> git checkout dapi-001-user-authorization

Важное замечание

Господа виндузятники, у вас скорее всего не настроено определение веток по-умолчанию, поэтому вместо

git pull; git push

нужно делать

git pull origin; git push origin

А иногда и указывать конкретную ветку, типа

git pull origin master

Чтобы этого не делать выполните:

> git config --global push.default current

Шпаргалка:

Способ перейти в ветку скачав ее с сервера:

> git checkout -b ВЕТКА origin/ВЕТКА
May 20

С коробля на бал

Army_airborne_soldiers

По статистике, мы нанимаем одного из 10-20 обратившихся кандидатов на должность веб-разработчика. При таком потоке необходимо быстро распознавать подходящие кандидатуры. Разного рода синтетические тесты при отборе сотрудников я не люблю – бессмысленая трата времени. Лучший способ проверить – сразу кинуть в бой. Вот бери тикет No.123 и выполняй. Слишком круто для тебя? Ну выбери, другой, из того что есть. Минимум затрат личного времени, максимум объективности.

Для этого необходимо быстро подключать новобранца к коду проекта. При этом исключая возможность негативного воздействие новичка на весь проект и минимизируя риск утечки информации. Делается это так.

  1. Новобранцу выдается доступ к системе контроля версия (git). Он создает свою ветку проекта и работает только в ней. git (в отличии от svn) позволяет быстро и оперативно работать с различными ветками (бранчами) и каждый работает в своей (ее название совпадает с именем разработчика), мержить только необходимые изменения. Здесь нам на встречу приходит github.com и 25$ за организационный аккаунт не жалко. По окончанию выполнения задачи, новобранец делает обычный pull-request, дальше код просматривает проект-мастер, если его устраивает, то мержит эти изменения с master-веткой проекта. Естественно никаких паролей, кодов и ключей в репозитории не лежит, только программный код. Доступа к серверу тоже нет, деплоит проект (и на тестовый (stage) и на продакшен сервер проект-мастер). Если вы боитесь что новобранец украдет ваш код и запустит такой-же свой проект, то вы заблуждаетесь. Если код простой и его просто запустить – то тут и воровать ничего не надо, его проще переписать заново, а если сложный и большой, то чтобы запустить такой проект нужно больше чем ворованый репозиторий (как минимум база пользователей). Кроме того удачный проект это далеко не код+база..
  2. Девелоперская база. На продакшен-сервере происходит ежедневный бакап базы. На основе бакапа маленький скриптик создает девелоперскую копию базы. Она идентична пордакшену, но в ней затерта вся “чувствительная информация” (пароли, имена, емайлы, хеши и др.). Свежая ежедневная девелоперская база абсолютно безопасна и всегда доступна всем разработчиков на скачивание по определенной ссылке. Таким образом девелопер запускает проект в условиях максимально приближенных к боевым, без риска утечки информации третьим лицам.
  3. Вопросы. У разработчика конечно-же возникают вопросы по проекту. Но, во-первых, на большую из них он может ответить сам посмотрев код проекта. Во-вторых, все переговоры старых разработчиков по проекту проходит по жестко установленным каналам связи с сохраняемой историей переписки. Это может быть bacecamp, но нам достаточно группового чата в skype и обсуждения ввиде комментариев по каждой задаче в тикет-трекере. Подключив новобранца к чату мы отдаем ему доступ ко все информации по проекту, которой обладаем сами. Ну если что-то не понял, спрашивай в том-же чате.

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

Плюсы такой модели:

  • Максимально снижены риски. Никаких доступов на сервера разработчики не получают вообще (исключая github). Если вы всетаки боитесь за свой код, то он наверняка он уже настолько большой, что его пора разбить на отдельные модули и репозитории, тогда можно выдавать каждому разработчику доступ к определенному коду.
  • Высокая скороть подключения и испытания нового разработчика. Никаких HR-овских заморочек. Получили письмо от искателя? Выдали доступ к git-у, ссылку на db, номер задачи и вперед, через день спросили результат и посмотрели в github процесс его разработки.
May 16

Рабочий пример использования gritter_notices

Gritter_notices
Люди начали просить пример использования gritter_notices, вот он http://gritter-notices-example.heroku.com/

Код, как всегда, на github

Mar 31

rspec

В помощь молодым rspec-ерам.

Презентации с исчерпывающей информацией по rspec-у. Их удобно использовать как шпаргалки.

best practices

Чаще пользуйте mock вместо factory_girl

Мы также используем factory_girl, но старайтесь использовать мокинг вместо факторинга.

Во-первых такие тесты выполняются быстрее, а так как полный комплекс можно запускать по несколько раз в час, ждать 1 минуту вместо 10 гораздо приятнее. Во-вторых мокинг подразумевает что вы укажете через stub или should_receive все ожидаемые вызовы, а значит ваш тест будет более понятен как спецификация и более исчерпывающий как тест.

BDD это спецификация, а не тест.

bdd подразумевает что вы сначала напишите спецификацию, а потом будете писать код. Прелесть в том, что эта спецификация является еще и тестом. Писать сначала спек, а потом код важно, потому что таким образом мы сначала задумываемся а что жы мы хотим сделать, какой метод имплементируем сначала, что он будет принимать и что делать с остальными объектами, а потом уже реализовывать это. Такой подход оправдывает затраты на написание спека, так как значительно снижаются затраты на написание кода – он получается более обдуманным.