Добавлена команда импорта 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("init", "Initializing the repository for storing snapshots"))
.add(new Command("status", "Checking the status of tracked files")) .add(new Command("status", "Checking the status of tracked files"))
.add(new Command("diff", "Show changed data")) .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 Command("export", "Export snapshot to a tar.gz archive")
.add(new Argument("path", "Output directory path for the archive").required) .add(new Argument("path", "Output directory path for the archive").required)
.add(new Option("s", "snapshot", "Specify snapshot hash") .add(new Option("s", "snapshot", "Specify snapshot hash")
@ -123,6 +147,14 @@ int main(string[] args)
e.arg("path"), e.arg("path"),
e.option("snapshot", ""), e.option("snapshot", ""),
) )
)
.on("import", i =>
snag.importSnapshot(
i.arg("archive"),
i.option("comment", ""),
i.option("author", ""),
i.option("email", "")
)
); );
} catch (SnagException e) { } catch (SnagException e) {
e.print(); e.print();

View file

@ -290,4 +290,99 @@ class Snag {
); );
writeln("Export to archive completed successfully: ", file); 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);
}
} }