Composer 2 منتشر شد

پس از مدت ها بالاخره نسخه دوم Composer منتشر شد که تغییرات و بهبود های مناسبی هم داشته. در این پست به بررسی این نسخه پرداخته میشه.

Composer 2 منتشر شد

درواقع لیست تغییرات و بهبود ها خیلی طولانیه که در ادامه به بخش های کلیدی اون اشاره می کنم.

بهبود عملکرد

در این نسخه تقریبا همه چیز اصلاح شده است. از جمله پروتکل استفاده شده بین Composer و Packagist تا مدیریت وابستگی ها مانند دانلود همزمان فایل ها با استفاده از CURL. این اصلاح ها از نظر سرعت و میزان استفاده از حافظه سیستم پیشرفت های گسترده ای اعمال کرده که به وضوح احساس میشه. گرچه در نهایت همه چیز به استفاده خودتون بستگی داره. در بعضی موارد گزارش هایی از بهبود عملکرد 50 درصدی وجود داره ولی خب نمیشه عدد دقیقی براش مشخص کرد.

نتیجه تمام این بهبود ها برای دستوراتی مانند require و remove و update افزایش سرعت بالایی بوده چون از این به بعد Composer فقط metadata های تغییر کرده رو بارگذاری میکنه.

مقایسه عملکرد در فریمورک های مختلف

تغییرات در معماری

نحوه انجام به روزرسانی ها اصلاح مناسبی داشته و از این به بعد وضعیت فعلی پوشه vendor دیگه تاثیری در انجام کار نداره.

و در نهایت پس از اینکه بروزرسانی ها انجام شد ٬ عملیات نصب شروع میشه. در حال حاضر ابتدا تمام عملیات های اتصال به شبکه انجام میشه ٬ در این صورت اگر در اواسط نصب خطای شبکه ای رخ بده همه چیز کنسل نمیشه و پوشه ی vendor نصف نیمه ای براتون باقی بمونه ( خودم به شخصه بارها با چنین مشکلی مواجه شدم ).

ویژگی های زمان اجرا

در این نسخه یه مرحله بررسی پلتفرم اضافه شده که به محض اجرای vendor/autoload.php اطلاعات PHP و افزونه های نصب شده رو میخونه تا در صورت تداخل با نیازمندی ها در همون مرحله خطا داده بشه و اجازه نده خطاها وارد مرحله اجرای کد بشه.

در این نسخه کلاس جدیدی به وجود اومده ٬ Composer\InstalledVersions. این کلاس به صورت خودکار در تمام پروژه ها و زمان اجرا بارگذاری میشه و به شما این امکان رو میده که در هر زمانی بررسی کنید چه پکیجی با چه نسخه ای درحال کاره.

برای جزپیات بیشتر به مستندات مربوط به Runtime مراجعه کنید.

در صورتی که بخواید از این ویژگی های جدید در پروژه تون استفاده کنید باید "composer-runtime-api": "^2.0" رو در فایل composer.json خودتون قرار بدید. این پکیج مجازی در نهایت باعث میشه اگه به صورت عمومی پروژه تون رو منتشر کنید ٬ افراد مجبور بشن از Composer 2 استفاده کنن. برای مثال اگر کتابخونه ای برای Laravel بنویسید که از این ویژگی های استفاده کنه ٬ Client ها مجبور میشن نسخه Composer خودشون رو آپدیت کنن.

گزارش خطا

از اونجایی که همیشه همه چیز درست پیش نمیره ٬ خطاهایی هم در پروژه ها وجود داره. در نسخه جدید بهبود های بسیار در زمینه گزارش ها به وجود اومده که باعث میشه خطاها یا هشدارها کوتاه و واضح تر به شما نمایش داده بشه. مثال زدن در این زمینه خیلی سخته و خودتون در حین کار با Composer 2 بهبود ها رو مشاهده می کنید.

آپدیت های تکی

خیلی وقت ها اینکه بتونیم فقط یه پکیج خاص رو آپدیت کنیم یا به نسخه قبلی برگردونیم میتونه مفید باشه واسمون. فرض کنید برای تست یه کتابخونه میخوایم آخرین نسخه اش رو استفاده کنیم و اگه مشکل داشت دوباره به نسخه قبلی برگردیم. حالا خیلی راحت میتونیم با دستوری مانند composer update vendor/package:1.0.* فقط یه پکیج رو آپدیت کنیم. با اجرای این دستور فایل composer.json و composer.lock هیچ تغییری نمیکنه و فقط خود پکیج عوض میشه.

در کنار این دستور ٬ اگر بخواید باقی پکیج ها هم آپدیت بشه میتونید از چنین چیزی استفاده کنید : update --with vendor/package:1.0.*. در این صورت کل پکیج ها آپدیت میشه و در کنارش درخواست شما برای بروزرسانی پکیج خاصی هم اعمال میشه.

روش آپدیت به Composer 2

یکی از اهداف این بروزرسانی پشتیبانی از رنج وسیع کاربرهاست و اینکه همه بتونن خیلی ساده و سریع عملیات آپدیت رو انجام بدن. از این رو ۳ قابلیت در نظر گرفته شده :

  • نسخه دوم هنوز از PHP 5.3 به بالا پشتیبانی میکنه ( دقیقا همانند Composer 1.x )
  • فایل composer.lock بین نسخه های ۱ و ۲ قابل استفاده است و تغییر خاصی نیاز نداره. بنابراین به راحتی میتونید به نسخه 2 مهاجرت کنید و هروقت نخواستید به نسخه ۱ برگردید
  • تمام دستورات و آرگومان ها همانند نسخه ۱ بوده و تغییر خاصی در اون ها اعمال نشده. گرچه موارد جدید مانند مثال update که در بالا ذکر شد وجود دارن

