/** Stuff related to installation. Copyright: © 2012 Matthias Dondorff License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. Authors: Matthias Dondorff */ module dub.installation; import dub.utils; import vibe.core.log; import vibe.core.file; import vibe.data.json; import vibe.inet.url; import std.array; import std.exception; import std.conv; const bool PRETTY_JOURNAL = true; /// Installation journal for later uninstallation, saved alongside the installation. /// Example Json: /// { /// "version": 1, /// "files": { /// "file1": "typeoffile1", /// ... /// } /// } class Journal { private const int Version = 1; enum Type { RegularFile, Directory, Alien } struct Entry { this( Type t, Path f ) { type = t; relFilename = f; } Type type; Path relFilename; } @property const(Entry[]) entries() const { return m_entries; } this() { } /// Initializes a Journal from a previous installation. this(Path journalFile) { auto jsonJournal = jsonFromFile(journalFile); enforce(cast(int)jsonJournal["Version"] == Version, "Mismatched version: "~to!string(cast(int)jsonJournal["Version"]) ~ "vs. " ~to!string(Version)); foreach(string file, type; jsonJournal["Files"]) m_entries ~= Entry(to!Type(cast(string)type), Path(file)); } void add(Entry e) { foreach(Entry ent; entries) { if( e.relFilename == ent.relFilename ) { enforce(e.type == ent.type, "Duplicate('"~to!string(e.relFilename)~"'), different types: "~to!string(e.type)~" vs. "~to!string(ent.type)); return; } } m_entries ~= e; } void save(Path p) { Json jsonJournal = serialize(); Appender!(char[]) data; if(PRETTY_JOURNAL) toPrettyJson(data, jsonJournal); else toJson(data, jsonJournal); auto fileJournal = openFile(to!string(p), FileMode.CreateTrunc); scope(exit) fileJournal.close(); fileJournal.write(cast(ubyte[])data.data()); } private Json serialize() const { Json[string] files; foreach(Entry e; m_entries) files[to!string(e.relFilename)] = to!string(e.type); Json[string] json; json["Version"] = Version; json["Files"] = files; return Json(json); } private { Entry[] m_entries; } }