Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
265 lines (236 sloc) 10 KB
<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25">
<Class name="CacheGitHubCI.Install">
<TimeCreated>63613,47857.460994</TimeCreated>
<XData name="Install">
<Description>
See generated code in zsetup+1^CacheGitHubCI.Install.1
todo add optional parameter WEBAPP to Alter web app name if it needs to have another then namespace name</Description>
<XMLNamespace>INSTALLER</XMLNamespace>
<Data><![CDATA[
<Manifest>
<If Condition='(##class(Config.Namespaces).Exists("${Namespace}")=0)'>
<Log Text="Creating namespace ${Namespace}" Level="0"/>
<Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Data="${Namespace}">
<Configuration>
<Database Name="${Namespace}" Dir="${MGRDIR}/${Namespace}" Create="yes" MountRequired="true" Resource="%DB_${Namespace}" PublicPermissions="RW" MountAtStartup="true"/>
</Configuration>
</Namespace>
<Log Text="End Creating namespace ${Namespace}" Level="0"/>
</If>
<Namespace Name="${Namespace}" Create="no">
<IfDef Var="SourceDir">
<Log Text="SourceDir defined - offline install from ${SourceDir}" Level="0"/>
<Import File="${SourceDir}"/>
</IfDef>
<IfNotDef Var="SourceDir">
<Log Text="SourceDir undefined - online install from GitHub" Level="0"/>
<RunInstall Class="CacheGitHubCI.Install" Method="DownloadFromGitHub"/>
</IfNotDef>
<IfDef Var="IP">
<Log Text="IP set to ${IP} you can now create hooks." Level="0"/>
<RunInstall Class="CacheGitHubCI.Install" Method="SetIP"/>
<If Condition='(##class(Security.Applications).Exists("/cgci")=0)'>
<Log Text="Creating web application /cgci" Level="0"/>
<RunInstall Class="CacheGitHubCI.Install" Method="CreateWebApp"/>
</If>
</IfDef>
</Namespace>
</Manifest>
]]></Data>
</XData>
<Method name="setup">
<Description>
This is a method generator whose code is generated by XGL.
Set pVars("Namespace")="CGCI"
Set pVars("IP")="serverip:serverport"
do ##class(CacheGitHubCI.Install).setup(.pVars)</Description>
<Internal>1</Internal>
<ClassMethod>1</ClassMethod>
<CodeMode>objectgenerator</CodeMode>
<FormalSpec><![CDATA[&pVars,pLogLevel:%Integer=0,pInstaller:%Installer.Installer]]></FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[ Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install")
]]></Implementation>
</Method>
<Method name="CreateWebApp">
<ClassMethod>1</ClassMethod>
<FormalSpec>pVars,pLogLevel,tInstaller</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
Set Namespace=pVars("Namespace")
Set cspProperties("AutheEnabled") = 64 // Unauthenticated
Set cspProperties("MatchRoles") = ":" _ ..GetNSResource("%SYS")
Set cspProperties("NameSpace") = Namespace
Set cspProperties("IsNameSpaceDefault") = 1
Set cspProperties("DispatchClass")="CacheGitHubCI.REST"
Do tInstaller.PushNS("%SYS")
Set tSC = ##class(Security.Applications).Create("/cgci", .cspProperties)
Do tInstaller.PopNS()
If $$$ISERR(tSC) Throw ##class(%Installer.Exception).CreateFromStatus(tSC)
quit $$$OK
]]></Implementation>
</Method>
<Method name="GetNSResource">
<Description>
Determine Namespace databease resource.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>Namespace:%String="%SYS"</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
set ns = $Namespace
zn "%SYS"
do ##Class(Config.Namespaces).Get("%SYS",.Properties)
set dbname = Properties("SysRoutines")
Set rset = ##class(%ResultSet).%New("Config.Databases:List")
do rset.Execute(dbname)
do rset.Next()
set dbdir = rset.Data("Directory")
set db=##class(SYS.Database).%OpenId(dbdir)
set resname = db.ResourceName
kill (resname,ns)
zn ns
return resname
]]></Implementation>
</Method>
<Method name="SetIP">
<ClassMethod>1</ClassMethod>
<FormalSpec>pVars,pLogLevel,tInstaller</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
Set ^CacheGitHubCI("IP")=pVars("IP")
quit $$$OK
]]></Implementation>
</Method>
<Method name="DownloadFromGitHub">
<ClassMethod>1</ClassMethod>
<FormalSpec>pVars,pLogLevel,tInstaller</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
Set Namespace=tInstaller.Evaluate("${Namespace}")
Do tInstaller.PushNS("%SYS")
Set tSC = ..Update(Namespace, "intersystems-ru", "CacheGitHubCI", "master")
Do tInstaller.PopNS()
If $$$ISERR(tSC) Throw ##class(%Installer.Exception).CreateFromStatus(tSC)
quit $$$OK
]]></Implementation>
</Method>
<Method name="Update">
<Description><![CDATA[
Downloads and compiles GitHub repository.<br>
<b>Owner</b> - The name of the repository owner.<br>
<b>Repository</b> - The name of the repository.<br>
<b>Branch</b> - The name of the commit/branch/tag. If skipped the repository’s default branch (usually master) would be used.<br>
<b>Username</b> - GitHub user, who has access to repository. Optional for public repositories.<br>
<b>Password</b> - GitHub password, corresponding to Username. Optional for public repositories.<br>
Note, that with Username, you can make up to 5,000 requests per hour.
For unauthenticated requests, the rate limit allows to make up to 60 requests per hour.
Unauthenticated requests are associated with an IP address.<br>
<b>Namespace</b> - Namespace, where to download and compile repository.<br>
For example in the repository: https://github.com/intersystems-ru/Cache-MDX2JSON<br>
Owner - intersystems-ru, Repository - Cache-MDX2JSON.<br> ]]></Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>Namespace=$Namespace,Owner:%String="intersystems-ru",Repository:%String="CacheGitHubCI",Branch:%String,Username:%String,Password:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
Set namespace = $Namespace
Set SSLConfig = "GitHub"
Zn "%SYS"
Do:'##class(Security.SSLConfigs).Exists(SSLConfig) ##class(Security.SSLConfigs).Create(SSLConfig)
Set req=##class(%Net.HttpRequest).%New()
Set req.Https=1
Set req.SSLConfiguration=SSLConfig
Set req.Server="api.github.com"
Set req.Location = "repos/" _ Owner _ "/" _ Repository _ "/contents" // as described in https://developer.github.com/v3/repos/
Do:$d(Branch) req.SetParam("ref",Branch) // if omitted the repository’s default branch (usually master) would be used
Do req.SetHeader("Accept","application/vnd.github.v3+json") // we want to receive API v3
If ($d(Username) && $d(Password)) { // supply Username and Passwor, if both are provided. GitHub accept Basic Auth
Set req.Username = Username // https://developer.github.com/v3/auth/
Set req.Password = Password
}
Set links = ##class(%ListOfDataTypes).%New()
Set st = ..ProcessDirectory("",req,.links)
Return:$$$ISERR(st) st
Zn Namespace
Set st = ..DownloadFiles(links,req,.list)
Set st2 = $system.OBJ.CompileList(.list)
Zn namespace
Return $$$ADDSC(st, st2)
]]></Implementation>
</Method>
<Method name="ProcessDirectory">
<Description><![CDATA[
Process one directory of GitHub repository. Recursive.<br>
<b>Path</b> -Internal repository path. Root is empty string<br>
<b>Request</b> - Authenticated/Set %Net.HttpRequest object.<br>
<b>Links</b> - List of links to raw files (which satisfy <b>IsCacheFile</b> conditions) from repository.<br>]]></Description>
<ClassMethod>1</ClassMethod>
<FormalSpec><![CDATA[Path:%String="",Request:%Net.HttpRequest,&Links:%ListOfDataTypes]]></FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
Set location = Request.Location
Set Request.Location = Request.Location _ Path
Set st = Request.Get()
Return:$$$ISERR(st) st
Return:(Request.HttpResponse.StatusCode = 404) $$$ERROR($$$GeneralError,"Repository doesn't exist OR you don't have access")
Return:((Request.HttpResponse.StatusCode = 403) && (Request.HttpResponse.GetHeader("X-RATELIMIT-REMAINING")=0)) $$$ERROR($$$GeneralError,"API rate limit exceeded. Try logging in.")
Return:(Request.HttpResponse.StatusCode '= 200) $$$ERROR($$$GeneralError,"Received " _ Request.HttpResponse.StatusCode _ " status, expected 200")
#dim objects As List of %ZEN.proxyObject
#dim obj As %ZEN.proxyObject
Set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(Request.HttpResponse.Data,,.objects,1)
Return:$$$ISERR(st) st
For i = 1:1:objects.Count() {
Set obj = objects.GetAt(i)
If (obj.type = "dir") {
Set st = ..ProcessDirectory("/"_obj.name,Request,.Links)
Return:$$$ISERR(st) st
} ElseIf (obj.type = "file") {
Do:..IsCacheFile(obj) Links.Insert(obj."download_url")
} Else {
// obj.type = "symlink" or obj.type = "submodule"
}
}
Set Request.Location = location // to keep track of where in the repository tree we are
Return $$$OK
]]></Implementation>
</Method>
<Method name="IsCacheFile">
<Description>
Check that incoming file is the one you need.
See $$autoDetectType^%apiOBJ</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>File:%ZEN.proxyObject</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[
Set extensions = ",xml,cls,csp,csr,mac,int,bas,inc,gbl,prj,obj,pkg,gof,gsa,go,gto,cdl,"
Return:($L(File.name,".")=1) 0 //no extension
Set File.Extension = $P(File.name,".",$L(File.name,"."))
Return $F(extensions,","_$ZCVT(File.Extension,"l")_",")
]]></Implementation>
</Method>
<Method name="DownloadFiles">
<Description><![CDATA[
Download list of files on https://raw.githubusercontent.com/ server.<br>
<b>Links</b> - List of links to raw files.<br>
<b>Request</b> - Authenticated/Set %Net.HttpRequest object.<br>
<b>loadedlist</b> - Returns an array of the items loaded. ]]></Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>Links:%ListOfDataTypes,Request:%Net.HttpRequest,*Items</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
Kill Items
Set Request.Server = "raw.githubusercontent.com"
Set st = $$$OK
For i = 1:1:Links.Count() {
Set streq = Request.Get($e(Links.GetAt(i),35,*)) // Remove "https://raw.githubusercontent.com/" from URL.
Set:$$$ISERR(streq) st=$$$ADDSC(st, streq)
Set stload = $system.OBJ.LoadStream(Request.HttpResponse.Data,"",.error,.items)
Set:$$$ISERR(stload) st=$$$ADDSC(st, stload)
Merge Items = items
}
Set Request.Server="api.github.com"
Return st
]]></Implementation>
</Method>
</Class>
</Export>