Использование Сomposer в Git репозитории

в 9:43, , рубрики: composer, Git, php, метки: ,

Я предлагаю некоторый workflow обновления зависимостей в Git репозитории с помощью Сomposer. Проект основан на Symfony и все зависимости хранятся в папке vendors. Я уверен, что версия зависимостей всегда должна соответствовать версии кода на момент его написания, и обновлять зависимости нужно централизованно, т.к с проектом работают много людей.
Однако, Сomposer подразумевает использование Git submodules, то есть все скачанные зависимости представляют собой Git репозитории, об обновлении которых каждый пользователь должен заботиться самостоятельно.

Преобразовать Git submodules в обычный код помогла команда

find vendors/ -name ".git" -type -d | xarg rm -rf

Однако, при следующем обновлении Сomposer выдает ошибку: Source directory has uncommitted changes.

Сomposer знает, что обновляемый модуль это Git репозиторий, и для проверки изменений использует git status.

protected function enforceCleanDirectory($path)
{
    $command = sprintf('cd %s && git status --porcelain --untracked-files=no', escapeshellarg($path));
    if (0 !== $this->process->execute($command, $output)) {
        throw new RuntimeException('Failed to execute ' . $command . "nn" . $this->process->getErrorOutput());
    }
    if (trim($output)) {
        throw new RuntimeException('Source directory ' . $path . ' has uncommitted changes');
    }
}

Поскольку я удалил все .git папки, мы получаем ответ от репозитория основного проекта, изменения в котором произвел как минимум сам Composer в файле Composer/installed.json.

Я написал простой скрипт, который выполняет 2 команды:

  • создать резервную копию .git папок в архив stash_git.tar и удалить их
    $ ./stash_git.sh
    

  • распаковать и удалить архив
    $ ./stash_git.sh apply
    

Текст скрипта:

#!/bin/bash
backup_git="stash_git.tar"
stash() {
	echo "Stashing....."
	tar -czf $backup_git $git_list
	rm -rf $git_list
}
apply() {
	echo "Applying....."
	tar -xf $backup_git && rm $backup_git
}
if [ "$1" = "apply" ]
then
	if [ -f $backup_git ]
	then
		apply
	else
		echo "Nothing to apply"
	fi
else
	git_list=`find vendor/ -type d -name ".git"`
	if [ "$git_list" ]
	then
		stash
	else
		echo "Nothing to stash."
		exit 0
	fi
fi
exit 1;

Не забудьте пометить скрипт исполняемым

$ chmod +x ./stash_git.sh

Итак, наш workflow:

$ git pull
$ php composer.phar self-update
$ php composer.phar install
$ php composer.phar update
$ ./stash_git.sh 
Stashing.....
$ git add .
$ git commit -am "vendors update"
$ git push

При следующем обновлении

$ ./stash_git.sh apply
Applying.....

Не забудьте stash_git.tar внести в .gitignore

Автор: karser

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js