Slide 1

Slide 1 text

X Никита Соболев github.com/sobolevn 1

Slide 2

Slide 2 text

!2

Slide 3

Slide 3 text

>_ X Как не делать код ревью 3

Slide 4

Slide 4 text

Нет Да Как критиковать? • Критиковать код • Предлагать решение • Критиковать людей • Высказывать претензии 4

Slide 5

Slide 5 text

Нет Да Как критиковать? • Критиковать код • Предлагать решение • Критиковать людей • Высказывать претензии 5

Slide 6

Slide 6 text

Нет Да Как критиковать? • Критиковать код • Предлагать решение • Критиковать людей • Высказывать претензии 6

Slide 7

Slide 7 text

Нет Да Как критиковать? • Критиковать код • Предлагать решение • Критиковать людей • Высказывать претензии 7

Slide 8

Slide 8 text

Нет Да Как критиковать? • Критиковать код • Предлагать решение • Критиковать людей • Высказывать претензии 8

Slide 9

Slide 9 text

Нет Да Как критиковать? • Критиковать код • Предлагать решения • Критиковать людей • Высказывать претензии 9

Slide 10

Slide 10 text

Checklist: 10

Slide 11

Slide 11 text

Checklist: > Удостоверьтесь, что вы строите инклюзивную культуру 10

Slide 12

Slide 12 text

Checklist: > Удостоверьтесь, что вы строите инклюзивную культуру > Слушайте мнения всех людей 10

Slide 13

Slide 13 text

Checklist: > Удостоверьтесь, что вы строите инклюзивную культуру > Слушайте мнения всех людей > Мотивируйте свою команду 10

Slide 14

Slide 14 text

Checklist: > Удостоверьтесь, что вы строите инклюзивную культуру > Слушайте мнения всех людей > Мотивируйте свою команду > Учитесь коммуникации 10

Slide 15

Slide 15 text

Checklist: > Удостоверьтесь, что вы строите инклюзивную культуру > Слушайте мнения всех людей > Мотивируйте свою команду > Учитесь коммуникации > Be empathetic! 10

Slide 16

Slide 16 text

>_ X Стоп! 11

Slide 17

Slide 17 text

Если вы делаете код-ревью, то вы уже проиграли! 12

Slide 18

Slide 18 text

13

Slide 19

Slide 19 text

Любая привычка является "деланием", для функционирования деланию необходимы все его составные части 14

Slide 20

Slide 20 text

Деланье код-ревью 15

Slide 21

Slide 21 text

Неделанье код-ревью 16

Slide 22

Slide 22 text

• Гармония • Созерцание Деланье Неделанье • Рутина • Сложный процесс 17

Slide 23

Slide 23 text

• Гармония • Созерцание Деланье Неделанье • Рутина • Сложный процесс 18

Slide 24

Slide 24 text

• Гармония • Созерцание Деланье Неделанье • Рутина • Сложный процесс 19

Slide 25

Slide 25 text

• Гармония • Созерцание Деланье Неделанье • Рутина • Сложный процесс 20

Slide 26

Slide 26 text

• Гармония • Созерцание Деланье Неделанье • Рутина • Сложный процесс 21

Slide 27

Slide 27 text

Код-ревью за 15 минут или меньше 22

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

github.com/wemake- services/wemake- python-styleguide 24

Slide 30

Slide 30 text

>_ X Почему все плохо? 25

Slide 31

Slide 31 text

26

Slide 32

Slide 32 text

Цели код ревью 27

Slide 33

Slide 33 text

Цели код ревью > Контроль выполнения 27

Slide 34

Slide 34 text

Цели код ревью > Контроль выполнения > Контроль качества кода 27

Slide 35

Slide 35 text

Цели код ревью > Контроль выполнения > Контроль качества кода > Неповторение грабель 27

Slide 36

Slide 36 text

Цели код ревью > Контроль выполнения > Контроль качества кода > Неповторение грабель > Ревью архитектуры 27

Slide 37

Slide 37 text

