feat: Optimize source download with shallow clone

使用浅克隆方式下载源代码,避免git仓库太大的问题

Log:
This commit is contained in:
myml 2024-01-24 13:33:35 +08:00 committed by black-desk
parent 064ab6cca9
commit abf262d844
9 changed files with 73 additions and 65 deletions

View File

@ -166,7 +166,7 @@ pfl_add_library(
./src/linglong/builder/builder.h
./src/linglong/builder/builder_config.cpp
./src/linglong/builder/builder_config.h
./src/linglong/builder/builder_templates.qrc
./src/linglong/builder/builder_releases.qrc
./src/linglong/builder/depend_fetcher.cpp
./src/linglong/builder/depend_fetcher.h
./src/linglong/builder/linglong_builder.cpp

View File

@ -92,7 +92,8 @@ configure_file(scripts/create-linglong-dirs.in scripts/create-linglong-dirs
configure_file(scripts/upgrade-all.in scripts/upgrade-all @ONLY)
set(LINGLONG_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/scripts/create-linglong-dirs
${CMAKE_CURRENT_BINARY_DIR}/scripts/upgrade-all)
${CMAKE_CURRENT_BINARY_DIR}/scripts/upgrade-all
scripts/fetch-git-repo)
install(PROGRAMS ${LINGLONG_SCRIPTS}
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/linglong/)

View File

@ -0,0 +1,31 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-or-later
set -e
workdir=$1
url=$2
commit=$3
version=$4
mkdir "$workdir" || true
cd "$workdir"
# init repo
if [ -d ".git" ]; then
git remote set-url origin "$url"
else
git init --initial-branch "$version"
git remote add origin "$url"
fi
# fetch commit
git tag --delete "$version" || true
git fetch origin "$commit:refs/tags/$version" --depth 1 -n
git reset --hard "$version"
# init submodule
git submodule update --init --recursive --depth 1
git submodule foreach git reset --hard HEAD

View File

@ -14,7 +14,7 @@
static void initQResource()
{
Q_INIT_RESOURCE(builder_templates);
Q_INIT_RESOURCE(builder_releases);
}
namespace linglong {

View File

@ -5,6 +5,7 @@ SPDX-License-Identifier: LGPL-3.0-or-later
-->
<RCC>
<qresource prefix="/">
<!-- template -->
<file alias="config.yaml">../../../misc/linglong/builder/config.yaml</file>
<file alias="strip.sh">../../../misc/linglong/builder/templates/strip.sh</file>
<file alias="autotools.yaml">../../../misc/linglong/builder/templates/autotools.yaml</file>
@ -14,5 +15,7 @@ SPDX-License-Identifier: LGPL-3.0-or-later
<file alias="example.yaml">../../../misc/linglong/builder/templates/example.yaml</file>
<file alias="appimage.yaml">../../../misc/linglong/builder/templates/appimage.yaml</file>
<file alias="makeimage.yaml">../../../misc/linglong/builder/templates/makeimage.yaml</file>
<!-- scripts -->
<file alias="scripts/fetch-git-repo">../../../misc/scripts/fetch-git-repo</file>
</qresource>
</RCC>

View File

@ -12,10 +12,12 @@
#include "linglong/util/file.h"
#include "linglong/util/http/http_client.h"
#include "linglong/util/runner.h"
#include "linglong/utils/global/initialize.h"
#include "project.h"
#include "source_fetcher_p.h"
#include <QNetworkRequest>
#include <QTemporaryDir>
namespace linglong {
namespace builder {
@ -159,80 +161,41 @@ std::tuple<QString, linglong::util::Error> SourceFetcherPrivate::fetchArchiveFil
return { path, Success() };
}
// TODO: DO NOT clone all repo, see here for more:
// https://stackoverflow.com/questions/3489173/how-to-clone-git-repository-with-specific-revision-changeset/3489576
util::Error SourceFetcherPrivate::fetchGitRepo()
{
Q_Q(SourceFetcher);
q->setSourceRoot(sourceTargetPath());
util::ensureDir(sourceTargetPath());
if (!QDir::setCurrent(sourceTargetPath())) {
return NewError(-1, QString("change to %1 failed").arg(sourceTargetPath()));
q->printer.printMessage(QString("Path: %1").arg(sourceTargetPath()), 2);
// 如果二进制安装在系统目录中,优先使用系统中安装的脚本文件(便于用户更改),否则使用二进制内嵌的脚本(便于开发调试)
auto scriptFile = QString(LINGLONG_LIBEXEC_DIR) + "/fetch-git-repo.sh";
auto useInstalledFile = utils::global::linglongInstalled() && QFile(scriptFile).exists();
QScopedPointer<QTemporaryDir> dir;
if (!useInstalledFile) {
qWarning() << "Dumping fetch-git-repo from qrc...";
dir.reset(new QTemporaryDir);
// 便于在执行失败时进行调试
dir->setAutoRemove(false);
scriptFile = dir->filePath("fetch-git-repo");
QFile::copy(":/scripts/fetch-git-repo", scriptFile);
}
QStringList args = {
scriptFile, sourceTargetPath(), source->url, source->commit, source->version,
};
q->printer.printMessage(QString("Command: sh %1").arg(args.join(" ")), 2);
QSharedPointer<QByteArray> output = QSharedPointer<QByteArray>::create();
q->printer.printMessage(
QString("git clone --recurse-submodules %1 %2").arg(source->url).arg(sourceTargetPath()),
2);
auto err = util::Exec("git",
{
"clone",
"--recurse-submodules",
source->url,
sourceTargetPath(),
},
-1,
output);
if (!output->isEmpty()) {
q->printer.printMessage(QString(output->constData()));
}
auto err = util::Exec("sh", args, -1, output);
if (err) {
q->printer.printMessage("git clone failed. " + err.message());
output->clear();
q->printer.printMessage("download source failed." + err.message(), 2);
return NewError(-1, "download source failed." + err.message());
}
QDir::setCurrent(sourceTargetPath());
q->printer.printMessage(
QString("git checkout -b %1 %2").arg(source->version).arg(source->commit),
2);
err = util::Exec("git",
{
"checkout",
"-b",
source->version,
source->commit,
},
-1,
output);
if (!output->isEmpty()) {
q->printer.printMessage(QString(output->constData()));
if (!dir.isNull()) {
dir->remove();
}
if (err) {
q->printer.printMessage("git checkout failed. " + err.message(), 2);
output->clear();
}
q->printer.printMessage(QString("git reset --hard %1").arg(source->commit), 2);
err = util::Exec("git",
{
"reset",
"--hard",
source->commit,
},
-1,
output);
if (!output->isEmpty()) {
q->printer.printMessage(QString(output->constData()), 2);
}
return WrapError(err, "git reset failed");
return Success();
}
util::Error SourceFetcherPrivate::handleLocalPatch()

View File

@ -14,5 +14,6 @@
#define LINGLONG_DATA_DIR "@CMAKE_INSTALL_FULL_DATADIR@/linglong"
#define LINGLONG_USERNAME "@LINGLONG_USERNAME@"
#define LINGLONG_VERSION "@PROJECT_VERSION@"
#define LINGLONG_LIBEXEC_DIR "@CMAKE_INSTALL_FULL_LIBEXECDIR@/linglong"
#endif

View File

@ -6,6 +6,8 @@
#include "linglong/utils/global/initialize.h"
#include "linglong/util/configure.h"
#include <systemd/sd-journal.h>
#include <QCoreApplication>
@ -119,4 +121,10 @@ void installMessageHandler()
qInstallMessageHandler(linglong_message_handler);
}
// Return current binary file is installed on the system
bool linglongInstalled()
{
return QCoreApplication::applicationDirPath() == BINDIR;
}
} // namespace linglong::utils::global

View File

@ -11,6 +11,7 @@ namespace linglong::utils::global {
void applicationInitializte();
void installMessageHandler();
bool linglongInstalled();
} // namespace linglong::utils::global