Добавлена команда export для экспорта в архив tar.gz файлов указанного состояния снимка, по умолчанию экспортируется текущее состояние снимка

This commit is contained in:
Alexander Zhirov 2025-05-26 02:14:18 +03:00
parent 4301c27ca9
commit 4590ee5fbc
Signed by: alexander
GPG key ID: C8D8BE544A27C511
3 changed files with 72 additions and 11 deletions

View file

@ -12,6 +12,16 @@ 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("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")
.optional
.validateEachWith(
opt => opt.isValidHash,
"must contain snapshot hash provided"
)
)
)
.add(new Command("create", "Create a new snapshot")
.add(new Option("c", "comment", "Specify comment")
.optional
@ -50,7 +60,7 @@ int main(string[] args)
)
)
.add(new Command("restore", "Restore to the specified snapshot state")
.add(new Argument("hash", "hash").required)
.add(new Argument("snapshot", "Specify snapshot hash").required)
)
.add(new Option("c", "config", "Сonfiguration file path")
.optional
@ -100,7 +110,13 @@ int main(string[] args)
)
)
.on("restore", restore =>
snag.restore(restore.arg("hash"))
snag.restore(restore.arg("snapshot"))
)
.on("export", e =>
snag.exportSnapshot(
e.arg("path"),
e.option("snapshot", ""),
)
);
} catch (SnagException e) {
e.print();

View file

@ -8,6 +8,8 @@ import std.array;
import std.process;
import std.algorithm;
import std.string;
import std.file;
import std.path;
import snag.lib;
import snag.core.exception;
@ -22,10 +24,9 @@ class Snag {
"git --git-dir=%s --work-tree=%s",
config.git, config.project
).split();
_config = config;
auto currentTime = Clock.currTime();
_date = format("%02d%03d%02d%02d%02d",
currentTime.year % 100,
currentTime.dayOfYear,
@ -67,12 +68,10 @@ class Snag {
["status", "--porcelain"],
"An error occurred while checking the file tracking status"
);
if (!result.output.length) {
writeln("The current state of the files is up to date as of the latest snapshot");
return;
}
writeln("The following list of files requires backup:");
result.output.split('\n').filter!(e => !e.strip.empty).each!((e) {
writefln("\t/%s", e.strip.split[1]);
@ -205,18 +204,20 @@ class Snag {
throw new SnagException(
"Invalid snapshot hash provided"
);
auto result = git(
["status", "--porcelain"],
"An error occurred while checking the file tracking status"
);
if (result.output.length)
if (result.output.length) {
git(
["restore", "."],
"Failed to reset file changes state"
);
git(
["clean", "-fd"],
"Failed to clean untracked files"
);
}
git(
["rev-parse", hash],
"This snapshot is not available in the archive"
@ -239,4 +240,48 @@ class Snag {
}
writeln("No changes at the moment");
}
void exportSnapshot(string path, string hash) {
try {
!path.isDir &&
throw new SnagException(
"Path is not a directory"
);
} catch (Exception e) {
throw new SnagException(
"Failed to verify the archive output directory:\n\t"
~ e.msg
);
}
if (hash.length) {
!isValidHash(hash) &&
throw new SnagException(
"Invalid snapshot hash provided"
);
git(
["rev-parse", hash],
"This snapshot is not available in the archive"
);
} else {
hash = git(
["rev-parse", "--short", "HEAD"],
"Failed to retrieve current snapshot information"
).output.strip('\n');
}
string file = buildPath(
path.absolutePath.buildNormalizedPath,
"%s-%s.tar.gz".format(_date, hash)
);
git(
[
"archive",
"--format=tar.gz",
hash,
"-o",
file
],
"Failed to export snapshot to archive"
);
writeln("Export to archive completed successfully: ", file);
}
}

View file

@ -1,3 +1,3 @@
module snag.version_;
enum snagVersion = "0.0.8";
enum snagVersion = "0.0.9";