Цели код ревью > Контроль выполнения > Контроль качества кода > Неповторение грабель > Ревью архитектуры > Ознакомление и обучение 27

Slide 38

Slide 38 text

Цели код ревью > Контроль качества кода > Контроль выполнения > Неповторение грабель > Ревью архитектуры > Ознакомление и обучение 28

Slide 39

Slide 39 text

Правильная цель 29

Slide 40

Slide 40 text

Код-ревью нужно за контролем корректности автоматики Правильная цель 30

Slide 41

Slide 41 text

>_ X Ознакомление и обучение 31

Slide 42

Slide 42 text

Проблемы обучения через код-ревью 32

Slide 43

Slide 43 text

Проблемы обучения через код-ревью > Неважные задачи 32

Slide 44

Slide 44 text

Проблемы обучения через код-ревью > Неважные задачи > Изолированная работа 32

Slide 45

Slide 45 text

Проблемы обучения через код-ревью > Неважные задачи > Изолированная работа > Всем пофиг 32

Slide 46

Slide 46 text

Проблемы обучения через код-ревью > Неважные задачи > Изолированная работа > Всем пофиг > Долго 32

Slide 47

Slide 47 text

Решение: маленькие задачи, онбординг и документация 33

Slide 48

Slide 48 text

Маленькие задачи – быстрая обратная связь 34

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

Онбординг: посмотрим на Open-Source 36

Slide 51

Slide 51 text

Checklist: 37

Slide 52

Slide 52 text

Checklist: > CONTRIBUTING.md 37

Slide 53

Slide 53 text

Checklist: > CONTRIBUTING.md > Developer Docs 37

Slide 54

Slide 54 text

Checklist: > CONTRIBUTING.md > Developer Docs > Architecture Decision Records 37

Slide 55

Slide 55 text

Checklist: > CONTRIBUTING.md > Developer Docs > Architecture Decision Records > Wiki 37

Slide 56

Slide 56 text

Checklist: > CONTRIBUTING.md > Developer Docs > Architecture Decision Records > Wiki > Issue and PR database 37

Slide 57

Slide 57 text

Checklist: > CONTRIBUTING.md > Developer Docs > Architecture Decision Records > Wiki > Issue and PR database > Human-readable tests 37

Slide 58

Slide 58 text

Задача: утром разработчик – вечером код 38

Slide 59

Slide 59 text

Для вдохновления

Slide 60

Slide 60 text

Для вдохновления > Gatsby.js

Slide 61

Slide 61 text

Для вдохновления > Gatsby.js > dev.to

Slide 62

Slide 62 text

Для вдохновления > Gatsby.js > dev.to > wemake-python-styleguide

Slide 63

Slide 63 text

>_ X Ревью архитектуры 40

Slide 64

Slide 64 text

Проблемы ревью архитектуры пост-фактум 41

Slide 65

Slide 65 text

Проблемы ревью архитектуры пост-фактум > Долго ждать 41

Slide 66

Slide 66 text

Проблемы ревью архитектуры пост-фактум > Долго ждать > Долго и дорого переделывать 41

Slide 67

Slide 67 text

Проблемы ревью архитектуры пост-фактум > Долго ждать > Долго и дорого переделывать > Участвует один человек 41

Slide 68

Slide 68 text

Решение: прототипирование и дизайн ревью до 42

Slide 69

Slide 69 text

И автоматизация! 43

Slide 70

Slide 70 text

Слои 44

Slide 71

Slide 71 text

Слои 45

Slide 72

Slide 72 text

[importlinter] root_package = django_project include_external_packages = True [importlinter:contract:layers] name = Layered architecture of our linter type = layers containers = django_project layers = urls views forms models logic 46

Slide 73

Slide 73 text

[importlinter] root_package = django_project include_external_packages = True [importlinter:contract:layers] name = Layered architecture of our linter type = layers containers = django_project layers = urls views forms models logic 47

Slide 74

Slide 74 text

[importlinter] root_package = django_project include_external_packages = True [importlinter:contract:layers] name = Layered architecture of our linter type = layers containers = django_project layers = urls views forms models logic 48

Slide 75

Slide 75 text

[importlinter] root_package = django_project include_external_packages = True [importlinter:contract:layers] name = Layered architecture of our linter type = layers containers = django_project layers = urls views forms models logic 49

Slide 76

Slide 76 text

[importlinter] root_package = django_project include_external_packages = True [importlinter:contract:layers] name = Layered architecture of our linter type = layers containers = django_project layers = urls views forms models logic 50

Slide 77

Slide 77 text

Независимость 51

Slide 78

Slide 78 text

[importlinter:contract:violation-independence] name = Independence contract for violations type = independence modules = django_project.billing_app django_project.auth_app django_project.orders_app django_project.statistics_app 52

Slide 79

Slide 79 text

[importlinter:contract:violation-independence] name = Independence contract for violations type = independence modules = django_project.billing_app django_project.auth_app django_project.orders_app django_project.statistics_app 53

Slide 80

Slide 80 text

[importlinter:contract:violation-independence] name = Independence contract for violations type = independence modules = django_project.billing_app django_project.auth_app django_project.orders_app django_project.statistics_app 54

Slide 81

Slide 81 text

Непротекающие абстракции 55

Slide 82

Slide 82 text

[importlinter:contract:api-restrictions] name = Forbids to import anything from dependencies type = forbidden source_modules = django_project.logic forbidden_modules = # Important direct and indirect dependencies: django rest_framework 56

Slide 83

Slide 83 text

[importlinter:contract:api-restrictions] name = Forbids to import anything from dependencies type = forbidden source_modules = django_project.logic forbidden_modules = # Important direct and indirect dependencies: django rest_framework 57

Slide 84

Slide 84 text

[importlinter:contract:api-restrictions] name = Forbids to import anything from dependencies type = forbidden source_modules = django_project.logic forbidden_modules = # Important direct and indirect dependencies: django rest_framework 58

Slide 85

Slide 85 text

[importlinter:contract:api-restrictions] name = Forbids to import anything from dependencies type = forbidden source_modules = django_project.logic forbidden_modules = # Important direct and indirect dependencies: django rest_framework 59

Slide 86

Slide 86 text

Можно писать свои контракты

Slide 87

Slide 87 text

>_ X Неповторение грабель 61

Slide 88

Slide 88 text

Проблемы повторения грабель 62

Slide 89

Slide 89 text

Проблемы повторения грабель > Вам больно 62

Slide 90

Slide 90 text

Решение: документация, регрессионное тестирование 63

Slide 91

Slide 91 text

sobolevn.me/2019/02/engineering-guide- to-user-stories !64

Slide 92

Slide 92 text

pypi.org/project/pytest-bdd !65

Slide 93

Slide 93 text

def test_regression71(): """ Testing that local variables are counted correctly. Regression test for #74. See: wemake-services/wemake-python-styleguide/issues/74 Regression test for #247 See: wemake-services/wemake-python-styleguide/issues/247 """ assert ... 66

Slide 94

Slide 94 text

И автоматизация! 67

Slide 95

Slide 95 text

!68

Slide 96

Slide 96 text

!69

Slide 97

Slide 97 text

!70

Slide 98

Slide 98 text

Упади, все плохо import { danger, fail } from 'danger' if (danger.github.pr.base.ref !== 'master') { fail('We only accept PRs to `master` branch.') } if (!danger.github.pr.rebaseable) { fail('Looks like your PR cannot be merged, please fix it: reopen or rebase.') } 71

Slide 99

Slide 99 text