برای بروزرسانی به نسخه دوم کافیه دستور زیر رو اجرا کنید :

composer self-update --2

و هروقت که به مشکل خوردید یا نخواستید از نسخه جدید استفاده کنید با دستور composer self-update --1 به نسخه قبلی برگردید. در حال حاضر وقتی برای اولین بار قصد نصب Composer رو دارید به صورت پیشفرض نسخه ۲ نصب میشه که برای جلوگیری از این کار میشه از همین آرگومان --1 استفاده کرد.

لیست کامل تغییرات

مواردی که در بالا ذکر شد تغییرات و بهبود های مهم بود. در ادامه لیست کامل تغییرات نسخه دوم رو مشاهده می کنید :

  • Breaking: This is a major release and while we tried to keep things compatible for most users, you might want to have a look at the UPGRADE guides
  • Many CPU and memory performance improvements
  • The update command is now much more deterministic as it does not take the already installed packages into account
  • Package installation now performs all network operations first before doing any changes on disk, to reduce the chances of ending up with a partially updated vendor dir
  • Partial updates and require/remove are now much faster as they only load the metadata required for the updated packages
  • Added a platform-check step when vendor/autoload.php gets initialized which checks the current PHP version/extensions match what is expected and fails hard otherwise. Can be disabled with the platform-check config option
  • Added a Composer\InstalledVersions class which is autoloaded in every project and lets you check which packages/versions are present at runtime
  • Added a composer-runtime-api virtual package which you can require (as e.g. ^2.0) to ensure things like the InstalledVersions class above are present. It will effectively force people to use Composer 2.x to install your project
  • Added support for parallel downloads of package metadata and zip files, this requires that the curl extension is present and we thus strongly recommend enabling curl
  • Added parallel installation of packages (requires OSX/Linux/WSL, and that unzip is present in PATH)
  • Added much clearer dependency resolution error reporting for common error cases
  • Added support for updating to a specific version with partial updates, as well as a --with flag to pass in temporary constraint overrides
  • Added automatic removal of packages which are not required anymore whenever an update is done, this will purge packages previously left over by partial updates and require/remove
  • Added support for TTY mode on Linux/OSX/WSL so that script handlers now run in interactive mode
  • Added only, exclude and canonical options to all repositories, see repository priorities for details
  • Added support for many new lib-* packages in the platform repository and improved version detection for some ext-* and lib-* packages
  • Added pre-operations-exec event to be fired before the packages get installed/upgraded/removed
  • Added pre-pool-create event to be fired before the package pool for the dependency solver is created, which lets you modify the list of packages going in
  • Added post-file-download event to be fired after package dist files are downloaded, which lets you do additional checks on the files
  • Added --locked flag to show command to see the packages from the composer.lock file
  • Added --unused flag to remove command to make sure any packages which are not needed anymore get removed
  • Added --dry-run flag to require and remove commands
  • Added --no-install flag to update, require and remove commands to disable the install step and only do the update step (composer.lock file update)
  • Added an --ask flag to create-project command to make Composer prompt for the install dir name, useful for project install instructions
  • Added support for multiple --repository flags being passed into the create-project command, only useful in combination with --add-repository to persist them to composer.json
  • Added --with-dependencies and --with-all-dependencies flag aliases to require and remove commands for consistency with update
  • Added shorthand aliases -w for --with-dependencies and -W for --with-all-dependencies on update/require/remove commands
  • Added more info to vendor/composer/installed.json, a dev key stores whether dev requirements were installed, and every package now has an install-path key with its install location
  • Added COMPOSER_DISABLE_NETWORK which if set makes Composer do its best to run offline. This can be useful when you have poor connectivity or to do benchmarking without network jitter
  • Added COMPOSER_DEBUG_EVENTS=1 env var support for plugin authors to figure out which events are triggered when
  • Added setCustomCacheKey to PreFileDownloadEvent and fixed a cache bug for integrations changing the processed url of package archives
  • Added Composer\Util\SyncHelper for plugin authors to deal with async Promises more easily
  • Added $composer->getLoop()->getHttpDownloader()` to get access to the main HttpDownloader instance in plugins
  • Added --json and --merge flags to config command to allow editing complex extra.* values by using json as input
  • Added confirmation prompt when running Composer as superuser in interactive mode
  • Added --no-check-version to validate command to remove the warning in case the version is defined
  • Added --ignore-platform-req (without s) to all commands supporting --ignore-platform-reqs, which accepts a package name so you can ignore only specific platform requirements
  • Added --no-dev support to show and outdated commands to skip dev requirements
  • Added --format=summary flag to license command
  • Added a cache-read-only config option to make the cache usable in read only mode for containers and such
  • Added support for wildcards (*) in classmap autoloader paths
  • Added support for configuring GitLab deploy tokens in addition to private tokens, see gitlab-token
  • Added support for package version guessing for require and init command to take all platform packages into account, not just php version
  • Added support for tar in artifact repositories
  • Added a non-zero exit code (2) and warning to remove command when a package to be removed could not be removed
  • Added --apcu-autoloader-prefix (or --apcu-prefix for dump-autoload command) flag to let people use apcu autoloading in a deterministic output way if that is needed
  • Fixed package ordering when autoloading and especially when loading plugins, to make sure dependencies are loaded before their dependents
  • Fixed suggest output being very spammy, it now is only one line long and shows more rarely
  • Fixed conflict rules like e.g. >=5 from matching dev-master, as it is not normalized to 9999999-dev internally anymore
  • Fixed solver bug resulting in endless loops in some cases
  • Lots of minor bug fixes and improvements