Compare commits
4 commits
016455d8f2
...
f924800387
Author | SHA1 | Date | |
---|---|---|---|
f924800387 | |||
a2131ec574 | |||
5f746c33b7 | |||
9f8759238b |
6 changed files with 101 additions and 23 deletions
|
@ -4,12 +4,11 @@
|
|||
"email": "user@site.domain",
|
||||
"author": "snag",
|
||||
"presnag": [
|
||||
"/usr/bin/ls",
|
||||
"/usr/local/bin/script.sh"
|
||||
"echo $(which ls)",
|
||||
"pwd"
|
||||
],
|
||||
"postsnag": [
|
||||
"/usr/bin/ls",
|
||||
"/usr/local/bin/script.sh"
|
||||
"/usr/bin/ls"
|
||||
],
|
||||
"rules": {
|
||||
"tracking": [
|
||||
|
|
48
source/app.d
48
source/app.d
|
@ -63,6 +63,14 @@ int main(string[] args)
|
|||
"must contain an email address"
|
||||
)
|
||||
)
|
||||
.add(new Flag(null, "no-presnag", "Execution without running pre-execution commands")
|
||||
.name("nopre")
|
||||
.optional
|
||||
)
|
||||
.add(new Flag(null, "no-postsnag", "Execution without running post-execution commands")
|
||||
.name("nopost")
|
||||
.optional
|
||||
)
|
||||
)
|
||||
.add(new Command("export", "Export snapshot to a tar.gz archive")
|
||||
.add(new Argument("path", "Output directory path for the archive").required)
|
||||
|
@ -96,6 +104,14 @@ int main(string[] args)
|
|||
"must contain an email address"
|
||||
)
|
||||
)
|
||||
.add(new Flag(null, "no-presnag", "Execution without running pre-execution commands")
|
||||
.name("nopre")
|
||||
.optional
|
||||
)
|
||||
.add(new Flag(null, "no-postsnag", "Execution without running post-execution commands")
|
||||
.name("nopost")
|
||||
.optional
|
||||
)
|
||||
)
|
||||
.add(new Command("list", "List of snapshots")
|
||||
.add(new Flag("c", "comment", "Show comment")
|
||||
|
@ -113,6 +129,14 @@ int main(string[] args)
|
|||
)
|
||||
.add(new Command("restore", "Restore to the specified snapshot state")
|
||||
.add(new Argument("snapshot", "Specify snapshot hash").required)
|
||||
.add(new Flag(null, "no-presnag", "Execution without running pre-execution commands")
|
||||
.name("nopre")
|
||||
.optional
|
||||
)
|
||||
.add(new Flag(null, "no-postsnag", "Execution without running post-execution commands")
|
||||
.name("nopost")
|
||||
.optional
|
||||
)
|
||||
)
|
||||
.add(new Option("c", "config", "Сonfiguration file path")
|
||||
.optional
|
||||
|
@ -147,13 +171,15 @@ int main(string[] args)
|
|||
.on("status", status =>
|
||||
snag.status()
|
||||
)
|
||||
.on("create", create =>
|
||||
.on("create", (create) {
|
||||
create.flag("nopre") || snag.executePreSnag();
|
||||
snag.create(
|
||||
create.option("comment", ""),
|
||||
create.option("author", ""),
|
||||
create.option("email", "")
|
||||
)
|
||||
)
|
||||
);
|
||||
create.flag("nopost") || snag.executePostSnag();
|
||||
})
|
||||
.on("list", list =>
|
||||
snag.list(
|
||||
list.flag("comment"),
|
||||
|
@ -161,23 +187,27 @@ int main(string[] args)
|
|||
list.flag("email")
|
||||
)
|
||||
)
|
||||
.on("restore", restore =>
|
||||
snag.restore(restore.arg("snapshot"))
|
||||
)
|
||||
.on("restore", (restore) {
|
||||
restore.flag("nopre") || snag.executePreSnag();
|
||||
snag.restore(restore.arg("snapshot"));
|
||||
restore.flag("nopost") || snag.executePostSnag();
|
||||
})
|
||||
.on("export", e =>
|
||||
snag.exportSnapshot(
|
||||
e.arg("path"),
|
||||
e.option("snapshot", ""),
|
||||
)
|
||||
)
|
||||
.on("import", i =>
|
||||
.on("import", (i) {
|
||||
i.flag("nopre") || snag.executePreSnag();
|
||||
snag.importSnapshot(
|
||||
i.arg("archive"),
|
||||
i.option("comment", ""),
|
||||
i.option("author", ""),
|
||||
i.option("email", "")
|
||||
)
|
||||
)
|
||||
);
|
||||
i.flag("nopost") || snag.executePostSnag();
|
||||
})
|
||||
.on("rules", (r) {
|
||||
auto rules = new SnagRules(config);
|
||||
r
|
||||
|
|
|
@ -17,6 +17,8 @@ class SnagConfig {
|
|||
private string _author;
|
||||
private string[] _tracking;
|
||||
private string[] _ignore;
|
||||
private string[] _presnag;
|
||||
private string[] _postsnag;
|
||||
|
||||
this(string configFile) {
|
||||
string jsonText;
|
||||
|
@ -119,6 +121,22 @@ class SnagConfig {
|
|||
_ignore = rules["ignore"].array.map!(item => item.str).array;
|
||||
}
|
||||
}
|
||||
|
||||
if ("presnag" in jsonData) {
|
||||
if (jsonData["presnag"].type != JSONType.array)
|
||||
throw new SnagConfigException(
|
||||
"The \"presnag\" parameter must be an array containing a set of commands"
|
||||
);
|
||||
_presnag = jsonData["presnag"].array.map!(item => item.str).array;
|
||||
}
|
||||
|
||||
if ("postsnag" in jsonData) {
|
||||
if (jsonData["postsnag"].type != JSONType.array)
|
||||
throw new SnagConfigException(
|
||||
"The \"postsnag\" parameter must be an array containing a set of commands"
|
||||
);
|
||||
_postsnag = jsonData["postsnag"].array.map!(item => item.str).array;
|
||||
}
|
||||
}
|
||||
|
||||
@property string git() const { return _git; }
|
||||
|
@ -127,4 +145,6 @@ class SnagConfig {
|
|||
@property string author() const { return _author; }
|
||||
@property const(string[]) tracking() const { return _tracking; }
|
||||
@property const(string[]) ignore() const { return _ignore; }
|
||||
@property const(string[]) presnag() const { return _presnag; }
|
||||
@property const(string[]) postsnag() const { return _postsnag; }
|
||||
}
|
||||
|
|
|
@ -61,6 +61,32 @@ class Snag {
|
|||
return formatted && fullStatus.length < 8 ? fullStatus ~ "\t" : fullStatus;
|
||||
}
|
||||
|
||||
void executePreSnag() {
|
||||
_config.presnag().each!((command) {
|
||||
auto result = executeShell(command);
|
||||
result.status && throw new SnagException(
|
||||
"%s:\n\t%s\n\n%s".format(
|
||||
"An error occurred during presnag-command execution",
|
||||
command,
|
||||
result.output
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void executePostSnag() {
|
||||
_config.postsnag().each!((command) {
|
||||
auto result = executeShell(command);
|
||||
result.status && throw new SnagException(
|
||||
"%s:\n\t%s\n\n%s".format(
|
||||
"An error occurred during postsnag-command execution",
|
||||
command,
|
||||
result.output
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void initialize(bool force) {
|
||||
auto result = execute(_baseCommand ~ ["rev-parse", "--git-dir"]);
|
||||
!force && !result.status &&
|
||||
|
@ -127,13 +153,18 @@ class Snag {
|
|||
email.length && (environment["GIT_AUTHOR_EMAIL"] = email);
|
||||
|
||||
string message = comment.length ? comment : "Standard snapshot creation";
|
||||
string newSnapshot;
|
||||
|
||||
result = execute(_baseCommand ~ ["rev-parse", "--short", "HEAD"]);
|
||||
if (result.status == 128) {
|
||||
// Если это самый первый коммит после инициализации репозитория
|
||||
git(["add", "."], "Failed to prepare files for archiving");
|
||||
git(["commit", "-m"] ~ message, "Failed to create a backup");
|
||||
writeln("Backup was created successfully");
|
||||
git(["commit", "-m"] ~ message, "Failed to create a snapshot");
|
||||
newSnapshot = git(
|
||||
["rev-parse", "--short", "HEAD"],
|
||||
"Failed to retrieve current snapshot information"
|
||||
).output.strip('\n');
|
||||
writeln("Snapshot was created successfully: ", newSnapshot);
|
||||
return;
|
||||
} else if (result.status != 0)
|
||||
throw new SnagException(
|
||||
|
@ -157,8 +188,6 @@ class Snag {
|
|||
"Failed to get the commit list between HEAD and " ~ currentBranch
|
||||
);
|
||||
|
||||
string newSnapshot;
|
||||
|
||||
// Если список существует
|
||||
if (result.output.length) {
|
||||
// Если коммит не является последним, то необходимо ответвление
|
||||
|
@ -173,7 +202,7 @@ class Snag {
|
|||
);
|
||||
git(
|
||||
["commit", "-m"] ~ message,
|
||||
"Failed to create a backup"
|
||||
"Failed to create a snapshot"
|
||||
);
|
||||
newSnapshot = git(
|
||||
["rev-parse", "--short", "HEAD"],
|
||||
|
@ -187,7 +216,7 @@ class Snag {
|
|||
);
|
||||
git(
|
||||
["commit", "-m"] ~ message,
|
||||
"Failed to create a backup"
|
||||
"Failed to create a snapshot"
|
||||
);
|
||||
newSnapshot = git(
|
||||
["rev-parse", "--short", "HEAD"],
|
||||
|
@ -202,7 +231,7 @@ class Snag {
|
|||
"Issue with including the commit into the branch " ~ currentBranch
|
||||
);
|
||||
}
|
||||
writeln("Backup was created successfully: ", newSnapshot);
|
||||
writeln("Snapshot was created successfully: ", newSnapshot);
|
||||
}
|
||||
|
||||
void list(bool comment, bool author, bool email) {
|
||||
|
|
|
@ -86,7 +86,7 @@ class SnagRules {
|
|||
git(
|
||||
["diff", "--cached", "--name-only"],
|
||||
"Failed to retrieve the list of files removed from tracking"
|
||||
).output.split('\n')[0..$-1].each!(
|
||||
).output.split('\n').filter!(e => !e.strip.empty).each!(
|
||||
file => git(
|
||||
["add", "-f", file],
|
||||
"Failed to restore the file to tracking"
|
||||
|
@ -98,7 +98,7 @@ class SnagRules {
|
|||
git(
|
||||
["ls-files", "-i", "-c", "--exclude-standard"],
|
||||
"Failed to get the list of files to remove from tracking"
|
||||
).output.split('\n')[0..$-1].each!(
|
||||
).output.split('\n').filter!(e => !e.strip.empty).each!(
|
||||
file => git(
|
||||
["rm", "--cached", file],
|
||||
"Failed to remove file from tracking"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module snag.version_;
|
||||
|
||||
enum snagVersion = "0.0.11";
|
||||
enum snagVersion = "0.0.12";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue