Автоматическое переименование файлов проекта под стандарт PSR-4 через консоль

Есть директория с php-исходниками. Имена поддиректорий — строки вида ‘word1’, ‘word1_word2’. У файлов с классами php имена в формате «class.word1_word2.php». Все это добро надо привести под стандарт PSR-4. Начнем с директорий.

#!/bin/sh
 
dir="./includes"
 
# rename directories
for old in $(find $dir -type d)
do
	new=$(echo $old | sed -e 's/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g')
	mv -v "$old" "$new"
done

Тут все просто. find’ом находим все подпапки и в цикле переименовываем их (используя Sed — потоковый текстовый редактор). Как результат:

Было - models, стало - Models
Было - sub_modules, стало - SubModules

Теперь беремся за файлы:

#!/bin/sh
 
dir="./includes"
 
# rename and update files
for old in $(find $dir -name "*.php") 
do
	new=$(echo $old | sed -e 's/class\.//;s/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g;s/\.Php$/.php/')
	mv -v "$old" "$new"
done

В директории $dir находим все файлы, с расширением php и начинаем их переименовывать. Сначала убираем префикс «class.», потом заменяем подчеркивание на camelCase. В самом конце заменяем Php на php. Отличий от переименования директорий тут нет — все лишь на две замены больше.

Так как PSR-4 подразумевает, что структура директорий совпадает с вложенностью Namespaces, то можно немного подредактировать сами файлы с php-классами:

#!/bin/sh
 
basenamespace="Dota2Api"
toremove="Includes"
dir="./includes"
 
# rename and update files
for old in $(find $dir -name "*.php") 
do
	new=$(echo $old | sed -e 's/class\.//g;s/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g;s/\.Php$/.php/g')
	mv -v "$old" "$new"
 
	namespace=$(dirname "$new" | sed -e 's/\.\///g;s/\//\\\\/g')
	namespace=$(echo "$namespace" | sed -e "s/${toremove}/${basenamespace}/")
	sed -i -e "s/php/php\n\nnamespace ${namespace};\n\n/" "$new"
 
	names=$(cat "$new" | grep '^[((abstract\s)?class)|interface|trait].*{$')
	newnames=$(echo "$names" | sed -e 's/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g;s/Abstract/abstract/;s/Class/class/;s/Extends/extends/;s/Implements/implements/;s/Interface/interface/;s/Trait/trait/')
	sed -i -e "s/${names}/${newnames}/" "$new"
done

Что тут вообще происходит? Первых две строчки в теле цикла — это переименование файлов (описано выше). Дальше, на основе относительного пути до файла, формируется пространство имен. Берется dirname файла, в полученном пути заменяем косые черты на обратные (только для windows). Потом вырезаем не нужный нам фрагмент — имя корневой папки (Includes), которое заменяется на реальное название (Dota2Api). Далее необходимо записать полученный namespace в файл. Используем sed с флагом редактирования файла «на лету» (-i). Пространство имен вставляется в начало файла после <?php. Так же в файле можно заменить имя описанного класса на обновленное. Это делают последние три строчки тела цикла. В первой ищется строка с описанием класса, интерфейса, примеси (пример — «class bla_bla extends bla»). Во второй строке производится замена идентичная переименованию директории. Отличие только в том, что после нее слова Abstract, Class, Extends, Implemets, Interface, Trait переводятся в нижний регистр.

Полностью скрипт выглядит так:

#!/bin/sh
 
basenamespace="Dota2Api"
toremove="Includes"
dir="./includes"
 
# rename directories
for old in $(find $dir -type d)
do
	new=$(echo $old | sed -e 's/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g')
	mv -v "$old" "$new"
done
 
# rename and update files
for old in $(find $dir -name "*.php") 
do
	new=$(echo $old | sed -e 's/class\.//;s/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g;s/\.Php$/.php/')
	mv -v "$old" "$new"
 
	namespace=$(dirname "$new" | sed -e 's/\.\///g;s/\//\\\\/g')
	namespace=$(echo "$namespace" | sed -e "s/${toremove}/${basenamespace}/")
	sed -i -e "s/php/php\n\nnamespace ${namespace};\n\n/" "$new"
 
	names=$(cat "$new" | grep '^[((abstract\s)?class)|interface|trait].*{$')
	newnames=$(echo "$names" | sed -e 's/\b\(.\)/\u\1/g;s/_\(.\)/\U\1/g;s/Abstract/abstract/;s/Class/class/;s/Extends/extends/;s/Implements/implements/;s/Interface/interface/;s/Trait/trait/')
	sed -i -e "s/${names}/${newnames}/" "$new"
done

Запускать его надо находясь в той же директории, что и папка с исходниками, которые обновляются. В самом скрипте необходимо задать свои значения для переменных dir, basenamespace и toremove.

, , ,

Оставить комментарий

Top ↑ | Main page | Back