1 module reggae.backend.tup;
2 
3 
4 import reggae.build;
5 import reggae.range;
6 import reggae.options;
7 import std.array;
8 import std.typecons;
9 
10 @safe:
11 
12 struct Tup {
13     enum fileName = "Tupfile";
14 
15     Build build;
16     const(Options) options;
17 
18     this(Build build, in string projectPath) {
19         import reggae.config: options;
20         auto modOptions = options.dup;
21         modOptions.projectPath = projectPath;
22         this(build, modOptions);
23     }
24 
25     this(Build build, in Options options) {
26         this.build = build;
27         this.options = options;
28     }
29 
30     string output() pure {
31         auto ret = banner ~ lines.join("\n") ~ "\n";
32         if(options.export_) ret = options.eraseProjectPath(ret);
33         return ret;
34     }
35 
36     string[] lines() pure {
37 
38         string[] lines;
39         foreach(target; build.range) {
40             if(target.getCommandType == CommandType.code)
41                 throw new Exception("Command type 'code' not supported for tup backend");
42 
43             //tup does its own dependency detection, trying to output
44             //dependency files actually causes an error, so we request
45             //none to be generated
46             immutable line = ": " ~
47                 target.dependenciesInProjectPath(options.projectPath).join(" ") ~ " |> " ~
48                 target.shellCommand(options, No.dependencies) ~ " |> " ~
49                 target.expandOutputs(options.projectPath).join(" ");
50             lines ~= line;
51         }
52         return lines;
53     }
54 
55     void writeBuild() @system {
56         import std.file;
57         import std.string;
58         import std.stdio;
59         import std.path;
60         import std.process;
61 
62         if(!".tup".exists) {
63             immutable args = ["tup", "init"];
64             const string[string] env = null;
65             Config config = Config.none;
66             size_t maxOutput = size_t.max;
67 
68             try
69                 execute(args, env, config, maxOutput, options.workingDir);
70             catch(ProcessException _)
71                 stderr.writeln("Could not execute '", args.join(" "),
72                                "'. tup builds need to do that first.");
73         }
74         auto file = File(buildPath(options.workingDir, fileName), "w");
75         file.write(output);
76     }
77 }