1 /** 2 Copyright: © 2013 rejectedsoftware e.K. 3 License: Subject to the terms of the GNU GPLv3 license, as written in the included LICENSE.txt file. 4 Authors: Sönke Ludwig 5 */ 6 module dubregistry.repositories.repository; 7 8 import vibe.vibe; 9 10 import dubregistry.cache; 11 import std.digest.sha; 12 import std.typecons; 13 14 15 Repository getRepository(Json repinfo) 16 { 17 auto ident = repinfo.toString(); 18 if( auto pr = ident in s_repositories ) 19 return *pr; 20 21 logDebug("Returning new repository: %s", ident); 22 auto pf = repinfo.kind.get!string in s_repositoryFactories; 23 enforce(pf, "Unknown repository type: "~repinfo.kind.get!string); 24 auto rep = (*pf)(repinfo); 25 s_repositories[ident] = rep; 26 return rep; 27 } 28 29 void addRepositoryFactory(string kind, RepositoryFactory factory) 30 { 31 assert(kind !in s_repositoryFactories); 32 s_repositoryFactories[kind] = factory; 33 } 34 35 36 alias RepositoryFactory = Repository delegate(Json); 37 38 interface Repository { 39 RefInfo[] getTags(); 40 RefInfo[] getBranches(); 41 void readFile(string commit_sha, Path path, scope void delegate(scope InputStream) reader); 42 string getDownloadUrl(string tag_or_branch); 43 } 44 45 struct RefInfo { 46 string name; 47 string sha; 48 BsonDate date; 49 50 this(string name, string sha, SysTime date) 51 { 52 this.name = name; 53 this.sha = sha; 54 this.date = BsonDate(date); 55 } 56 } 57 58 package Json readJson(string url, bool sanitize = false, bool cache_priority = false) 59 { 60 Json ret; 61 logDiagnostic("Getting JSON response from %s", url); 62 Exception ex; 63 foreach (i; 0 .. 2) { 64 try { 65 downloadCached(url, (scope input){ 66 scope (failure) clearCacheEntry(url); 67 auto text = input.readAllUTF8(sanitize); 68 ret = parseJsonString(text); 69 }, cache_priority); 70 return ret; 71 } catch (Exception e) { 72 logDiagnostic("Failed to parse downloaded JSON document (attempt #%s): %s", i+1, e.msg); 73 ex = e; 74 } 75 } 76 throw new Exception(format("Failed to read JSON from %s: %s", url, ex.msg), __FILE__, __LINE__, ex); 77 } 78 79 private { 80 Repository[string] s_repositories; 81 RepositoryFactory[string] s_repositoryFactories; 82 }