1 /**
2  * Copyright: Copyright Jason White, 2016
3  * License:   MIT
4  * Authors:   Jason White
5  *
6  * Description:
7  * Initializes a directory with an initial build description. This is useful
8  * to quickly get up and running when creating first creating a build
9  * description for the first time on a project.
10  *
11  * This makes the assumption that you want to use Lua as your build description
12  * language and creates an initial BUILD.lua file for you.
13  */
14 module button.cli.init;
15 
16 import io;
17 
18 import button.cli.options : InitOptions, GlobalOptions;
19 
20 /**
21  * Contents of .gitignore
22  */
23 immutable gitIgnoreContents = q"EOS
24 # Generated Button files
25 .BUILD.lua.json
26 .*.json.state
27 EOS";
28 
29 /**
30  * Path to the root build description template.
31  */
32 immutable rootTemplate = "button.json";
33 
34 /**
35  * Contents of the root build description.
36  *
37  * In general this file should always be a wrapper for generating a build
38  * description. Thus, this should never need to be modified by hand.
39  *
40  * Here, we assume we want to use button-lua to generate the build description.
41  */
42 immutable rootTemplateContents = q"EOS
43 [
44     {
45         "inputs": ["BUILD.lua"],
46         "task": [["button-lua", "BUILD.lua", "-o", ".BUILD.lua.json"]],
47         "outputs": [".BUILD.lua.json"]
48     },
49     {
50         "inputs": [".BUILD.lua.json"],
51         "task": [["button", "build", "--color=always", "-f", ".BUILD.lua.json"]],
52         "outputs": [".BUILD.lua.json.state"]
53     }
54 ]
55 EOS";
56 
57 /**
58  * Path to the Lua build description template.
59  */
60 immutable luaTemplate = "BUILD.lua";
61 
62 /**
63  * Contents of the BUILD.lua file.
64  *
65  * TODO: Give more a more useful starting point. This should include:
66  *  1. A link to the documentation (when it finally exists).
67  *  2. A simple hello world example.
68  */
69 immutable luaTemplateContents = q"EOS
70 --[[
71     This is the top-level build description. This is where you either create
72     build rules or delegate to other Lua scripts to create build rules.
73 
74     See the documentation for more information on how to get started.
75 ]]
76 
77 EOS";
78 
79 
80 int initCommand(InitOptions opts, GlobalOptions globalOpts)
81 {
82     import std.path : buildPath;
83     import std.file : FileException, mkdirRecurse;
84 
85     try
86     {
87         // Ensure the directory and its parents exist. This will be used to
88         // store the root build description and the build state.
89         mkdirRecurse(opts.dir);
90     }
91     catch (FileException e)
92     {
93         println(e.msg);
94         return 1;
95     }
96 
97     try
98     {
99         File(buildPath(opts.dir, ".gitignore"), FileFlags.writeNew)
100             .write(gitIgnoreContents);
101     }
102     catch (SysException e)
103     {
104         // Don't care if it already exists.
105     }
106 
107     try
108     {
109         // Create the root build description
110         File(buildPath(opts.dir, rootTemplate), FileFlags.writeNew)
111             .write(rootTemplateContents);
112 
113         // Create BUILD.lua
114         File(buildPath(opts.dir, luaTemplate), FileFlags.writeNew)
115             .write(luaTemplateContents);
116     }
117     catch (SysException e)
118     {
119         println("Error: ", e.msg);
120         println("       Looks like you already ran `button init`.");
121         return 1;
122     }
123 
124     return 0;
125 }