1 /+
2     This file is part of Reloaded Vibes.
3     Copyright (c) 2019  0xEAB
4 
5     Distributed under the Boost Software License, Version 1.0.
6        (See accompanying file LICENSE_1_0.txt or copy at
7              https://www.boost.org/LICENSE_1_0.txt)
8  +/
9 module reloadedvibes.action;
10 
11 import std.stdio : stderr, stdout;
12 import std.process : spawnShell, wait;
13 import reloadedvibes.watcher;
14 
15 alias Action = void delegate() @safe;
16 
17 final class ActionWatcherClient : WatcherClient
18 {
19     private
20     {
21         Action _action;
22     }
23 
24     public this(Watcher w, Action action) @safe pure nothrow
25     {
26         super(w);
27         this._action = action;
28     }
29 
30     public override void notify() @safe
31     {
32         this._action();
33         this.setNotified();
34     }
35 }
36 
37 ActionWatcherClient fromCommandLines(Watcher w, string[] commandLines)
38 {
39     enum sepLine = "-------------------------------------------------------------------------------";
40     enum segmentPre = "----{ ";
41     enum segmentPost = " }";
42     enum segmentsLength = (segmentPre.length + segmentPost.length);
43     enum embeddedCMDMaxLength = 79 - segmentsLength;
44 
45     string[] sep = new string[commandLines.length];
46 
47     foreach (idx, cmd; commandLines)
48     {
49         if (cmd.length >= embeddedCMDMaxLength)
50         {
51             sep[idx] = sepLine ~ "\n" ~ cmd ~ "\n" ~ sepLine ~ "\n";
52             continue;
53         }
54 
55         immutable rest = embeddedCMDMaxLength - cmd.length;
56         sep[idx] = segmentPre ~ cmd ~ segmentPost ~ sepLine[0 .. rest] ~ "\n";
57     }
58 
59     return new ActionWatcherClient(w, delegate() @trusted {
60         foreach (idx, cmd; commandLines)
61         {
62             try
63             {
64                 stdout.writeln("\n", sep[idx]);
65                 immutable exitCode = spawnShell(cmd).wait();
66 
67                 if (exitCode != 0)
68                 {
69                     stderr.writeln("\n", sepLine,
70                         "\nAction {" ~ cmd ~ "} failed with exit code ", exitCode);
71                 }
72             }
73             catch (Exception ex)
74             {
75                 stderr.writeln("\n", sepLine, "\nAction {" ~ cmd ~ "} failed: ", ex.msg);
76             }
77             finally
78             {
79                 stdout.writeln("\n");
80             }
81         }
82     });
83 }