Не падай, но скажи import { danger, warn } from 'danger' if (danger.github.pr.body.length < 50) { warn('Please provide a summary, at least 50 chars') } if (!danger.github.pr.body.match(/closes #\d+/i)) { warn('MR does not close any issues. Should close one') } 72

Slide 100

Slide 100 text

!73

Slide 101

Slide 101 text

Все подсветить 74

Slide 102

Slide 102 text

bellybutton 75

Slide 103

Slide 103 text

deprecated_fn() 76

Slide 104

Slide 104 text

!77

Slide 105

Slide 105 text

!78

Slide 106

Slide 106 text

!79

Slide 107

Slide 107 text

!80

Slide 108

Slide 108 text

!80

Slide 109

Slide 109 text

DeprecatedFnCall: description: Please use `new_fn` instead of `deprecated_fn` expr: //Call[func/Name/@id='deprecated_fn'] example: "deprecated_fn(*values)" instead: "new_fn(values)" 81

Slide 110

Slide 110 text

DeprecatedFnCall: description: Please use `new_fn` instead of `deprecated_fn` expr: //Call[func/Name/@id='deprecated_fn'] example: "deprecated_fn(*values)" instead: "new_fn(values)" 82

Slide 111

Slide 111 text

DeprecatedFnCall: description: Please use `new_fn` instead of `deprecated_fn` expr: //Call[func/Name/@id='deprecated_fn'] example: "deprecated_fn(*values)" instead: "new_fn(values)" 83

Slide 112

Slide 112 text

84

Slide 113

Slide 113 text

84

Slide 114

Slide 114 text

!85

Slide 115

Slide 115 text

>_ X Контроль качества 86

Slide 116

Slide 116 text

>_ X Контроль качества 87

Slide 117

Slide 117 text

>_ X Контроль качества 87 Том Круз смеется над теми

Slide 118

Slide 118 text

>_ X Контроль качества 87 Том Круз смеется над теми Кто думает, что может проверять качество кода глазами

Slide 119

Slide 119 text

Проблемы контроля качества 88

Slide 120

Slide 120 text

Проблемы контроля качества > Люди не умеют писать код 88

Slide 121

Slide 121 text

Проблемы контроля качества > Люди не умеют писать код > Сложность накапливается незаметно 88

Slide 122

Slide 122 text

Проблемы контроля качества > Люди не умеют писать код > Сложность накапливается незаметно > Метрики скрыты 88

Slide 123

Slide 123 text

Проблемы контроля качества > Люди не умеют писать код > Сложность накапливается незаметно > Метрики скрыты > Исправлять долго 88

Slide 124

Slide 124 text

Решение: самый жесткий линтер из доступных 89

Slide 125

Slide 125 text

Иногда нужно будет писать свой! 90

Slide 126

Slide 126 text

!91

Slide 127

Slide 127 text

No content

Slide 128

Slide 128 text

Архитектура Код • Не знаем куда писать • Рискуем создать месиво • Сразу не знаем • Overengineering 93

Slide 129

Slide 129 text

Architecture on Demand sobolevn.me/2019/10/complexity-waterfall 94

Slide 130

Slide 130 text

95

Slide 131

Slide 131 text

96

Slide 132

Slide 132 text

Процесс: 97

Slide 133

Slide 133 text

Процесс: > Пишем простые блоки кода 97

Slide 134

Slide 134 text

Процесс: > Пишем простые блоки кода > В какой-то момент сложность переполняется 97

Slide 135

Slide 135 text

Процесс: > Пишем простые блоки кода > В какой-то момент сложность переполняется > Рефакторим 97

Slide 136

Slide 136 text

Автоматизируем все проверки github.com/wemake-services/wemake- python-styleguide 98

Slide 137

Slide 137 text

>_ X Контроль выполнения 99

Slide 138

Slide 138 text

Проблемы контроля выполнения 100

Slide 139

Slide 139 text

Проблемы контроля выполнения > Я не умею запускать код в мозгу 100

Slide 140

Slide 140 text

Проблемы контроля выполнения > Я не умею запускать код в мозгу > Я не знаю, что нужно клиенту 100

Slide 141

Slide 141 text

Проблемы контроля выполнения > Я не умею запускать код в мозгу > Я не знаю, что нужно клиенту > Не все ньюансы понятны из кода 100

Slide 142

Slide 142 text

Решение: BDD и Review Apps 101

Slide 143

Slide 143 text

sobolevn.me/2019/02/engineering-guide- to-user-stories !102

Slide 144

Slide 144 text

pypi.org/project/pytest-bdd !103

Slide 145

Slide 145 text

!104

Slide 146

Slide 146 text

!104

Slide 147

Slide 147 text

!105

Slide 148

Slide 148 text

!106

Slide 149

Slide 149 text

!107

Slide 150

Slide 150 text

>_ X Повторим 108

Slide 151

Slide 151 text

Цели код ревью 109

Slide 152

Slide 152 text

Цели код ревью > Контроль выполнения 109

Slide 153

Slide 153 text

Цели код ревью > Контроль выполнения > Контроль качества кода 109

Slide 154

Slide 154 text

Цели код ревью > Контроль выполнения > Контроль качества кода > Неповторение грабель 109

Slide 155

Slide 155 text

Цели код ревью > Контроль выполнения > Контроль качества кода > Неповторение грабель > Ревью архитектуры 109

Slide 156

Slide 156 text

Цели код ревью > Контроль выполнения > Контроль качества кода > Неповторение грабель > Ревью архитектуры > Ознакомление и обучение 109

Slide 157

Slide 157 text

Цели код ревью > Контроль качества кода > Контроль выполнения > Неповторение грабель > Ревью архитектуры > Ознакомление и обучение 110

Slide 158

Slide 158 text

Код-ревью нужно за контролем корректности автоматики Правильная цель 111

Slide 159

Slide 159 text

Инструменты код ревью 112

Slide 160

Slide 160 text

Инструменты код ревью > Маленькие задачи 112

Slide 161

Slide 161 text

Инструменты код ревью > Маленькие задачи > Review Apps 112

Slide 162

Slide 162 text

Инструменты код ревью > Маленькие задачи > Review Apps > Суровый статический анализ 112

Slide 163

Slide 163 text

Инструменты код ревью > Маленькие задачи > Review Apps > Суровый статический анализ > Строгие архитектурные правила 112

Slide 164

Slide 164 text

Инструменты код ревью > Маленькие задачи > Review Apps > Суровый статический анализ > Строгие архитектурные правила > Глаза человека 112

Slide 165

Slide 165 text

>_ X Нужно ли вообще смотреть в код? 113

Slide 166

Slide 166 text

Да! За контролем корректности автоматики 114

Slide 167

Slide 167 text

И кое-что еще: 115

Slide 168

Slide 168 text

И кое-что еще: > Корректные имена 115

Slide 169

Slide 169 text

И кое-что еще: > Корректные имена > Проверки гипотез 115

Slide 170

Slide 170 text

И кое-что еще: > Корректные имена > Проверки гипотез > Общая адекватность 115

Slide 171

Slide 171 text

Автоматизируйте ваш код-ревью 116

Slide 172

Slide 172 text

Код-ревью за 15 минут или меньше 117

Slide 173

Slide 173 text

Превратите деланье код-ревью в неделанье! 118

Slide 174

Slide 174 text

Что осталось за кадром? 119

Slide 175

Slide 175 text

Что осталось за кадром? > Обучение ревью 119

Slide 176

Slide 176 text

Что осталось за кадром? > Обучение ревью > Двойной ревью: CODEOWNERS vs случайный человек 119

Slide 177

Slide 177 text

Что осталось за кадром? > Обучение ревью > Двойной ревью: CODEOWNERS vs случайный человек > Ревью ревью 119

Slide 178

Slide 178 text

Что осталось за кадром? > Обучение ревью > Двойной ревью: CODEOWNERS vs случайный человек > Ревью ревью > Мотивация 119

Slide 179

Slide 179 text

Что осталось за кадром? > Обучение ревью > Двойной ревью: CODEOWNERS vs случайный человек > Ревью ревью > Мотивация > Аудиты 119

Slide 180

Slide 180 text

Что осталось за кадром? > Обучение ревью > Двойной ревью: CODEOWNERS vs случайный человек > Ревью ревью > Мотивация > Аудиты > Создание маленьких задач 119

Slide 181

Slide 181 text

t.me/ opensource_findings !120

Slide 182

Slide 182 text

Вопросы? github.com/sobolevn sobolevn.me