diff --git a/composer-2.5.4-6b67eee.tgz b/composer-2.5.4-6b67eee.tgz new file mode 100644 index 0000000000000000000000000000000000000000..7bb02743a27ed323570e9ffa73f51df0f1f2caea Binary files /dev/null and b/composer-2.5.4-6b67eee.tgz differ diff --git a/composer-add-aliyun-repository.patch b/composer-add-aliyun-repository.patch new file mode 100644 index 0000000000000000000000000000000000000000..f5bc1c23409cd450742541a8b4320435b15ee4c4 --- /dev/null +++ b/composer-add-aliyun-repository.patch @@ -0,0 +1,14 @@ +--- a/src/Composer/Config.php.orig 2023-02-25 11:59:19.951057271 +0800 ++++ b/src/Composer/Config.php 2023-02-25 12:03:48.490871158 +0800 +@@ -86,6 +86,11 @@ + + /** @var array */ + public static $defaultRepositories = [ ++ 'aliyun.com' => [ ++ 'type' => 'composer', ++ 'url' => 'https://mirrors.aliyun.com/composer/', ++ 'canonical' => false, ++ ], + 'packagist.org' => [ + 'type' => 'composer', + 'url' => 'https://repo.packagist.org', diff --git a/composer-bash-completion b/composer-bash-completion new file mode 100644 index 0000000000000000000000000000000000000000..938a1a6dff0160e2024ad81aa29813e0f4a0d3ee --- /dev/null +++ b/composer-bash-completion @@ -0,0 +1,84 @@ +# This file is part of the Symfony package. +# +# (c) Fabien Potencier +# +# For the full copyright and license information, please view +# https://symfony.com/doc/current/contributing/code/license.html + +_sf_composer() { + # Use newline as only separator to allow space in completion values + IFS=$'\n' + local sf_cmd="${COMP_WORDS[0]}" + + # for an alias, get the real script behind it + sf_cmd_type=$(type -t $sf_cmd) + if [[ $sf_cmd_type == "alias" ]]; then + sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/") + elif [[ $sf_cmd_type == "file" ]]; then + sf_cmd=$(type -p $sf_cmd) + fi + + if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then + return 1 + fi + + local cur prev words cword + _get_comp_words_by_ref -n := cur prev words cword + + local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-S2.5.3") + for w in ${words[@]}; do + w=$(printf -- '%b' "$w") + # remove quotes from typed values + quote="${w:0:1}" + if [ "$quote" == \' ]; then + w="${w%\'}" + w="${w#\'}" + elif [ "$quote" == \" ]; then + w="${w%\"}" + w="${w#\"}" + fi + # empty values are ignored + if [ ! -z "$w" ]; then + completecmd+=("-i$w") + fi + done + + local sfcomplete + if sfcomplete=$(${completecmd[@]} 2>&1); then + local quote suggestions + quote=${cur:0:1} + + # Use single quotes by default if suggestions contains backslash (FQCN) + if [ "$quote" == '' ] && [[ "$sfcomplete" =~ \\ ]]; then + quote=\' + fi + + if [ "$quote" == \' ]; then + # single quotes: no additional escaping (does not accept ' in values) + suggestions=$(for s in $sfcomplete; do printf $'%q%q%q\n' "$quote" "$s" "$quote"; done) + elif [ "$quote" == \" ]; then + # double quotes: double escaping for \ $ ` " + suggestions=$(for s in $sfcomplete; do + s=${s//\\/\\\\} + s=${s//\$/\\\$} + s=${s//\`/\\\`} + s=${s//\"/\\\"} + printf $'%q%q%q\n' "$quote" "$s" "$quote"; + done) + else + # no quotes: double escaping + suggestions=$(for s in $sfcomplete; do printf $'%q\n' $(printf '%q' "$s"); done) + fi + COMPREPLY=($(IFS=$'\n' compgen -W "$suggestions" -- $(printf -- "%q" "$cur"))) + __ltrim_colon_completions "$cur" + else + if [[ "$sfcomplete" != *"Command \"_complete\" is not defined."* ]]; then + >&2 echo + >&2 echo $sfcomplete + fi + + return 1 + fi +} + +complete -F _sf_composer composer diff --git a/composer-noxdg.patch b/composer-noxdg.patch new file mode 100644 index 0000000000000000000000000000000000000000..73195e7b327fd0be3d2fffa8e07a22d2ceebe522 --- /dev/null +++ b/composer-noxdg.patch @@ -0,0 +1,14 @@ +diff -up ./src/Composer/Factory.php.noxdg ./src/Composer/Factory.php +--- ./src/Composer/Factory.php.noxdg 2022-03-16 09:51:30.398977729 +0100 ++++ ./src/Composer/Factory.php 2022-03-16 09:52:14.113841110 +0100 +@@ -665,6 +665,10 @@ class Factory + + private static function useXdg(): bool + { ++ // As XDG is very patially implemted ++ // resulting in command/code in ~/.config ++ return false; ++ + foreach (array_keys($_SERVER) as $key) { + if (strpos($key, 'XDG_') === 0) { + return true; diff --git a/composer-rpm.patch b/composer-rpm.patch new file mode 100644 index 0000000000000000000000000000000000000000..224503ac69564d3aa1e21900e45129680c75168e --- /dev/null +++ b/composer-rpm.patch @@ -0,0 +1,115 @@ +diff -up ./bin/composer.rpm ./bin/composer +--- ./bin/composer.rpm 2022-08-29 07:36:37.000000000 +0200 ++++ ./bin/composer 2022-08-29 07:36:45.053967617 +0200 +@@ -11,7 +11,7 @@ if (PHP_VERSION_ID < 70205) { + } + + setlocale(LC_ALL, 'C'); +-require __DIR__.'/../src/bootstrap.php'; ++require '/usr/share/php/Composer/autoload.php'; + + use Composer\Console\Application; + use Composer\XdebugHandler\XdebugHandler; +diff -up ./src/Composer/Autoload/AutoloadGenerator.php.rpm ./src/Composer/Autoload/AutoloadGenerator.php +--- ./src/Composer/Autoload/AutoloadGenerator.php.rpm 2022-08-29 07:36:45.053967617 +0200 ++++ ./src/Composer/Autoload/AutoloadGenerator.php 2022-08-29 07:38:03.936134475 +0200 +@@ -431,7 +431,7 @@ EOF; + $filesystem->filePutContentsIfModified($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $checkPlatform)); + + $filesystem->safeCopy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php'); +- $filesystem->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE'); ++ $filesystem->safeCopy((getenv('BUILDROOT')?:'') . '/usr/share/composer/LICENSE', $targetDir.'/LICENSE'); + + if ($this->runScripts) { + $this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, [], [ +diff -up ./src/Composer/Compiler.php.rpm ./src/Composer/Compiler.php +--- ./src/Composer/Compiler.php.rpm 2022-08-29 07:36:37.000000000 +0200 ++++ ./src/Composer/Compiler.php 2022-08-29 07:36:45.053967617 +0200 +@@ -106,7 +106,7 @@ class Compiler + // Add Composer resources + $finder = new Finder(); + $finder->files() +- ->in(__DIR__.'/../../res') ++ ->in((getenv('BUILDROOT')?:'') . '/usr/share/composer/res') + ->sort($finderSort) + ; + foreach ($finder as $file) { +diff -up ./src/Composer/InstalledVersions.php.rpm ./src/Composer/InstalledVersions.php +--- ./src/Composer/InstalledVersions.php.rpm 2022-08-29 07:36:37.000000000 +0200 ++++ ./src/Composer/InstalledVersions.php 2022-08-29 07:36:45.053967617 +0200 +@@ -266,7 +266,7 @@ class InstalledVersions + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 +- if (substr(__DIR__, -8, 1) !== 'C') { ++ if (substr(__DIR__, -8, 1) !== 'C' && is_file(__DIR__ . '/installed.php')) { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); +@@ -339,7 +339,7 @@ class InstalledVersions + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 +- if (substr(__DIR__, -8, 1) !== 'C') { ++ if (substr(__DIR__, -8, 1) !== 'C' && is_file(__DIR__ . '/installed.php')) { + self::$installed = require __DIR__ . '/installed.php'; + } else { + self::$installed = array(); +diff -up ./src/Composer/Json/JsonFile.php.rpm ./src/Composer/Json/JsonFile.php +--- ./src/Composer/Json/JsonFile.php.rpm 2022-08-29 07:36:37.000000000 +0200 ++++ ./src/Composer/Json/JsonFile.php 2022-08-29 07:36:45.053967617 +0200 +@@ -39,7 +39,7 @@ class JsonFile + /** @deprecated Use \JSON_UNESCAPED_UNICODE */ + public const JSON_UNESCAPED_UNICODE = 256; + +- public const COMPOSER_SCHEMA_PATH = __DIR__ . '/../../../res/composer-schema.json'; ++ public const COMPOSER_SCHEMA_PATH = '/usr/share/composer/res/composer-schema.json'; + + /** @var string */ + private $path; +@@ -216,7 +216,7 @@ class JsonFile + $isComposerSchemaFile = false; + if (null === $schemaFile) { + $isComposerSchemaFile = true; +- $schemaFile = self::COMPOSER_SCHEMA_PATH; ++ $schemaFile = (getenv('BUILDROOT')?:'') . self::COMPOSER_SCHEMA_PATH; + } + + // Prepend with file:// only when not using a special schema already (e.g. in the phar) +diff -up ./src/Composer/PHPStan/ConfigReturnTypeExtension.php.rpm ./src/Composer/PHPStan/ConfigReturnTypeExtension.php +--- ./src/Composer/PHPStan/ConfigReturnTypeExtension.php.rpm 2022-08-29 07:36:37.000000000 +0200 ++++ ./src/Composer/PHPStan/ConfigReturnTypeExtension.php 2022-08-29 07:36:45.054967614 +0200 +@@ -39,7 +39,7 @@ final class ConfigReturnTypeExtension im + + public function __construct() + { +- $schema = JsonFile::parseJson((string) file_get_contents(__DIR__.'/../../../res/composer-schema.json')); ++ $schema = JsonFile::parseJson((string) file_get_contents('/usr/share/composer/res/composer-schema.json')); + /** + * @var string $prop + */ +diff -up ./src/Composer/vendor/composer/ca-bundle/src/CaBundle.php.rpm ./src/Composer/vendor/composer/ca-bundle/src/CaBundle.php +--- ./src/Composer/vendor/composer/ca-bundle/src/CaBundle.php.rpm 2022-07-20 09:14:26.000000000 +0200 ++++ ./src/Composer/vendor/composer/ca-bundle/src/CaBundle.php 2022-08-29 07:36:45.054967614 +0200 +@@ -125,7 +125,7 @@ class CaBundle + */ + public static function getBundledCaBundlePath() + { +- $caBundleFile = __DIR__.'/../res/cacert.pem'; ++ $caBundleFile = '/etc/pki/tls/certs/ca-bundle.crt'; // System CA, always + + // cURL does not understand 'phar://' paths + // see https://github.com/composer/ca-bundle/issues/10 +diff -up ./tests/Composer/Test/Json/ComposerSchemaTest.php.rpm ./tests/Composer/Test/Json/ComposerSchemaTest.php +--- ./tests/Composer/Test/Json/ComposerSchemaTest.php.rpm 2022-08-29 07:36:45.054967614 +0200 ++++ ./tests/Composer/Test/Json/ComposerSchemaTest.php 2022-08-29 07:39:34.814922582 +0200 +@@ -96,7 +96,8 @@ class ComposerSchemaTest extends TestCas + private function check(string $json) + { + $validator = new Validator(); +- $validator->check(json_decode($json), (object) ['$ref' => 'file://' . __DIR__ . '/../../../../res/composer-schema.json']); ++ $f = (getenv('BUILDROOT')?:'') . '/usr/share/composer/res/composer-schema.json'; ++ $validator->check(json_decode($json), (object) ['$ref' => 'file://' . $f]); + + if (!$validator->isValid()) { + $errors = $validator->getErrors(); diff --git a/composer.csh b/composer.csh new file mode 100644 index 0000000000000000000000000000000000000000..b57b1d01d2562aa0c1861356a3963f165b49c428 --- /dev/null +++ b/composer.csh @@ -0,0 +1,9 @@ +# Composer initialization script + +# Add path to commands installed using "composer global require ..." +if ( ${euid} > 0 ) then + if ( "${path}" !~ *${HOME}/.composer/vendor/bin* ) then + set path = ( $path ${HOME}/.composer/vendor/bin ) + endif +endif + diff --git a/composer.sh b/composer.sh new file mode 100644 index 0000000000000000000000000000000000000000..c75753c2d75145b4d0ae5daa008aad7a03e4ff2b --- /dev/null +++ b/composer.sh @@ -0,0 +1,11 @@ +# Composer initialization script + +# Add path to commands installed using "composer global require ..." +if [ "${EUID:-0}" != "0" ]; then + case :$PATH: in + *:${HOME}/.composer/vendor/bin:*) ;; + *) PATH=$PATH:${HOME}/.composer/vendor/bin ;; + esac + export PATH +fi + diff --git a/composer.spec b/composer.spec new file mode 100644 index 0000000000000000000000000000000000000000..4a2bf01601d05592516515378077fb55ca30b7f3 --- /dev/null +++ b/composer.spec @@ -0,0 +1,227 @@ +%define anolis_release 2 +%undefine __brp_mangle_shebangs + +%global gh_commit 6b67eeea4d72051c369ccdbfb2423a56e2ab51a9 +%global gh_short %(c=%{gh_commit}; echo ${c:0:7}) +%global gh_branch 2.0-dev +%global gh_owner composer +%global gh_project composer +%global api_version 2.3.0 +%global run_version 2.2.2 + +%global upstream_version 2.5.4 + +%global _phpunit %{_bindir}/phpunit9 +%global bashcompdir %(pkg-config --variable=completionsdir bash-completion 2>/dev/null) +%global bashcomproot %(dirname %{bashcompdir} 2>/dev/null) + + +Name: composer +Version: %{upstream_version}%{?upstream_prever:~%{upstream_lower}} +Release: %{anolis_release}%{?dist} +Summary: Dependency Manager for PHP + +# SPDX: composer and all dependencies are MIT +License: MIT +URL: https://getcomposer.org/ +Source0: %{gh_project}-%{upstream_version}%{?upstream_prever}-%{gh_short}.tgz +# Profile scripts +Source1: %{name}-bash-completion +Source3: %{name}.sh +Source4: %{name}.csh +# Get a git snapshot to retrieve the test suite +Source5: makesrc.sh + +# Use our autoloader, resources path, fix for tests +Patch0: %{name}-rpm.patch +# Disable XDG support as only partially implemented +Patch1: %{name}-noxdg.patch +# Use Aliyun mirror by default +Patch10: composer-add-aliyun-repository.patch + +BuildArch: noarch +# platform set in makesrc.sh +BuildRequires: php(language) >= 7.2.5 +BuildRequires: php-cli +BuildRequires: php-json +BuildRequires: pkgconfig(bash-completion) + +Requires: php(language) >= 7.2.5 +Requires: php-cli +Supplements: php-cli +# System certificates +Requires: ca-certificates +# Bundled libraries +# License MIT +Provides: bundled(php-composer-ca-bundle) = 1.3.5 +Provides: bundled(php-composer-class-map-generator) = 1.0.0 +Provides: bundled(php-composer-metadata-minifier) = 1.0.0 +Provides: bundled(php-composer-pcre) = 2.1.0 +Provides: bundled(php-composer-semver) = 3.3.2 +Provides: bundled(php-composer-spdx-licenses) = 1.5.7 +Provides: bundled(php-composer-xdebug-handler) = 3.0.3 +Provides: bundled(php-justinrainbow-json-schema) = 5.2.12 +Provides: bundled(php-psr-container) = 1.1.1 +Provides: bundled(php-psr-log) = 1.1.4 +Provides: bundled(php-react-promise) = v2.9.0 +Provides: bundled(php-seld-jsonlint) = 1.9.0 +Provides: bundled(php-seld-phar-utils) = 1.2.1 +Provides: bundled(php-seld-signal-handler) = 2.0.1 +Provides: bundled(php-symfony-console) = v5.4.19 +Provides: bundled(php-symfony-deprecation-contracts) = v2.5.2 +Provides: bundled(php-symfony-filesystem) = v5.4.19 +Provides: bundled(php-symfony-finder) = v5.4.19 +Provides: bundled(php-symfony-polyfill-ctype) = v1.27.0 +Provides: bundled(php-symfony-polyfill-intl-grapheme) = v1.27.0 +Provides: bundled(php-symfony-polyfill-intl-normalizer) = v1.27.0 +Provides: bundled(php-symfony-polyfill-mbstring) = v1.27.0 +Provides: bundled(php-symfony-polyfill-php73) = v1.27.0 +Provides: bundled(php-symfony-polyfill-php80) = v1.27.0 +Provides: bundled(php-symfony-polyfill-php81) = v1.27.0 +Provides: bundled(php-symfony-process) = v5.4.19 +Provides: bundled(php-symfony-service-contracts) = v2.5.2 +Provides: bundled(php-symfony-string) = v5.4.19 + +Requires: php-openssl +Requires: php-zip +Requires: php-zlib +# From phpcompatinfo for version 2.2.5 +Requires: php-ctype +Requires: php-curl +Requires: php-date +Requires: php-dom +Requires: php-filter +Requires: php-hash +Requires: php-iconv +Requires: php-intl +Requires: php-json +Requires: php-libxml +Requires: php-mbstring +Requires: php-pcntl +Requires: php-pcre +Requires: php-phar +Requires: php-posix +Requires: php-reflection +Requires: php-spl +Requires: php-tokenizer +Requires: php-xsl +Requires: php-zlib + +# Composer library +Provides: php-composer(composer/composer) = %{version} +# Special internal for Plugin API +Provides: php-composer(composer-plugin-api) = %{api_version} +Provides: php-composer(composer-runtime-api) = %{run_version} + + +%description +Composer helps you declare, manage and install dependencies of PHP projects, +ensuring you have the right stack everywhere. + +Documentation: https://getcomposer.org/doc/ + +%package doc +Summary: Documentation files for %{name} +Requires: %{name} = %{EVR} +BuildArch: noarch + +%description doc +The %{name}-doc package contains documentation files for %{name}. + + +%prep +%autosetup -p1 -n %{gh_project}-%{gh_commit} + +find . \( -name \*.rpm -o -name \*noxdg \) -delete -print + +if grep -r '\.\./res'; then + : Patch need to fixed + exit 1 +fi + +rm src/bootstrap.php +rm src/Composer/vendor/composer/ca-bundle/res/cacert.pem + +: symlink autoloader for library +ln -s vendor/autoload.php src/Composer/autoload.php + +: fix layout +sed -e "s:/../..' . '/src/Composer::" -i src/Composer/vendor/composer/autoload_static.php + +: List bundled libraries and Licenses +php -r ' + $pkgs = file_get_contents("src/Composer/vendor/composer/installed.json"); + $pkgs = json_decode($pkgs, true); + if (!is_array($pkgs) || !isset($pkgs["packages"])) { + echo "cant decode json file\n"; + exit(3); + } + $res = []; + foreach($pkgs["packages"] as $pkg) { + $lic = implode(" and ", $pkg["license"]); + if (!isset($res[$lic])) $res[$lic] = []; + $res[$lic][] = sprintf("Provides: bundled(php-%s) = %s", str_replace(["/", "_"], ["-", "-"], $pkg["name"]), $pkg["version"]); + } + foreach($res as $lic => $lib) { + sort($lib); + printf("# License %s\n%s\n", $lic, implode("\n", $lib)); + } +' + +: fix reported version +sed -e '/BRANCH_ALIAS_VERSION/s/@package_branch_alias_version@//' \ + -i src/Composer/Composer.php + +: check Plugin API version +php -r ' +namespace Composer; +include "src/Composer/autoload.php"; +if (version_compare(Plugin\PluginInterface::PLUGIN_API_VERSION, "%{api_version}")) { + printf("Plugin API version is %s, expected %s\n", Plugin\PluginInterface::PLUGIN_API_VERSION, "%{api_version}"); + exit(1); +} +if (version_compare(Composer::RUNTIME_API_VERSION, "%{run_version}")) { + printf("Runtime API version is %s, expected %s\n", Composer::RUNTIME_API_VERSION, "%{run_version}"); + exit(1); +}' + + +%build +# Nothing + + +%install +install -Dpm 644 %{SOURCE1} %{buildroot}%{bashcompdir}/%{name} +mkdir -p %{buildroot}%{_sysconfdir}/profile.d +install -m 644 %{SOURCE3} %{SOURCE4} %{buildroot}%{_sysconfdir}/profile.d/ + +mkdir -p %{buildroot}%{_datadir}/php +cp -pr src/* %{buildroot}%{_datadir}/php + +mkdir -p %{buildroot}%{_datadir}/%{name} +cp -pr res %{buildroot}%{_datadir}/%{name}/res +cp -p LICENSE %{buildroot}%{_datadir}/%{name}/LICENSE + +ln -sf %{_datadir}/%{name}/LICENSE LICENSE + +install -Dpm 755 bin/%{name} %{buildroot}%{_bindir}/%{name} + + +%files +%license LICENSE +%config(noreplace) %{_sysconfdir}/profile.d/%{name}.* +%{_bindir}/%{name} +%{_datadir}/php/Composer +%{_datadir}/%{name} +%{bashcomproot} + +%files doc +%doc *.md doc +%doc composer.json + +%changelog +* Mon Mar 27 2023 happy_orange - 2.5.4-2 +- add doc package + +* Sat Feb 18 2023 Funda Wang - 2.5.4-1 +- Import package from Remi diff --git a/makesrc.sh b/makesrc.sh new file mode 100755 index 0000000000000000000000000000000000000000..cb5e0694cbbab967a5c1ef71ef5a31483025e82a --- /dev/null +++ b/makesrc.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +NAME=$(sed -n '/^Name:/{s/.* //;p}' *.spec) +OWNER=$(sed -n '/^%global gh_owner/{s/.* //;p}' $NAME.spec) +PROJECT=$(sed -n '/^%global gh_project/{s/.* //;p}' $NAME.spec) +VERSION=$(sed -n '/^%global upstream_version/{s/.* //;p}' $NAME.spec) +PREVER=$(sed -n '/^%global upstream_prever/{s/.* //;p}' $NAME.spec) +COMMIT=$(sed -n '/^%global gh_commit/{s/.* //;p}' $NAME.spec) +SHORT=${COMMIT:0:7} + +if [ -f $NAME-$VERSION$PREVER-$SHORT.tgz ]; then + echo skip $NAME-$VERSION$PREVER-$SHORT.tgz already here +else + echo -e "\nCreate git snapshot\nName=$NAME, Owner=$OWNER, Project=$PROJECT, Version=$VERSION$PREVER\n" + + echo "Cloning..." + git clone https://github.com/$OWNER/$PROJECT.git $PROJECT-$COMMIT + + echo "Getting commit..." + pushd $PROJECT-$COMMIT + git checkout $COMMIT || exit 1 + cp composer.json ../composer.json + composer config platform.php 7.2.5 + rm composer.lock + export COMPOSER_VENDOR_DIR=src/Composer/vendor + composer install --no-interaction --no-progress --no-dev --optimize-autoloader + cp src/Composer/vendor/composer/installed.json ../ + # bash completion + ln -sf Composer/vendor/autoload.php src/bootstrap.php + bin/composer completion bash >../composer-bash-completion + popd + + echo "Archiving..." + tar czf $NAME-$VERSION$PREVER-$SHORT.tgz --exclude .git $PROJECT-$COMMIT + + echo "Cleaning..." + rm -rf $PROJECT-$COMMIT +fi +echo "Done."