Добавлена команда импорта import из архива tar.gz

This commit is contained in:
Alexander Zhirov 2025-05-26 23:13:54 +03:00
parent cc85cdec78
commit 9c4c2c9d05
Signed by: alexander
GPG key ID: C8D8BE544A27C511
2 changed files with 127 additions and 0 deletions

View file

@ -18,6 +18,30 @@ int main(string[] args)
.add(new Command("init", "Initializing the repository for storing snapshots"))
.add(new Command("status", "Checking the status of tracked files"))
.add(new Command("diff", "Show changed data"))
.add(new Command("import", "Import snapshot from a tar.gz archive")
.add(new Argument("archive", "The path to the tar.gz archive file").required)
.add(new Option("c", "comment", "Specify comment")
.optional
.validateEachWith(
opt => opt.length > 0,
"cannot be empty"
)
)
.add(new Option("a", "author", "Specify author")
.optional
.validateEachWith(
opt => opt.length > 0,
"cannot be empty"
)
)
.add(new Option("e", "email", "Specify email")
.optional
.validateEachWith(
opt => opt.isValidEmail,
"must contain an email address"
)
)
)
.add(new Command("export", "Export snapshot to a tar.gz archive")
.add(new Argument("path", "Output directory path for the archive").required)
.add(new Option("s", "snapshot", "Specify snapshot hash")
@ -123,6 +147,14 @@ int main(string[] args)
e.arg("path"),
e.option("snapshot", ""),
)
)
.on("import", i =>
snag.importSnapshot(
i.arg("archive"),
i.option("comment", ""),
i.option("author", ""),
i.option("email", "")
)
);
} catch (SnagException e) {
e.print();

View file

@ -290,4 +290,99 @@ class Snag {
);
writeln("Export to archive completed successfully: ", file);
}
void importSnapshot(string path, string comment, string author, string email) {
try {
(!path.isFile || !path.endsWith("tar.gz")) &&
throw new SnagException(
"Path is not an archive file"
);
} catch (Exception e) {
throw new SnagException(
"Failed to verify the archive file:\n\t"
~ e.msg
);
}
string newBranch = _date ~ "-import";
string tempDirectory = tempDir().buildPath(newBranch);
mkdir(tempDirectory);
scope(exit) tempDirectory.exists
&& tempDirectory.isDir
&& tempDirectory.rmdirRecurse;
auto result = execute([
"tar", "xf", path, "-C", tempDirectory
]);
result.status &&
throw new SnagException(
"The error occurred during decompression (or unpacking) of the archive:\n\t"
~ result.output.split('\n')[0]
);
// Выполнение git команд относительно распакованного архива
string[] customCommand = format(
"git --git-dir=%s --work-tree=%s",
_config.git, tempDirectory
).split();
// Необходимо проверить, что текущее состояние файлов не идентично файлам распакованного архива
result = execute(customCommand ~ ["status", "--porcelain"]);
result.status &&
throw new SnagException(
"An error occurred while checking the file tracking status:\n"
~ result.output.split('\n')[0]
);
// Если текущее состояние файлов идентично файлам распакованного архива
!result.output.length &&
throw new SnagException(
"Import aborted:\n\t"
~ "The new state of the files is up to date as of the current snapshot"
);
git(
["checkout", "--orphan", newBranch ],
"Failed to create a branch from the new state"
);
// Создание нового снимка на основе состояния файлов из распакованного архива
result = execute(customCommand ~ ["add", "."]);
result.status &&
throw new SnagException(
"Failed to prepare files for archiving:\n"
~ result.output.split('\n')[0]
);
author.length && (environment["GIT_AUTHOR_NAME"] = author);
email.length && (environment["GIT_AUTHOR_EMAIL"] = email);
string message = comment.length ? comment : "Creating a snapshot from import";
result = execute(customCommand ~ ["commit", "-m"] ~ message);
result.status &&
throw new SnagException(
"Failed to create a snapshot:\n"
~ result.output.split('\n')[0]
);
// Сброс состояния файлов
git(
["restore", "."],
"Failed to reset file changes state"
);
git(
["clean", "-fd"],
"Failed to clean untracked files"
);
string newSnapshot = git(
["rev-parse", "--short", "HEAD"],
"Failed to retrieve current snapshot information"
).output.strip('\n');
writeln("Import completed successfully: ", newSnapshot);
}
}