1 /** 2 * Copyright: Copyright Jason White, 2016 3 * License: MIT 4 * Authors: Jason White 5 */ 6 module button.deps; 7 8 import button.resource; 9 10 /** 11 * Format for dependencies received from a task over a pipe. 12 */ 13 align(4) struct Dependency 14 { 15 /** 16 * Timestamp of the resource. If unknown, this should be set to 0. In such a 17 * case, the parent build system will compute the value when needed. This is 18 * used by the parent build system to determine if the checksum needs to be 19 * recomputed. 20 * 21 * For files and directories, this is its last modification time. 22 */ 23 ulong timestamp; 24 25 /** 26 * SHA-256 checksum of the contents of the resource. If unknown or not 27 * computed, this should be set to 0. In such a case, the parent build 28 * system will compute the value when needed. 29 * 30 * For files, this is the checksum of the file contents. For directories, 31 * this is the checksum of the paths in the sorted directory listing. 32 */ 33 ubyte[32] checksum; 34 35 /** 36 * Length of the name. 37 */ 38 uint length; 39 40 /** 41 * Name of the resource that can be used to lookup the data. Length is given 42 * by the length member. 43 * 44 * This is usually a file or directory path. The path does not need to be 45 * normalized. The path is assumed to be relative to the associated task's 46 * working directory. 47 */ 48 char[0] name; 49 } 50 51 unittest 52 { 53 static assert(Dependency.sizeof == 44); 54 } 55 56 /** 57 * Range of resources received from a child process. 58 */ 59 struct Deps 60 { 61 private 62 { 63 immutable(void)[] buf; 64 65 Resource _current; 66 bool _empty; 67 } 68 69 this(immutable(void)[] buf) 70 { 71 this.buf = buf; 72 popFront(); 73 } 74 75 Resource front() inout 76 { 77 return _current; 78 } 79 80 bool empty() const pure nothrow 81 { 82 return _empty; 83 } 84 85 void popFront() 86 { 87 import std.datetime : SysTime; 88 89 if (buf.length == 0) 90 { 91 _empty = true; 92 return; 93 } 94 95 if (buf.length < Dependency.sizeof) 96 throw new Exception("Received partial dependency buffer"); 97 98 auto dep = *cast(Dependency*)buf[0 .. Dependency.sizeof]; 99 100 immutable totalSize = Dependency.sizeof + dep.length; 101 102 string name = cast(string)buf[Dependency.sizeof .. totalSize]; 103 104 _current = Resource( 105 name, 106 SysTime(cast(long)dep.timestamp), 107 dep.checksum 108 ); 109 110 buf = buf[totalSize .. $]; 111 } 112 } 113 114 /** 115 * Convenience function for returning a range of resources. 116 */ 117 Deps deps(immutable(void)[] buf) 118 { 119 return Deps(buf); 120 }