HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Многие пакеты - это приложения командной строки, еще их называют<a>cli-утилитами</a>. Пользователи по-разному взаимодействуют с ними: запускают команды, передают аргументы и опции, выводят результат. Все взаимодействие происходит интерактивным образом через терминал. Для запуска файлов из командной строки в Composer существует секция bin конфигурационного файла composer.json. Рассмотрим на примере:</p>
1 <p>Многие пакеты - это приложения командной строки, еще их называют<a>cli-утилитами</a>. Пользователи по-разному взаимодействуют с ними: запускают команды, передают аргументы и опции, выводят результат. Все взаимодействие происходит интерактивным образом через терминал. Для запуска файлов из командной строки в Composer существует секция bin конфигурационного файла composer.json. Рассмотрим на примере:</p>
2 <p>Эта запись означает, что при установке пакета в операционной системе будет создан файл с именем php-package. Это не просто файл, а<a>символическая ссылка</a>. Запуск этого файла-ссылки приведет к запуску файла вашего проекта по адресу bin/php-package.</p>
2 <p>Эта запись означает, что при установке пакета в операционной системе будет создан файл с именем php-package. Это не просто файл, а<a>символическая ссылка</a>. Запуск этого файла-ссылки приведет к запуску файла вашего проекта по адресу bin/php-package.</p>
3 <p>Как можно заметить, имя ссылки задается именем файла и совпадает с ним. Также обратите внимание, что ссылок может быть множество - столько, сколько вы сами укажете в секции bin.</p>
3 <p>Как можно заметить, имя ссылки задается именем файла и совпадает с ним. Также обратите внимание, что ссылок может быть множество - столько, сколько вы сами укажете в секции bin.</p>
4 <p>Месторасположение символической ссылки и способ ее запуска из командной строки различаются в зависимости от способа установки пакета:</p>
4 <p>Месторасположение символической ссылки и способ ее запуска из командной строки различаются в зависимости от способа установки пакета:</p>
5 <ul><li>Локального</li>
5 <ul><li>Локального</li>
6 <li>Глобального с командой global - например, composer global vendor/package</li>
6 <li>Глобального с командой global - например, composer global vendor/package</li>
7 </ul><p>Рассмотрим каждый случай отдельно.</p>
7 </ul><p>Рассмотрим каждый случай отдельно.</p>
8 <h2>Глобальная установка: генерация ссылок и запуск исполняемых файлов</h2>
8 <h2>Глобальная установка: генерация ссылок и запуск исполняемых файлов</h2>
9 <p>При глобальной установке пакета Composer создает символические ссылки в каталоге $HOME/.composer/vendor/bin. Другими словами, при создании ссылок в домашнюю директорию пользователя, от имени которого запускалась установка пакета, будет добавлен каталог .composer/vendor/bin со ссылками. Это каталог по умолчанию, но путь к нему нам надо<a>самостоятельно прописать</a>в переменной окружения PATH. После этого мы можем запускать приложение по имени символической ссылки из командной строки, находясь в любой точке файловой системы. Так происходит, потому что при поиске исполняемых файлов командная оболочка ищет их последовательно по всем путям, прописанным в переменной окружения PATH.</p>
9 <p>При глобальной установке пакета Composer создает символические ссылки в каталоге $HOME/.composer/vendor/bin. Другими словами, при создании ссылок в домашнюю директорию пользователя, от имени которого запускалась установка пакета, будет добавлен каталог .composer/vendor/bin со ссылками. Это каталог по умолчанию, но путь к нему нам надо<a>самостоятельно прописать</a>в переменной окружения PATH. После этого мы можем запускать приложение по имени символической ссылки из командной строки, находясь в любой точке файловой системы. Так происходит, потому что при поиске исполняемых файлов командная оболочка ищет их последовательно по всем путям, прописанным в переменной окружения PATH.</p>
10 <p>В зависимости от версии Composer директория по умолчанию может различаться. Кроме того, это значение можно<a>конфигурировать</a>. Чтобы посмотреть, в какую конкретно директорию<strong>composer</strong>складывает ссылки на исполняемые файлы, можно воспользоваться командой composer global config bin-dir --absolute:</p>
10 <p>В зависимости от версии Composer директория по умолчанию может различаться. Кроме того, это значение можно<a>конфигурировать</a>. Чтобы посмотреть, в какую конкретно директорию<strong>composer</strong>складывает ссылки на исполняемые файлы, можно воспользоваться командой composer global config bin-dir --absolute:</p>
11 <p>Посмотреть содержание переменной окружения PATH в вашей системе можно с помощью команды echo:</p>
11 <p>Посмотреть содержание переменной окружения PATH в вашей системе можно с помощью команды echo:</p>
12 <h3>Пример</h3>
12 <h3>Пример</h3>
13 <p>Давайте создадим и опубликуем пакет, который для краткости и наглядности будет очень простым. Этот пакет будет состоять всего из двух исполняемых файлов, запуск которых выведет приветствие и прощание с Хекслетом.</p>
13 <p>Давайте создадим и опубликуем пакет, который для краткости и наглядности будет очень простым. Этот пакет будет состоять всего из двух исполняемых файлов, запуск которых выведет приветствие и прощание с Хекслетом.</p>
14 <p>Структура проекта:</p>
14 <p>Структура проекта:</p>
15 <p>Содержимое исполняемого файла sayHi:</p>
15 <p>Содержимое исполняемого файла sayHi:</p>
16 <p>Содержимое исполняемого файла sayBye:</p>
16 <p>Содержимое исполняемого файла sayBye:</p>
17 <p>Содержимое конфигурационного файла composer.json:</p>
17 <p>Содержимое конфигурационного файла composer.json:</p>
18 <p>Обсудим исполняемые файлы немного подробнее:</p>
18 <p>Обсудим исполняемые файлы немного подробнее:</p>
19 <ol><li>Чтобы запускать файлы из командной строки, пользователь должен иметь<strong>право на выполнение этого файла</strong>(атрибут x)</li>
19 <ol><li>Чтобы запускать файлы из командной строки, пользователь должен иметь<strong>право на выполнение этого файла</strong>(атрибут x)</li>
20 <li>Если исполняемый файл содержит код, то надо указать интерпретатор, который будет исполнять этот код при запуске исполняемого файла. Это делается с помощью<strong><a>шебанга</a></strong>. В примере выше мы указали<strong>php</strong>в качестве интерпретатора, а путь к нему задали с помощью специальной утилиты<strong><a>env</a></strong>. Мы решили не указывать абсолютный путь, потому что в разных системах<strong>php</strong>может находиться по совершенно разным путям</li>
20 <li>Если исполняемый файл содержит код, то надо указать интерпретатор, который будет исполнять этот код при запуске исполняемого файла. Это делается с помощью<strong><a>шебанга</a></strong>. В примере выше мы указали<strong>php</strong>в качестве интерпретатора, а путь к нему задали с помощью специальной утилиты<strong><a>env</a></strong>. Мы решили не указывать абсолютный путь, потому что в разных системах<strong>php</strong>может находиться по совершенно разным путям</li>
21 </ol><p>В итоге, мы подготовили пакет. После публикации он становится доступен для установки под именем hex/small-talk-with-hexlet.</p>
21 </ol><p>В итоге, мы подготовили пакет. После публикации он становится доступен для установки под именем hex/small-talk-with-hexlet.</p>
22 <p>Теперь установим этот пакет в систему глобально. Но сначала убедимся, что никаких символических ссылок в директории не существует:</p>
22 <p>Теперь установим этот пакет в систему глобально. Но сначала убедимся, что никаких символических ссылок в директории не существует:</p>
23 <p>Здесь с помощью фильтра grep мы попытались найти файлы, содержащие в своем имени строчку "say" (как наши ссылки в секции bin). Поиск не дал результатов, потому что до установки пакета таких файлов нет.</p>
23 <p>Здесь с помощью фильтра grep мы попытались найти файлы, содержащие в своем имени строчку "say" (как наши ссылки в секции bin). Поиск не дал результатов, потому что до установки пакета таких файлов нет.</p>
24 <p>Далее глобально устанавливаем пакет в систему:</p>
24 <p>Далее глобально устанавливаем пакет в систему:</p>
25 <p>Теперь воспользуемся grep и снова проверим директорию установки исполняемых файлов:</p>
25 <p>Теперь воспользуемся grep и снова проверим директорию установки исполняемых файлов:</p>
26 <p>Как и ожидалось, в этом каталоге находятся символические ссылки - об этом свидетельствует первый символ l, определяющий тип файла в строке атрибутов файла lrwxrwxrwx. Эти ссылки можно запускать из любой точки файловой системы:</p>
26 <p>Как и ожидалось, в этом каталоге находятся символические ссылки - об этом свидетельствует первый символ l, определяющий тип файла в строке атрибутов файла lrwxrwxrwx. Эти ссылки можно запускать из любой точки файловой системы:</p>
27 <p>Из примера видно, что мы можем успешно запускать одни и те же команды из разных директорий. Причины, по которым это происходит, мы подробно обсуждали выше.</p>
27 <p>Из примера видно, что мы можем успешно запускать одни и те же команды из разных директорий. Причины, по которым это происходит, мы подробно обсуждали выше.</p>
28 <h2>Что происходит при локальной установке</h2>
28 <h2>Что происходит при локальной установке</h2>
29 <p>В подавляющем большинстве случаев разработчики устанавливают пакеты не глобально, а локально. При такой установке пакеты привязываются к конкретному проекту и размещаются внутри его каталога по пути ./vendor/. При этом ссылки на исполняемые файлы устанавливаемых пакетов Composer размещает в каталоге ./vendor/bin.</p>
29 <p>В подавляющем большинстве случаев разработчики устанавливают пакеты не глобально, а локально. При такой установке пакеты привязываются к конкретному проекту и размещаются внутри его каталога по пути ./vendor/. При этом ссылки на исполняемые файлы устанавливаемых пакетов Composer размещает в каталоге ./vendor/bin.</p>
30 <p>Ссылки на исполняемые файлы локально установленных пакетов заточены под использование в скриптах, в секции scripts конфигурационного файла composer.json. Для этого существует особенный синтаксис. Эту тему мы проходили в<a>уроке, посвященном скриптам</a>.</p>
30 <p>Ссылки на исполняемые файлы локально установленных пакетов заточены под использование в скриптах, в секции scripts конфигурационного файла composer.json. Для этого существует особенный синтаксис. Эту тему мы проходили в<a>уроке, посвященном скриптам</a>.</p>
31 <p>Естественно, к символическим ссылкам можно также обратиться напрямую, указав нужный путь. Давайте рассмотрим это на примере, подключив к нашему разрабатываемому проекту small-talk-with-hexlet пакет<a>PHP_CodeSniffer</a>:</p>
31 <p>Естественно, к символическим ссылкам можно также обратиться напрямую, указав нужный путь. Давайте рассмотрим это на примере, подключив к нашему разрабатываемому проекту small-talk-with-hexlet пакет<a>PHP_CodeSniffer</a>:</p>
32 <p>Для примера возьмем команду composer require --dev some_package. Если установить пакет с флагом --dev в корневом каталоге проекта, он автоматически добавится в зависимости проекта, то есть в секцию require-dev файла composer.json. Этой возможностью мы и воспользовались.</p>
32 <p>Для примера возьмем команду composer require --dev some_package. Если установить пакет с флагом --dev в корневом каталоге проекта, он автоматически добавится в зависимости проекта, то есть в секцию require-dev файла composer.json. Этой возможностью мы и воспользовались.</p>
33 <p>Посмотрим, какие новые файлы появились в директории проекта:</p>
33 <p>Посмотрим, какие новые файлы появились в директории проекта:</p>
34 <p>Как и ожидалось, появился каталог ./vendor, в котором лежит код подключенного пакета и других пакетов, от которых он зависит.</p>
34 <p>Как и ожидалось, появился каталог ./vendor, в котором лежит код подключенного пакета и других пакетов, от которых он зависит.</p>
35 <p>Как узнать место, где Composer хранит ссылки на исполняемые файлы локально подключаемых пакетов? Это можно сделать с помощью команды composer config bin-dir.</p>
35 <p>Как узнать место, где Composer хранит ссылки на исполняемые файлы локально подключаемых пакетов? Это можно сделать с помощью команды composer config bin-dir.</p>
36 <p>Обратите внимание, что здесь нет команды global. В нашем случае это каталог ./vendor/bin. Заглянем в него:</p>
36 <p>Обратите внимание, что здесь нет команды global. В нашем случае это каталог ./vendor/bin. Заглянем в него:</p>
37 <p>В коде выше видно, что при установке PHP_CodeSniffer добавилось два исполняемых файла для запуска разных программ. Давайте запустим phpcs. Это<strong>линтер</strong>- утилита, которая проверяет код на соответствие стандартам:</p>
37 <p>В коде выше видно, что при установке PHP_CodeSniffer добавилось два исполняемых файла для запуска разных программ. Давайте запустим phpcs. Это<strong>линтер</strong>- утилита, которая проверяет код на соответствие стандартам:</p>
38 <p>Программа отработала корректно и завершилась молча - без дополнительного вывода отчета об ошибках. Так произошло, потому что в наших файлах не было никаких нарушений<a>оформления кода</a>.</p>
38 <p>Программа отработала корректно и завершилась молча - без дополнительного вывода отчета об ошибках. Так произошло, потому что в наших файлах не было никаких нарушений<a>оформления кода</a>.</p>
39 <p>Затем была попытка запустить исполняемый файл из командной строки только по имени, но она привела к неудаче - bash: phpcs: command not found. Командная оболочка просто не нашла файл - при глобальной установке все было бы по-другому.</p>
39 <p>Затем была попытка запустить исполняемый файл из командной строки только по имени, но она привела к неудаче - bash: phpcs: command not found. Командная оболочка просто не нашла файл - при глобальной установке все было бы по-другому.</p>
40 <h2>Выводы</h2>
40 <h2>Выводы</h2>
41 <p>В этом уроке мы рассмотрели общие принципы и отдельные нюансы работы Composer с исполняемыми файлами проекта. Важно отметить, что эти принципы характерны для большинства других пакетных менеджеров из разных языков - например,<a>менеджера пакетов Node.js</a>в JavaScript. Если в будущем вам придется столкнуться с чем-то подобным, вам будет намного проще.</p>
41 <p>В этом уроке мы рассмотрели общие принципы и отдельные нюансы работы Composer с исполняемыми файлами проекта. Важно отметить, что эти принципы характерны для большинства других пакетных менеджеров из разных языков - например,<a>менеджера пакетов Node.js</a>в JavaScript. Если в будущем вам придется столкнуться с чем-то подобным, вам будет намного проще.</p>
42 <p>Пример глобальной установки пакета:</p>
42 <p>Пример глобальной установки пакета:</p>
43  
43