{"id":319101,"date":"2021-03-05T15:00:17","date_gmt":"2021-03-05T15:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=319101"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=319101","title":{"rendered":"\u041a\u0430\u043a \u0443\u0431\u0435\u0434\u0438\u0442\u044c \u0433\u0435\u0439\u043c-\u0434\u0438\u0437\u0430\u0439\u043d\u0435\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b?"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\u041f\u043e\u043b\u0430\u0433\u0430\u044e, \u043d\u0438 \u0434\u043b\u044f \u043a\u043e\u0433\u043e \u043d\u0435 \u0441\u0435\u043a\u0440\u0435\u0442, \u0447\u0442\u043e \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u0433\u0440 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u043e\u0432, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b. \u0412\u044b\u043f\u0443\u0441\u043a \u0438\u0433\u0440\u044b \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0431\u0435\u0437 \u0445\u0443\u0434\u043e\u0436\u043d\u0438\u043a\u043e\u0432, \u043c\u043e\u0434\u0435\u043b\u043b\u0435\u0440\u043e\u0432, VFX-\u0445\u0443\u0434\u043e\u0436\u043d\u0438\u043a\u043e\u0432, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0433\u0435\u0439\u043c-\u0434\u0438\u0437\u0430\u0439\u043d\u0435\u0440\u043e\u0432. \u041a\u0441\u0442\u0430\u0442\u0438 \u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445. \u041c\u044b \u0438\u0445 \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u0438\u043c, \u043d\u043e \u043e\u043d\u0438 \u0447\u0430\u0441\u0442\u043e \u043b\u043e\u043c\u0430\u044e\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u041d\u0435 \u0442\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0445\u043e\u0442\u044f\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u043e \u0438\u0437-\u0437\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u043e\u043a, \u0438 \u0448\u0430\u043d\u0441 \u043d\u0430\u043a\u043e\u0441\u044f\u0447\u0438\u0442\u044c \u0432\u044b\u0448\u0435. \u0418 \u0432\u0435\u0434\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0448\u0438\u0431\u043e\u043a \u2014 \u044d\u0442\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0438, \u043d\u0435\u0434\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0438\u043b\u0438, \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043b\u0438\u0448\u043d\u044f\u044f \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430. \u0412\u0441\u0451 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0435 \u043e\u0442\u0445\u043e\u0434\u044f \u043e\u0442 \u043a\u0430\u0441\u0441\u044b. \u041d\u043e \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c? \u041f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0440\u0435\u0433\u043b\u0430\u043c\u0435\u043d\u0442\u0435, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u043a\u043e\u043c\u043c\u0438\u0442\u043e\u043c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c %my_folder%\/scripts\/mega_checker? \u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0438 \u2014 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0427\u0435\u043b\u043e\u0432\u0435\u043a \u2014 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u0438 \u0437\u0430\u0431\u044b\u0432\u0447\u0438\u0432\u043e\u0435. \u0410 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0445\u043e\u0447\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u041d\u043e \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u0432\u044b\u0445\u043e\u0434 \u2014 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0431\u0435\u0437 \u0442\u0435\u0441\u0442\u043e\u0432. \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0438 \u0431\u0435\u0437\u043d\u0430\u043a\u0430\u0437\u0430\u043d\u043d\u043e.<\/p>\n<p>  <a href=\"https:\/\/habr.com\/ru\/company\/playrix\/blog\/545726\/\"><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/fb2\/1ae\/28f\/fb21ae28ffb96570035d1668b68c0c95.png\"><\/div>\n<p><\/a><br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/h2>\n<p>  \u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u2014 \u044d\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041c\u044b \u0435\u0451 \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0438 \u0437\u0434\u0435\u0441\u044c. \u041d\u0430\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u043d\u0443\u0436\u0435\u043d \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434 \u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 Ci, \u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435. \u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u043e\u0431\u0449\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0430 \u0435\u0449\u0451 \u043b\u0443\u0447\u0448\u0435 \u2014 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043a\u043e\u043d\u0444\u0435\u0442\u043a\u0430 \u0441\u0440\u0430\u0437\u0443 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c.<\/p>\n<p>  <strong>\u042d\u0442\u0430\u043f \u043f\u0435\u0440\u0432\u044b\u0439 <\/strong>\u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e, \u043d\u043e \u0431\u043e\u043b\u044c\u043d\u043e. \u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 python-\u043a\u043e\u0434\u043e\u043c \u0435\u0449\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0430 \u0432\u043e\u0442 \u0441\u043e \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u043c\u0438 \u0432\u0440\u043e\u0434\u0435 CppCheck, Bloaty, optipng, \u043d\u0430\u0448\u0438\u043c\u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u043a\u043e\u0441\u0442\u044b\u043b\u044f\u043c\u0438-\u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u043c\u0438 \u2014 \u043d\u0435\u0442. \u0414\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0443\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430\u0448\u0438 \u043a\u043e\u043b\u043b\u0435\u0433\u0438 (mac, windows \u0438 linux). \u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0438\u0441\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u0430 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0442\u0435\u0441\u0442\u043e\u0432 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u043f\u0430\u043f\u043a\u0435 \u0441 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430\u043c\u0438.<\/p>\n<pre><code class=\"plaintext\">&lt;CppCheck bin_folder=\u201dutils\/cppcheck\u201d&gt;...&lt;\/CppCheck&gt;<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c:<\/p>\n<ul>\n<li>\u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043b\u0438\u0448\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u043d\u0443\u0436\u043d\u044b \u043d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435.<\/li>\n<li>\u043a\u043e\u0433\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0430\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0442\u043e\u0438\u0442 \u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0443\u0436\u043d\u0430\u044f \u043b\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432 \u043f\u0430\u043f\u043a\u0435.<\/li>\n<li>\u0433\u0434\u0435 \u0431\u0440\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b? \u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435?<\/li>\n<\/ul>\n<p>  <strong>\u042d\u0442\u0430\u043f \u0432\u0442\u043e\u0440\u043e\u0439 <\/strong>\u2014 \u043d\u0430\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432 \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u0445. \u0410 \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u0432\u044b\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0445 \u0432 \u043e\u0434\u043d\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435? \u0418\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0443\u0436\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0449\u0451 \u0438 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f. \u0423 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Nexus Sonatype, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043f\u043e\u0448\u043b\u0438 \u0432 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0439 \u043e\u0442\u0434\u0435\u043b \u0438 \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438\u0441\u044c \u0437\u0430 \u0444\u0430\u0439\u043b\u0438\u043a\u0438. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430:\u00a0<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4b2\/c87\/2e9\/4b2c872e9066958dad6c8cfefcda9e16.png\"><\/div>\n<p>  \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0443\u0436\u0435\u043d \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u043d\u0430\u0435\u0442 \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441, \u0433\u0434\u0435 \u043b\u0435\u0436\u0430\u0442 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0438, \u0443\u043c\u0435\u0435\u0442 \u0438\u0445 \u0441\u043a\u0430\u0447\u0430\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041e\u043f\u0443\u0441\u043a\u0430\u044f \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">def get_tools_info(project_tools_xml, available_tools_xml): \u00a0\u00a0\u00a0\u00a0# Parse available tools at first and feel up dictionary \u00a0\u00a0\u00a0\u00a0root = etree.parse(available_tools_xml).getroot() \u00a0\u00a0\u00a0\u00a0tools = {}  \u00a0\u00a0\u00a0\u00a0# Parse xml and find current installed version ... \u00a0\u00a0\u00a0\u00a0return tools  def update_tool(tool_info: ToolInfo): \u00a0\u00a0\u00a0\u00a0if tool_info.current_version == tool_info.needed_version: \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return \u00a0\u00a0\u00a0\u00a0if tool_info.needed_version not in tool_info.versions: \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0raise RuntimeError(f'Tool &quot;{tool_info.tool_id}&quot; has no version &quot;{tool_info.needed_version}&quot;') \u00a0\u00a0\u00a0\u00a0if os.path.isdir(tool_info.output_folder): \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0shutil.rmtree(tool_info.output_folder) \u00a0\u00a0\u00a0\u00a0g_server_interface.download(tool_id=tool_info.tool_id, version=tool_info.needed_version, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0output_folder=tool_info.output_folder)  def run_tool(tool_info: ToolInfo, tool_args): \u00a0\u00a0\u00a0\u00a0system_name = platform.system().lower() \u00a0\u00a0\u00a0\u00a0tool_bin = tool_info.exe_infos[system_name].executable \u00a0\u00a0\u00a0\u00a0full_path = os.path.join(tool_info.output_folder, tool_bin) \u00a0\u00a0\u00a0\u00a0command = [full_path] + tool_args \u00a0\u00a0\u00a0\u00a0try: \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(f'Run tool: &quot;{tool_info.tool_id}&quot; with commands: &quot;{&quot; &quot;.join(tool_args)}&quot;') \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0output = subprocess.check_output(command) \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(output) \u00a0\u00a0\u00a0\u00a0except Exception as e: \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(f'Fail with: {e}') \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1 \u00a0\u00a0\u00a0\u00a0return 0  def run(project_tools_xml, available_tools_xml, tool_id, tool_args): \u00a0\u00a0\u00a0\u00a0tools = get_tools_info(project_tools_xml=project_tools_xml, available_tools_xml=available_tools_xml) \u00a0\u00a0\u00a0\u00a0update_tool(tools[tool_id]) \u00a0\u00a0\u00a0\u00a0return run_tool(tool_info, tool_args) <\/code><\/pre>\n<\/div><\/div>\n<p>  \u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0444\u0430\u0439\u043b \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0443\u0442\u0438\u043b\u0438\u0442. \u0410\u0434\u0440\u0435\u0441 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0438\u0434\u0451\u043c \u0442\u0443\u0434\u0430 \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432 \u043d\u0430\u043b\u0438\u0447\u0438\u0438. \u041e\u043f\u0443\u0441\u043a\u0430\u044f \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u043f\u0443\u0442\u044c \u043a \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">xml \u00ab\u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435\u00bb<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;?xml version='1.0' encoding='utf-8'?&gt; &lt;Tools&gt; \t&lt;CppCheck&gt; \t\t&lt;windows executable=&quot;cppcheck.exe&quot; \/&gt; \t\t&lt;darwin executable=&quot;cppcheck&quot; \/&gt; \t\t&lt;linux executable=&quot;cppcheck&quot; \/&gt; \t&lt;\/CppCheck&gt; &lt;\/Tools&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0410 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">xml \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\"> &lt;?xml version='1.0' encoding='utf-8'?&gt; &lt;Tools&gt; \t&lt;CppCheck version=&quot;1.89&quot; \/&gt; &lt;\/Tools&gt;<\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u0445\u043e\u0440\u043e\u0448\u043e, \u0438 \u043d\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u0435\u0440\u0435\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u043e\u0440\u043e\u0447\u0438\u0442\u044c\u0441\u044f, \u0441\u0434\u0435\u043b\u0430\u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u0435\u0448. \u0422\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u0441\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0434\u0435\u0448\u0451\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439.<\/p>\n<pre><code class=\"plaintext\">python -m utility_runner --available-source D:\\Playrix\\![habr]\\gd_hooks\\available_source.xml --project-tools D:\\Playrix\\![habr]\\gd_hooks\\project\\project_tools.xml --run-tool CppCheck -- --version <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e:<\/p>\n<ul>\n<li>\u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b, \u0433\u0434\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u0435\u0440\u0441\u0438\u0438 \u0443\u0442\u0438\u043b\u0438\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b<\/li>\n<li>\u0441\u0442\u0430\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0438 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0410 \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0434\u0430 \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043f\u043e\u0438\u0441\u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.<\/li>\n<\/ul>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/87c\/b09\/d3a\/87cb09d3af39267836b96ea529c63ada.png\"><\/div>\n<p>  \u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043c\u044b \u044d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u0434\u043d\u044f\u043b\u0438, \u043d\u043e \u043d\u0430\u0448\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u2014 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0443 \u0413\u0414.<\/p>\n<h2>\u0410 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c-\u0442\u043e \u043a\u0430\u043a?<\/h2>\n<p>  \u0412\u044b \u043a\u043e\u0433\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u043a\u0430\u043a \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u0440\u0443\u0430\u0441\u0441\u0430\u043d\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0434\u0430\u0436\u0435 \u044f\u0438\u0447\u043d\u0438\u0446\u044b? \u0412\u043e\u0442 \u0438 \u043d\u0430\u043c \u0441\u043b\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0433\u0435\u0439\u043c-\u0434\u0438\u0437\u0430\u0439\u043d\u0435\u0440\u0430\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b. \u0415\u0441\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b \u2014 \u0438 \u043e\u043d\u043e \u0431\u043e\u0434\u0440\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f, \u0442\u043e \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0435\u0441\u0442\u044c \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432. \u0422\u043e\u0447\u043d\u0435\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d: \u0445\u0443\u043a\u0438 <i>git<\/i>.<\/p>\n<p>  \u041f\u043e-\u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443, \u0445\u0443\u043a \u2014 \u044d\u0442\u043e bash-\u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 git: \u043f\u0435\u0440\u0435\u0434 pull \u0438\u043b\u0438 push, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u0430, \u0435\u0441\u0442\u044c \u0445\u0443\u043a\u0438 \u0434\u0430\u0436\u0435 \u043d\u0430 git-\u0441\u0435\u0440\u0432\u0435\u0440\u0435.<\/p>\n<p>  \u0418\u0437 \u0432\u0441\u0435\u0433\u043e \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u044f \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0440\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u0430:<\/p>\n<ul>\n<li>pre-commit \u2014 \u043e\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c \u0438 \u0441\u0442\u043e\u0438\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u043b\u0438 \u043a\u043e\u0434 \u0432\u044b\u0445\u043e\u0434\u0430 \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043e\u0442 \u043d\u0443\u043b\u044f, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/li>\n<li>prepare-commit-msg \u2014 \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u0430, \u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041d\u0430\u043c \u043e\u043d \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u043e\u0432 \u0441\u043b\u0438\u044f\u043d\u0438\u044f \u0438\u043b\u0438 rebase.<\/li>\n<li>commit-msg \u2014 \u0432 \u044d\u0442\u043e\u043c \u0445\u0443\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a \u043a\u043e\u043c\u043c\u0438\u0442\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0435 \u0437\u0430\u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0443. \u0415\u0441\u043b\u0438 \u043e\u043d \u0432\u0435\u0440\u043d\u0451\u0442 \u043d\u0435 \u043d\u043e\u043b\u044c, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/li>\n<\/ul>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0445\u0443\u043a \u043d\u0430\u0447\u0430\u043b \u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u0435\u0433\u043e \u043c\u0430\u043b\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u043a\u0430\u043a \u0441\u043a\u0440\u0438\u043f\u0442, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 <strong>.git\/hooks<\/strong>. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f \u2014 \u044d\u043a\u0441\u043f\u043b\u043e\u0439\u0442. \u041c\u044b \u043d\u0435 \u0432\u044b\u0434\u0443\u043c\u044b\u0432\u0430\u043b\u0438 \u0445\u0438\u0442\u0440\u044b\u0445 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439, \u0430 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0434\u0432\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430 (\u0434\u043b\u044f Windows \u0438 Mac), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442 \u0445\u0443\u043a\u0438 \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u043e\u0439\u043d\u044b\u043c \u043a\u043b\u0438\u043a\u043e\u043c. \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0438 \u0442\u0430\u043a\u043e\u0435 \u0443\u0436\u0435 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0443 \u0431\u0435\u0437 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u0441\u0451 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e. \u0418\u043d\u043e\u0433\u0434\u0430 \u0431\u044b\u0432\u0430\u044e\u0442 \u0441\u0431\u043e\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0442\u0438\u043f\u0438\u0447\u043d\u044b \u0438 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0435 \u0433\u0440\u0443\u043f\u043f\u044b.<\/p>\n<p>  <strong>\u041c\u0430\u0433\u0438\u044f \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/strong>. \u041d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u0430\u044f \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043e\u0448\u0438\u0431\u043a\u0430, \u043d\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432\u0440\u043e\u0434\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u043f\u0443\u0442\u044f\u0445, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f git-bash \u043d\u0430 Windows. \u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043c\u044b \u043f\u0438\u0448\u0435\u043c FAQ.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0435\u0434\u0430\u0432\u043d\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439<\/b>                         <\/p>\n<div class=\"spoiler_text\">\u041c\u044b \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0439: \u043d\u0435\u0442 \u043f\u0440\u0430\u0432 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043f\u0430\u043f\u043a\u0443, \u043d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, dns \u043d\u0435 \u0440\u0435\u0437\u043e\u043b\u0432\u0438\u0442\u0441\u044f. \u0410 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e curl \u043d\u0435 \u043f\u0435\u0440\u0435\u0432\u0430\u0440\u0438\u0432\u0430\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u044b <strong>[<\/strong> \u0432 \u043f\u0443\u0442\u0438.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/caf\/60e\/e31\/caf60ee3141940505b4a083bea104d4a.png\"><\/div>\n<\/div><\/div>\n<p>  <strong>\u0422\u043e\u043d\u043a\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c<\/strong>. \u041f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0435 \u0431\u0430\u0433\u0438. \u041c\u044b \u0438\u043b\u0438 \u043f\u043e\u0434\u043f\u0438\u0440\u0430\u0435\u043c \u0438\u0445 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435, \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0443\u043d\u043a\u0442 \u0432 FAQ. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0430\u043f\u043a\u0430 <i>.git\/hooks<\/i> \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u043d\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f. \u0427\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c \u0442\u043e\u0447\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">git rev-parse<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">git rev-parse --git-path hooks <\/code><\/pre>\n<\/div><\/div>\n<p>  \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0432 \u043a\u0430\u043a\u043e\u043c \u0442\u0438\u043f\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u043e\u043d\u0430 \u0432\u0435\u0440\u043d\u0451\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<div class=\"scrollable-table\">\n<table>\n<tr>\n<td>\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/td>\n<td>\n<pre><code class=\"plaintext\">.git\/hooks<\/code><\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td>Worktree<\/td>\n<td>\n<pre><code class=\"plaintext\">%repo_abs%\/.git\/hooks<\/code><\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td>submodule<\/td>\n<td>\n<pre><code class=\"plaintext\">%repo_abs%\/.git\/modules\/hooks<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>  \u0414\u0440\u0443\u0433\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u2014 \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0432\u0435\u0442\u043a\u0430\u043c\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041c\u044b \u043d\u0435 \u043e\u0447\u0438\u0449\u0430\u043b\u0438 \u043f\u0430\u043f\u043a\u0443 <i>.git\/hooks,<\/i> \u0438 \u0442\u0430\u043c \u043c\u043e\u0433\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0430\u0440\u044b\u0435 \u0445\u0443\u043a\u0438. \u041e\u043d\u0438 \u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0438 \u043f\u0430\u0434\u0430\u043b\u0438. \u042d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442 \u043e\u0447\u0438\u0441\u0442\u043a\u0443 <i>.git\/hooks<\/i> \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0445\u0443\u043a\u043e\u0432.<\/p>\n<p>  \u0412\u0441\u0451 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0430 \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u00a0 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u0438 \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u043a\u0430\u043a\u0438\u043c-\u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0445\u0432\u0430\u0442\u0438\u043b\u0438\u0441\u044c \u0443 \u0432\u0441\u0435\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e. \u042d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0441\u043f\u0430\u0441\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0439 \u043f\u0440\u043e\u0441\u0447\u0451\u0442 \u0438 \u043d\u0435 \u0431\u0435\u0433\u0430\u0435\u043c \u0432\u0441\u0435\u043c \u0432 \u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043f\u0440\u043e\u0441\u044c\u0431\u043e\u0439 \u043e\u043f\u044f\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0443\u0431\u0435\u0440-\u0441\u043a\u0440\u0438\u043f\u0442. \u0412\u0441\u044f \u044d\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0441\u043a\u0440\u044b\u0442\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u2014 \u044d\u0442\u043e \u043d\u0435 \u0435\u0433\u043e \u0432\u043e\u0439\u043d\u0430. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0445\u0443\u043a\u0430 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0430\u043c \u0444\u0430\u0439\u043b \u0445\u0443\u043a\u0430 \u2014 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043d\u0435\u0433\u043e \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439. \u041e\u0434\u043d\u043e \u0438\u0437 \u0440\u0435\u0448\u0435\u043d\u0438\u0439:<\/p>\n<ol>\n<li>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u00a0 pre-commit \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u043a\u0440\u043e\u043c\u0435 \u043d\u0435\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e. \u0418 \u0441\u043e\u0437\u0434\u0430\u0442\u044c pre-commit-tmp<\/li>\n<li>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 commit-msg \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b pre-commit \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0448\u0430\u0433\u0435 pre-commit-tmp<\/li>\n<\/ol>\n<p>  \u0412\u043e\u0442, \u0442\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0440\u043e\u0448\u043e: \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0445\u0443\u043a\u0438, \u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f. \u041c\u044b \u0432\u044b\u0434\u043e\u0445\u043d\u0443\u043b\u0438, \u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043f\u0440\u0438\u0441\u043b\u0430\u043b\u0438 \u043d\u0430\u043c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/c5a\/23e\/2eb\/c5a23e2ebcc6a52a8caaef801bd45ed9.png\"><\/div>\n<p>  &lt;spoiler title=\u00ab\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438:&gt;\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 32-\u0431\u0438\u0442\u043d\u044b\u0439 \u043f\u0438\u0442\u043e\u043d \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438; \u043f\u043e\u043d\u044f\u043b\u0438 \u0441\u0432\u043e\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u0443\u0434\u0430\u043b\u0438\u043b\u0438 \u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 64-\u0431\u0438\u0442\u043d\u044b\u0439; pip install \u0432\u0438\u0434\u0438\u0442, \u0447\u0442\u043e \u043f\u0430\u043a\u0435\u0442 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442. \u041d\u043e \u043f\u0430\u043a\u0435\u0442-\u0442\u043e \u0434\u043b\u044f 32-\u0431\u0438\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442.<\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h2>\u041d\u043e \u0432\u0441\u0451 \u0436\u0435, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c?<\/h2>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043c\u043d\u043e\u0433\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0443\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043e \u0442\u043e\u043c, <i>\u043a\u0430\u043a\u0438\u0435 \u043a\u0440\u0443\u0430\u0441\u0441\u0430\u043d\u044b \u0432\u043a\u0443\u0441\u043d\u0435\u0435<\/i>, \u043a\u0430\u043a\u043e\u0439 python \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c. \u041d\u043e \u043c\u044b \u043f\u043e\u043c\u043d\u0438\u043c \u043f\u0440\u043e \u0433\u0435\u0439\u043c-\u0434\u0438\u0437\u0430\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u044f\u0438\u0447\u043d\u0438\u0446\u0443? \u041e\u043d\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b\u0430 \u043f\u043e\u0434\u0433\u043e\u0440\u0435\u0432\u0448\u0435\u0439: \u0442\u043e python \u043d\u0435 \u0442\u043e\u0439 \u0431\u0438\u0442\u043d\u043e\u0441\u0442\u0438, \u0442\u043e 2.7 \u0432\u043c\u0435\u0441\u0442\u043e 3.7. \u0418 \u0432\u0441\u0451 \u044d\u0442\u043e \u043c\u043d\u043e\u0436\u0438\u0442\u0441\u044f \u0435\u0449\u0451 \u0438 \u043d\u0430 \u0434\u0432\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0433\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438: windows \u0438 mac. (\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 Linux \u0443 \u043d\u0430\u0441 \u043b\u0438\u0431\u043e \u0433\u0443\u0440\u0443 \u0438 \u0441\u0430\u043c\u0438 \u0432\u0441\u0451 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b\u0438, \u0442\u0438\u0445\u043e \u043f\u0440\u0438\u0442\u043e\u043f\u044b\u0432\u0430\u044f \u043f\u043e\u0434 \u0437\u0432\u0443\u043a\u0438 \u0431\u0443\u0431\u043d\u0430, \u043b\u0438\u0431\u043e \u0438\u0445 \u043c\u0438\u043d\u043e\u0432\u0430\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.)<\/p>\n<p>  \u041c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0432\u043e\u043f\u0440\u043e\u0441 \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u2014 \u0441\u043e\u0431\u0440\u0430\u043b\u0438 python \u043d\u0443\u0436\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u0431\u0438\u0442\u043d\u043e\u0441\u0442\u0438. \u0410 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u00ab\u043a\u0430\u043a \u043d\u0430\u043c \u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0438 \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438: Nexus! \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u0443 \u043d\u0430\u0441 \u0435\u0449\u0451 \u043d\u0435\u0442 python, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c python-\u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0442\u0438\u043b\u0438\u0442 \u0438\u0437 Nexus.<\/p>\n<p>  \u0418 \u0442\u0443\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 bash! \u041e\u043d \u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u0443\u0436 \u0438 \u0441\u0442\u0440\u0430\u0448\u043d\u044b\u0439, \u0430 \u0434\u0430\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u0432\u044b\u043a\u043d\u0435\u0448\u044c. \u0418 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0435\u0437\u0434\u0435: \u043d\u0430 unix \u0443\u0436\u0435 \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e, \u0430 \u043d\u0430 Windows \u043e\u043d \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <a href=\"https:\/\/git-scm.com\/download\/win\">git-bash<\/a> (\u044d\u0442\u043e \u043d\u0430\u0448\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435). \u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439:<\/p>\n<ol>\n<li>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0432 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e python \u0434\u043b\u044f \u043d\u0443\u0436\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 curl \u2014 \u043e\u043d \u0435\u0441\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0432\u0435\u0437\u0434\u0435 (\u0434\u0430\u0436\u0435 \u0432 <a href=\"https:\/\/devblogs.microsoft.com\/commandline\/windows10v1803\/\">Windows<\/a>).\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u0438\u0442\u043e\u043d<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">mkdir -p &quot;$PYTHON_PRIMARY_DIR&quot; \tcurl &quot;$PYTHON_NEXUS_URL&quot; --output &quot;$PYTHON_PRIMARY_DIR\/ci_python.zip&quot; --insecure || exit 1<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<\/li>\n<li>\u0420\u0430\u0437\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0441\u0441\u044b\u043b\u0430\u044e\u0449\u0435\u0435\u0441\u044f \u043d\u0430 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a. \u041d\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0439\u0442\u0435 \u043d\u0430\u0448\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a: \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u0440\u0438\u0431\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e virtualenv.\n<pre><code class=\"plaintext\">echo &quot;Unzip python...&quot; unzip &quot;$PYTHON_PRIMARY_DIR\/ci_python.zip&quot; -d &quot;$PYTHON_PRIMARY_DIR&quot; &gt; &quot;unzip.log&quot; \trm -f &quot;$PYTHON_PRIMARY_DIR\/ci_python.zip&quot;  \techo &quot;Create virtual environment...&quot; &quot;$PYTHON_EXECUTABLE&quot; -m pip install virtualenv==16.7.9 --disable-pip-version-check --no-warn-script-location<\/code><\/pre>\n<\/li>\n<li>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u044b \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u0437 lib\/*, \u043d\u0443\u0436\u043d\u043e \u0438\u0445 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443. virtualenv \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0435 \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/li>\n<li>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b. \u0422\u0443\u0442 \u043c\u044b \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438\u0441\u044c \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u0447\u0442\u043e \u0443 \u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u0444\u0430\u0439\u043b ci\/required.txt, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <a href=\"https:\/\/pip.pypa.io\/en\/stable\/reference\/pip_install\/#requirements-file-format\">pip<\/a>.<\/li>\n<\/ol>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">OUT_FILE=&quot;$VENV_DIR\/pip_log.txt&quot; &quot;$PYTHON_VENV_EXECUTABLE&quot; -m pip install -r &quot;$REQUIRED_FILE&quot; &gt;&gt; &quot;$OUT_FILE&quot; 2&gt;&amp;1 result=$? if [[ &quot;$result&quot; != &quot;0&quot; ]]; then \tvar2=$(grep ERROR &quot;$OUT_FILE&quot;) \techo &quot;$(tput setaf 3)&quot; &quot;$var2&quot; &quot;$(tput sgr 0)&quot; \techo -e &quot;\\e[1;31m&quot; &quot;Error while installing requirements. More details in: $OUT_FILE&quot; &quot;\\e[0m&quot; \tresult=$ERR_PIP fi exit $result <\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 required.txt<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">pywin32==225;sys_platform == &quot;win32&quot; cryptography==3.0.0 google-api-python-client==1.7.11 <\/code><\/pre>\n<\/div><\/div>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043e\u0431\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438\u043b\u0430\u0433\u0430\u044e\u0442 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u043a\u043e\u043d\u0441\u043e\u043b\u0438, \u0433\u0434\u0435 \u0432\u044b\u0432\u0435\u043b\u0438\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0438. \u0414\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0431\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u0440\u0430\u043d\u0438\u043c \u0432\u044b\u0432\u043e\u0434 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 <i>pip install<\/i>, \u043d\u043e \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043a\u0440\u0430\u0441\u043e\u043a \u0432 \u0436\u0438\u0437\u043d\u044c, \u0432\u044b\u0432\u043e\u0434\u044f \u0446\u0432\u0435\u0442\u043e\u043c \u043e\u0448\u0438\u0431\u043a\u0438 \u0438\u0437 \u043b\u043e\u0433\u0430 \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c. \u0414\u0430 \u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0435\u0442 grep!<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/859\/c95\/92b\/859c9592bf98bc5a0320692e8ebc29bd.png\"><\/div>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435. \u0412\u0435\u0434\u044c \u043c\u044b \u0438 \u0442\u0430\u043a \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a, \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e. \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043f\u043e\u043a, \u0433\u0434\u0435 \u0440\u0430\u0437\u0432\u0451\u0440\u043d\u0443\u0442\u0430 \u043d\u0430\u0448\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0438 \u0440\u0430\u0437\u043d\u044b\u0435. \u041d\u043e! \u0423 virtualenv \u0435\u0441\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 <strong>activate<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u0430\u043a, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <strong>python<\/strong>, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u043e\u043d \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438. \u042d\u0442\u043e \u0438\u0437\u043e\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a.<\/p>\n<p>  \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435: \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f python-\u0441\u043a\u0440\u0438\u043f\u0442, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 python-\u0441\u043a\u0440\u0438\u043f\u0442. \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0435 \u0432\u044b\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u0439 \u2014 \u0442\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f post-build \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0411\u0435\u0437 virtualenv \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0432\u0435\u0437\u0434\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043d\u0430 \u043b\u0435\u0442\u0443 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0443\u0442\u0438, \u0430 \u0441 <strong>activate<\/strong> \u0432\u0435\u0437\u0434\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <i>python<\/i>. \u0422\u043e\u0447\u043d\u0435\u0435 <i>vpython <\/i>\u2014 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0441\u0432\u043e\u044e \u043e\u0431\u0451\u0440\u0442\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u043e\u0431\u043d\u0435\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438 \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438, \u0438 \u0438\u0437 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0412 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0435 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u043b\u0438 \u0443\u0436\u0435 \u0432 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u043d\u0435\u0442, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u0441\u044f \u043b\u0438 \u043d\u0430 TeamCity (\u0433\u0434\u0435 \u0441\u0432\u043e\u0451 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435), \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">vpython.cmd<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">set CUR_DIR=%~dp0 set &quot;REPO_DIR=%CUR_DIR%\\.&quot;  rem VIRTUAL_ENV is the variable from activate.bat and is set automatically rem TEAMCITY - if we are running from agent we need no virtualenv activation if &quot;%VIRTUAL_ENV%&quot;==&quot;&quot; IF &quot;%TEAMCITY%&quot;==&quot;&quot; ( \tset RETURN=if_state \tgoto prepare \t:if_state \tif %ERRORLEVEL% neq 0 ( \t\techo [31m Error while prepare environment. Run ci\\PrepareAll.cmd via command line [0m \t\texit \/b 1 \t) \tcall &quot;%REPO_DIR%\\.venv\\Scripts\\activate.bat&quot; \trem special variable to check if venv activated from this script \tset VENV_FROM_CURRENT=true )  rem Run simple python and forward args to it python %*  SET result=%errorlevel%  if &quot;%VENV_FROM_CURRENT%&quot;==&quot;true&quot; ( \tcall &quot;%REPO_DIR%\\.venv\\Scripts\\deactivate.bat&quot; \tset CI_VENV_RUN= \tset VENV_FROM_CURRENT= )  :eof exit \/b %result%  :prepare setlocal set RUN_FROM_SCRIPT=true call &quot;%REPO_DIR%\\ci\\PrepareEnvironment.cmd&quot; &gt; NUL endlocal goto %RETURN% <\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/26e\/d13\/041\/26ed13041749f10c47a6ef60d9f92aff.png\"><\/div>\n<p>  <\/p>\n<h2>\u0422\u0430\u043d\u0430\u043a\u0430\u043d, \u0438\u043b\u0438 \u043d\u0435 \u043d\u0430\u0434\u043e \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b<\/h2>\n<p>  \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0437\u0430\u0431\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438, \u043d\u043e \u0434\u0430\u0436\u0435 \u043e\u0434\u0438\u043d \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437 \u0432\u0438\u0434\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0442\u0430\u0431\u043b\u0435\u0442\u043a\u0443 \u043e\u0442 \u0437\u0430\u0431\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438. \u041e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0430\u0441\u0442\u0435\u0439.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043d\u0430\u0448\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0430\u0441\u044c, \u043e\u043d\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043a \u043a\u043e\u043c\u043c\u0438\u0442\u0443 \u0438 \u0441\u0442\u0430\u0432\u0438\u0442 \u043c\u0435\u0442\u043a\u0443 \u00ab\u043e\u0434\u043e\u0431\u0440\u0435\u043d\u043e\u00bb. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043a\u0438 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043d\u0435 \u043c\u0443\u0434\u0440\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c [+] \u0438\u043b\u0438 [-] \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f \u043a \u043a\u043e\u043c\u043c\u0438\u0442\u0443.<\/p>\n<p>  \u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043a\u0440\u0443\u0442\u0438\u0442\u0441\u044f \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0438 \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0437\u0430\u0432\u0435\u0442\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0430.\u042d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u041d\u0435\u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u2014 \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0445\u0443\u043a\u0438, \u043d\u0443\u0436\u0435\u043d \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d \u043d\u0430 \u0413\u0438\u0442\u0445\u0430\u0431\u0435, \u0430 \u043f\u043e\u043a\u0443\u043f\u0430\u0442\u044c \u043f\u0440\u0435\u043c\u0438\u0443\u043c \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0444\u0438\u0447\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u041f\u0440\u043e\u0431\u0435\u0436\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u043e\u0432, \u043f\u043e\u0438\u0441\u043a\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b \u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u2014 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0438 \u043d\u0435 \u0442\u0430\u043a \u0434\u043e\u0440\u043e\u0433\u043e.<\/p>\n<p>  \u0414\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b \u0438 \u0441\u0432\u043e\u0438\u043c\u0438 \u0440\u0443\u0447\u043a\u0430\u043c\u0438, \u043d\u043e \u0432\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u043d\u0435 \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0435 \u0441\u0431\u043e\u0440\u043a\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435? \u0410 \u0435\u0441\u043b\u0438 \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0435\u2026 \u0434\u0430-\u0434\u0430, \u0437\u0430 \u0432\u0430\u043c\u0438 \u0443\u0436\u0435 \u0435\u0434\u0435\u0442 \u043b\u044b\u0441\u044b\u0439 \u0438\u0437 Homescapes.<\/p>\n<h2>\u041a\u0430\u043a\u043e\u0432 \u0438\u0442\u043e\u0433<\/h2>\n<p>  \u041e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0448\u0438\u0431\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0448\u043b\u0438 \u0445\u0443\u043a\u0438, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u2014 \u043e\u043d\u0438 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0415\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043c\u043d\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0437\u0435\u043b\u0451\u043d\u044b\u0445 \u0441\u0431\u043e\u0440\u043e\u043a \u0441\u0442\u0430\u043b\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u0442\u044c \u0438 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u2014 \u043a\u043e\u043c\u043c\u0438\u0442 \u0441\u0442\u0430\u043b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e 10 \u043c\u0438\u043d\u0443\u0442, \u043d\u043e \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043f\u0440\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e.<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/playrix\/blog\/545726\/\"> https:\/\/habr.com\/ru\/company\/playrix\/blog\/545726\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\u041f\u043e\u043b\u0430\u0433\u0430\u044e, \u043d\u0438 \u0434\u043b\u044f \u043a\u043e\u0433\u043e \u043d\u0435 \u0441\u0435\u043a\u0440\u0435\u0442, \u0447\u0442\u043e \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u0433\u0440 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u043e\u0432, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b. \u0412\u044b\u043f\u0443\u0441\u043a \u0438\u0433\u0440\u044b \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0431\u0435\u0437 \u0445\u0443\u0434\u043e\u0436\u043d\u0438\u043a\u043e\u0432, \u043c\u043e\u0434\u0435\u043b\u043b\u0435\u0440\u043e\u0432, VFX-\u0445\u0443\u0434\u043e\u0436\u043d\u0438\u043a\u043e\u0432, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0433\u0435\u0439\u043c-\u0434\u0438\u0437\u0430\u0439\u043d\u0435\u0440\u043e\u0432. \u041a\u0441\u0442\u0430\u0442\u0438 \u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445. \u041c\u044b \u0438\u0445 \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u0438\u043c, \u043d\u043e \u043e\u043d\u0438 \u0447\u0430\u0441\u0442\u043e \u043b\u043e\u043c\u0430\u044e\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u041d\u0435 \u0442\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0445\u043e\u0442\u044f\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u043e \u0438\u0437-\u0437\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u043e\u043a, \u0438 \u0448\u0430\u043d\u0441 \u043d\u0430\u043a\u043e\u0441\u044f\u0447\u0438\u0442\u044c \u0432\u044b\u0448\u0435. \u0418 \u0432\u0435\u0434\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0448\u0438\u0431\u043e\u043a \u2014 \u044d\u0442\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0438, \u043d\u0435\u0434\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0438\u043b\u0438, \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043b\u0438\u0448\u043d\u044f\u044f \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430. \u0412\u0441\u0451 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0435 \u043e\u0442\u0445\u043e\u0434\u044f \u043e\u0442 \u043a\u0430\u0441\u0441\u044b. \u041d\u043e \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c? \u041f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0440\u0435\u0433\u043b\u0430\u043c\u0435\u043d\u0442\u0435, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u043a\u043e\u043c\u043c\u0438\u0442\u043e\u043c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c %my_folder%\/scripts\/mega_checker? \u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0438 \u2014 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0427\u0435\u043b\u043e\u0432\u0435\u043a \u2014 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u0438 \u0437\u0430\u0431\u044b\u0432\u0447\u0438\u0432\u043e\u0435. \u0410 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0445\u043e\u0447\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u041d\u043e \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u0432\u044b\u0445\u043e\u0434 \u2014 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0431\u0435\u0437 \u0442\u0435\u0441\u0442\u043e\u0432. \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0438 \u0431\u0435\u0437\u043d\u0430\u043a\u0430\u0437\u0430\u043d\u043d\u043e.<\/p>\n<p>  <a href=\"https:\/\/habr.com\/ru\/company\/playrix\/blog\/545726\/\"><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/fb2\/1ae\/28f\/fb21ae28ffb96570035d1668b68c0c95.png\"><\/div>\n<p><\/a>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-319101","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=319101"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319101\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=319101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=319101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=319101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}