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.github; 7 8 import dubregistry.cache; 9 import dubregistry.repositories.repository; 10 import std.string : startsWith; 11 import std.typecons; 12 import vibe.core.log; 13 import vibe.core.stream; 14 import vibe.data.json; 15 import vibe.inet.url; 16 17 18 class GithubRepository : Repository { 19 private { 20 string m_owner; 21 string m_project; 22 string m_authUser; 23 string m_authPassword; 24 } 25 26 static void register(string user, string password) 27 { 28 Repository factory(Json info){ 29 return new GithubRepository(info.owner.get!string, info.project.get!string, user, password); 30 } 31 addRepositoryFactory("github", &factory); 32 } 33 34 this(string owner, string project, string auth_user, string auth_password) 35 { 36 m_owner = owner; 37 m_project = project; 38 m_authUser = auth_user; 39 m_authPassword = auth_password; 40 } 41 42 RefInfo[] getTags() 43 { 44 import std.datetime : SysTime; 45 46 Json tags; 47 try tags = readJson(getAPIURLPrefix()~"/repos/"~m_owner~"/"~m_project~"/tags"); 48 catch( Exception e ) { throw new Exception("Failed to get tags: "~e.msg); } 49 RefInfo[] ret; 50 foreach_reverse (tag; tags) { 51 try { 52 auto tagname = tag.name.get!string; 53 Json commit = readJson(getAPIURLPrefix()~"/repos/"~m_owner~"/"~m_project~"/commits/"~tag.commit.sha.get!string, true, true); 54 ret ~= RefInfo(tagname, tag.commit.sha.get!string, SysTime.fromISOExtString(commit.commit.committer.date.get!string)); 55 logDebug("Found tag for %s/%s: %s", m_owner, m_project, tagname); 56 } catch( Exception e ){ 57 throw new Exception("Failed to process tag "~tag.name.get!string~": "~e.msg); 58 } 59 } 60 return ret; 61 } 62 63 RefInfo[] getBranches() 64 { 65 import std.datetime : SysTime; 66 67 Json branches = readJson(getAPIURLPrefix()~"/repos/"~m_owner~"/"~m_project~"/branches"); 68 RefInfo[] ret; 69 foreach_reverse( branch; branches ){ 70 auto branchname = branch.name.get!string; 71 Json commit = readJson(getAPIURLPrefix()~"/repos/"~m_owner~"/"~m_project~"/commits/"~branch.commit.sha.get!string, true, true); 72 ret ~= RefInfo(branchname, branch.commit.sha.get!string, SysTime.fromISOExtString(commit.commit.committer.date.get!string)); 73 logDebug("Found branch for %s/%s: %s", m_owner, m_project, branchname); 74 } 75 return ret; 76 } 77 78 void readFile(string commit_sha, Path path, scope void delegate(scope InputStream) reader) 79 { 80 assert(path.absolute, "Passed relative path to readFile."); 81 auto url = getContentURLPrefix()~"/"~m_owner~"/"~m_project~"/"~commit_sha~path.toString(); 82 downloadCached(url, (scope input) { 83 reader(input); 84 }, true); 85 } 86 87 string getDownloadUrl(string ver) 88 { 89 if( ver.startsWith("~") ) ver = ver[1 .. $]; 90 else ver = ver; 91 return "https://github.com/"~m_owner~"/"~m_project~"/archive/"~ver~".zip"; 92 } 93 94 private string getAPIURLPrefix() { 95 if (m_authUser.length) return "https://"~m_authUser~":"~m_authPassword~"@api.github.com"; 96 else return "https://api.github.com"; 97 } 98 99 private string getContentURLPrefix() { 100 return "http://raw.github.com"; 101 } 102 }