1 /** 2 * Copyright: Copyright Jason White, 2016 3 * License: MIT 4 * Authors: Jason White 5 * 6 * Description: 7 * Command to delete outputs. 8 */ 9 module button.cli.clean; 10 11 import button.cli.options : CleanOptions, GlobalOptions; 12 13 import io.text, io.file.stdio; 14 15 import button.state, 16 button.rule, 17 button.graph, 18 button.build, 19 button.textcolor, 20 button.exceptions; 21 22 /** 23 * Deletes outputs. 24 */ 25 int cleanCommand(CleanOptions opts, GlobalOptions globalOpts) 26 { 27 import std.getopt; 28 import std.file : remove; 29 30 immutable color = TextColor(colorOutput(opts.color)); 31 32 try 33 { 34 string path = buildDescriptionPath(opts.path); 35 string statePath = path.stateName; 36 37 auto state = new BuildState(statePath); 38 39 { 40 state.begin(); 41 scope (success) 42 { 43 if (opts.dryRun) 44 state.rollback(); 45 else 46 state.commit(); 47 } 48 49 scope (failure) 50 state.rollback(); 51 52 clean(state, opts.dryRun); 53 } 54 55 // Close the database before (potentially) deleting it. 56 state.close(); 57 58 if (opts.purge) 59 { 60 println("Deleting `", statePath, "`"); 61 remove(statePath); 62 } 63 } 64 catch (BuildException e) 65 { 66 stderr.println(color.status, ":: ", color.error, 67 "Error", color.reset, ": ", e.msg); 68 return 1; 69 } 70 71 return 0; 72 } 73 74 /** 75 * Deletes all outputs from the file system. 76 */ 77 void clean(BuildState state, bool dryRun) 78 { 79 import io.text, io.file.stdio; 80 import std.range : takeOne; 81 import button.resource : Resource; 82 83 foreach (id; state.enumerate!(Index!Resource)) 84 { 85 if (state.degreeIn(id) > 0) 86 { 87 auto r = state[id]; 88 89 println("Deleting `", r, "`"); 90 91 r.remove(dryRun); 92 93 // Update the database with the new status of the resource. 94 state[id] = r; 95 96 // We want to build this the next time around, so mark its task as 97 // pending. 98 auto incoming = state 99 .incoming!(NeighborIndex!(Index!Resource))(id) 100 .takeOne; 101 assert(incoming.length == 1, 102 "Output resource has does not have 1 incoming edge! "~ 103 "Something has gone horribly wrong!"); 104 state.addPending(incoming[0].vertex); 105 } 106 } 107 }