From dd5d57c75ba291d59a4da52f778932fb4ea22118 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Sun, 25 May 2025 01:27:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D1=8B=D0=BB=20=D0=BF=D1=80=D0=BE=D0=B8?= =?UTF-8?q?=D0=B7=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=20=D1=80=D0=B5=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20=D0=B2=D1=8B=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE=D0=B2=20git.=20=D0=9D=D0=B5=D0=BE=D0=B1?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE=20=D0=B4=D0=BE=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D1=82=D1=8C=20create,=20=D1=82=D0=B0?= =?UTF-8?q?=D0=BA=20=D0=BA=D0=B0=D0=BA=20=D0=BF=D1=80=D0=B8=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=BC?= =?UTF-8?q?=D0=B8=D1=82=D0=B0=20=D0=B2=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=82=D0=B2=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B8=D1=85?= =?UTF-8?q?=D0=BE=D0=B4=D0=B8=D1=82=20"=D0=BF=D1=80=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=BE=D1=81"=20=D0=BD=D0=B5=D0=BD=D1=83=D0=B6=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2=20=D0=B2=20=D0=B2?= =?UTF-8?q?=D1=8B=D1=88=D0=B5=D1=81=D1=82=D0=BE=D1=8F=D1=89=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82=D1=8B,=20=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D1=85=20=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82?= =?UTF-8?q?=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/snag/core/core.d | 261 ++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 174 deletions(-) diff --git a/source/snag/core/core.d b/source/snag/core/core.d index b09fb89..c283cc8 100644 --- a/source/snag/core/core.d +++ b/source/snag/core/core.d @@ -28,32 +28,28 @@ class Snag { _config = config; } + private auto git(string[] command, string message, string separator = ":\n") { + auto result = execute(_baseCommand ~ command); + if (result.status) + throw new SnagException( + message ~ separator ~ result.output + ); + return result; + } + void initialize() { - auto result = execute(_baseCommand ~ "init"); - if (result.status) - throw new SnagException( - "A Git repository initialization error occurred:\n" - ~ result.output - ); - - result = execute( - _baseCommand ~ ["config", "user.email", _config.email] + git( + ["init"], + "A Git repository initialization error occurred" ); - if (result.status) - throw new SnagException( - "A Git repository initialization error occurred:\n" - ~ result.output - ); - - result = execute( - _baseCommand ~ ["config", "user.name", _config.user] + git( + ["config", "user.email", _config.email], + "A Git repository initialization error occurred" + ); + git( + ["config", "user.name", _config.user], + "A Git repository initialization error occurred" ); - if (result.status) - throw new SnagException( - "A Git repository initialization error occurred:\n" - ~ result.output - ); - writeln( "The Git repository has been initialized successfully: " ~ _config.git @@ -61,50 +57,36 @@ class Snag { } void status() { - auto result = execute( - _baseCommand ~ ["status", "--porcelain"] + auto result = git( + ["status", "--porcelain"], + "An error occurred while checking the file tracking status" ); - if (result.status) - throw new SnagException( - "An error occurred while checking the file tracking status:\n" - ~ result.output - ); 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]); }); } void create() { - /** - * Проверка файлов на состояние изменения - */ - auto result = execute( - _baseCommand ~ ["status", "--porcelain"] + auto result = git( + ["status", "--porcelain"], + "An error occurred while checking the file tracking status" ); - if (result.status) - throw new SnagException( - "An error occurred while checking the file tracking status:\n" - ~ result.output - ); + if (!result.output.length) throw new SnagException( "Current file state doesn't need to be archived again" ); - result = execute( - _baseCommand ~ [ - "rev-parse", "--short", "HEAD" - ] - ); - if (result.status) + result = execute(_baseCommand ~ ["rev-parse", "--short", "HEAD"]); + if (result.status == 128) { + git(["add", "."], "Failed to prepare files for archiving"); + git(["commit", "-m", "test"], "Failed to create a backup"); + writeln("Backup was created successfully"); + return; + } else if (result.status != 0) throw new SnagException( "Failed to retrieve current snapshot information:\n" ~ result.output @@ -112,113 +94,67 @@ class Snag { string currentSnapshot = result.output.strip('\n'); - result = execute( - _baseCommand ~ [ - "checkout", - "-b", - "mod", - currentSnapshot - ] + git( + ["checkout", "-b", "mod", currentSnapshot ], + "Failed to create a branch from the current state" + ); + git( + ["add", "."], + "Failed to prepare files for archiving" + ); + git( + ["commit", "-m", "test"], + "Failed to create a backup" + ); + git( + ["checkout", "master"], + "Failed to perform intermediate state switching" + ); + git( + ["rebase", "--onto", "mod", currentSnapshot, "master", "-X", "theirs"], + "Ошибка при rebase" ); - result = execute( - _baseCommand ~ ["add", "."] + result = git( + ["rev-parse", "--short", "mod"], + "An error occurred while checking the file tracking status" ); - if (result.status) - throw new SnagException( - "Failed to prepare files for archiving:\n" - ~ result.output - ); - result = execute( - _baseCommand ~ ["commit", "-m", "test"] - ); - if (result.status) - throw new SnagException( - "Failed to create a backup:\n" - ~ result.output - ); + string newSnapshot = result.output.strip('\n'); - result = execute( - _baseCommand ~ ["checkout", "master"] + git( + ["checkout", newSnapshot], + "Failed to perform intermediate state switching" ); - if (result.status) - throw new SnagException( - "Failed to perform intermediate state switching:\n" - ~ result.output - ); - - result = execute( - _baseCommand ~ [ - "merge", - "-X", - "theirs", - "--squash", - "mod" - ] + git( + ["branch", "-D", "mod"], + "Error while deleting temporary intermediate snapshot" ); - if (result.status) - throw new SnagException( - "Failed to retrieve changes from the new intermediate snapshot:\n" - ~ result.output - ); - - result = execute( - _baseCommand ~ ["commit", "-m", "test"] - ); - if (result.status) - throw new SnagException( - "Failed to create backup after acquiring new intermediate snapshot:\n" - ~ result.output - ); - - result = execute( - _baseCommand ~ ["branch", "-D", "mod"] - ); - if (result.status) - throw new SnagException( - "Error while deleting temporary intermediate snapshot:\n" - ~ result.output - ); - writeln("Backup was created successfully"); } void list() { - auto result = execute( - _baseCommand ~ [ - "rev-parse", "--short", "HEAD" - ] + auto result = git( + ["rev-parse", "--short", "HEAD"], + "Failed to retrieve current snapshot information" ); - if (result.status) - throw new SnagException( - "Failed to retrieve current snapshot information:\n" - ~ result.output - ); string current = result.output.strip('\n'); - result = execute( - _baseCommand ~ [ + result = git( + [ "log", "--all", "--date=format:%Y.%m.%d %H:%M", "--pretty=format:%ad\t%h" - ] + ], + "Failed to retrieve the list of snapshots" ); - if (result.status) - throw new SnagException( - "Failed to retrieve the list of snapshots:\n" - ~ result.output - ); - result.output.split('\n').each!((e) { - auto eArray = e.split('\t'); - if (current == eArray[1]) - writefln(" >\t%s\t%s", eArray[0], eArray[1]); - else - writefln("\t%s\t%s", eArray[0], eArray[1]); - }); + result.output.split('\n').map!(line => line.split('\t')).array + .sort!((a, b) => a[0] > b[0]).each!(e => + writefln("%s\t%s\t%s", current == e[1] ? " >" : "", e[0], e[1]) + ); } void restore(string hash) { @@ -227,48 +163,25 @@ class Snag { "Invalid snapshot hash provided" ); - auto result = execute( - _baseCommand ~ ["status", "--porcelain"] + auto result = git( + ["status", "--porcelain"], + "An error occurred while checking the file tracking status" ); - if (result.status) - throw new SnagException( - "An error occurred while checking the file tracking status:\n" - ~ result.output + + if (result.output.length) + git( + ["restore", "."], + "Failed to reset file changes state" ); - if (result.output.length) { - result = execute( - _baseCommand ~ ["restore", "."] - ); - if (result.status) - throw new SnagException( - "Failed to reset file changes state:\n" - ~ result.output - ); - } - - result = execute( - _baseCommand ~ [ - "rev-parse", hash - ] + git( + ["rev-parse", hash], + "This snapshot is not available in the archive" ); - if (result.status) - throw new SnagException( - "This snapshot is not available in the archive:\n" - ~ result.output.split('\n')[0] - ); - - result = execute( - _baseCommand ~ [ - "checkout", hash - ] + git( + ["checkout", hash], + "Failed to restore the snapshot state " ~ hash ); - if (result.status) - throw new SnagException( - "Failed to restore the snapshot state %s:\n" - .format(hash, result.output) - ); - writeln("Backup was restored successfully"); } }