-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathload_package.d
210 lines (188 loc) · 5.08 KB
/
load_package.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
import std.stdio;
import std.file;
import std.string;
import std.process;
import std.path;
import std.algorithm : canFind;
import globals;
import resolve_dep;
static this() {
auto dpath_tmp = getenv("DPATH");
if (dpath_tmp=="") {
writeln("WARNING DPATH NOT SET, suggest DPATH=\"~/d/"~pathSeparator~droot~"\"");
} else {
dpath = dpath_tmp.split(pathSeparator);
}
// allow override of D's installation directory
auto droot_env = getenv("DROOT");
if (droot_env!="") {
droot = droot_env;
}
if (!dpath.canFind(droot))
dpath ~= droot;
}
// Load environment variables at start up.
Package init(string dir) {
// set up search path for D files
load_parent_dir_dpaths(dir);
return load_package_details(dir);
}
Package load_package_details(string dir) {
const VERSION_MARKER="*Version:*";
const NAME_MARKER="# ";
const DEPENDENCY_MARKER="## Dependencies:";
const FLAGS_MARKER="## Flags:";
const SKIP_FILES_MARKER="## Skip D Files:";
Package ret;
ret.dir = dir;
ret.name = ret.dir[ret.dir.lastIndexOf(dirSeparator)+1..$];
auto f = new File(ret.dir ~dirSeparator~"README.md");
uint i=0;
bool in_dependencies = false;
bool in_flags = false;
bool in_skip_files = false;
foreach (char[] line; f.byLine()) {
if (i==0) {
if (line.length<3 || !line.startsWith(NAME_MARKER)) {
throw new Exception("Error: package has invalid name in README.md. Should start with #");
} else {
auto idx = line.indexOf("-");
if (idx== -1)
idx=line.length;
auto n = strip(line[1..idx]);
if (n!=ret.name) {
throw new Exception("Package name does not match name in README.md");
}
}
}
i++;
if (line.startsWith(DEPENDENCY_MARKER)) {
in_dependencies = true;
continue;
}
if (in_dependencies) {
if (line.length<1) {
in_dependencies = false;
continue;
}
if (!line.startsWith(" * ")) {
throw new Exception("Dependency list invalid, correct format is: \"* name: version\". list ends with blank line.");
}
line = line[" * ".length..$];
if (line.startsWith("link ")) {
line = line["link ".length..$];
auto idx = line.indexOf("-");
if (idx==-1) {
throw new Exception("Dependency list invalid, correct format is: link name - description. list ends with blank line.");
}
ret.dependencies ~= Dependency(strip(line[0..idx]).idup, strip(line[idx+1..$]).idup, true);
} else {
auto idx = line.indexOf(":");
if (idx==-1) {
throw new Exception("Dependency list invalid, correct format is:\" * name: version\". list ends with blank line.");
}
ret.dependencies ~= Dependency(strip(line[0..idx]).idup, strip(line[idx+1..$]).idup);
}
}
if (line.startsWith(FLAGS_MARKER)) {
in_flags = true;
continue;
}
if (in_flags) {
if (line.length<1) {
in_flags = false;
continue;
}
if (!line.startsWith(" * ")) {
writeln("line is!!!!", line);
throw new Exception("Invalid flag, flag format is:\" * someflag - description\"");
}
line = line[" * ".length..$];
if (line.strip()=="Library") {
ret.isLibrary = true;
} else {
auto idx = line.lastIndexOf(" - ");
if (idx>0) {
line = line[0..idx];
}
ret.flags ~= line.idup;
}
continue;
}
if (line.startsWith(SKIP_FILES_MARKER)) {
in_skip_files = true;
continue;
}
if (in_skip_files) {
if (line.length<1) {
in_skip_files = false;
continue;
}
ret.skipDFiles ~= line.strip().idup;
}
if (ret.version_str==null && line.length>VERSION_MARKER.length && line[0..VERSION_MARKER.length]==VERSION_MARKER) {
ret.version_str = strip(line[VERSION_MARKER.length..$]).idup;
}
}
return ret;
}
void load_parent_dir_dpaths(string dir) {
string[] newdpath = [];
for (;dir.lastIndexOf(dirSeparator)>0;dir = dir[0..dir.lastIndexOf(dirSeparator)]) {
auto entries = dirEntries(dir, SpanMode.shallow);
foreach (dir1; entries) {
if (!isDir(dir1)) continue;
if (dir1.lastIndexOf(dirSeparator)<=0) continue;
if (dir1[dir1.lastIndexOf(dirSeparator)+1..$]==".dpath") {
newdpath ~= dir1;
}
}
}
foreach (p; dpath) {
newdpath ~= p;
}
dpath = newdpath;
}
struct Dependency {
string name,version_str;
bool linkonly;
}
struct Package {
bool isLibrary = false;
string name;
string version_str;
Dependency[] dependencies;
string[] flags;
string dir;
string[] skipDFiles;
bool isDubPackage;
void print_details() {
writefln("Package: %s[%s]", this.name, this.version_str);
writefln("Dependencies: ");
foreach (dep; this.dependencies) {
string dirfound = "Not Found";
try {
package_dependency_dir(dep.name);
dirfound = "Found";
} catch (Exception e) {
}
writefln("\t%s[%s]: %s", dep.name, dep.version_str, (dep.linkonly?"-l"~dep.name:dirfound));
}
}
// get all files in current directory
string[] get_dfiles() {
return get_dfiles(this.dir);
}
string[] get_dfiles(string dir) {
string[] dfiles = [];
auto entries = dirEntries(dir, SpanMode.shallow);
foreach (entry; entries) {
if (isDir(entry))
dfiles ~= this.get_dfiles(entry);
if (entry.name=="." || entry.name==".." || !entry.name.endsWith(".d"))
continue;
dfiles ~= entry.name;
}
return dfiles;
}
}