|
| 1 | +// Require Remote GET |
| 2 | +// Copyright (c) 2021 Jaskirat Rajasansir |
| 3 | + |
| 4 | +.require.lib each `http`file; |
| 5 | + |
| 6 | +// URL FORMAT -- source://user/repo:version |
| 7 | +// "latest" supported for 'version' |
| 8 | + |
| 9 | +.rrg.cfg.repoUrls:(`symbol$())!(); |
| 10 | +.rrg.cfg.repoUrls[`gh]:"https://api.github.com/repos/{owner}/{repo}"; |
| 11 | + |
| 12 | +.rrg.cfg.relativeUrls:`source`query xkey flip `source`query`relativeUrl!"SS*"$\:(); |
| 13 | +.rrg.cfg.relativeUrls[``]:enlist ""; |
| 14 | +.rrg.cfg.relativeUrls[`gh`releases]:enlist "releases"; |
| 15 | + |
| 16 | +.rrg.location.root:`; |
| 17 | + |
| 18 | + |
| 19 | +.rrg.init:{ |
| 20 | + if[null .rrg.location.root; |
| 21 | + .rrg.location.root:` sv first[.require.location.paths],`$".require-remote-deps"; |
| 22 | + ]; |
| 23 | + |
| 24 | + .file.ensureDir .rrg.location.root; |
| 25 | + |
| 26 | + existingLibs:.rrg.list[]; |
| 27 | + |
| 28 | + if[0 < count existingLibs; |
| 29 | + .require.addPath[;0b] each existingLibs`libRoot; |
| 30 | + .require.rescan[]; |
| 31 | + ]; |
| 32 | + |
| 33 | + .log.if.info ("Require 'Remote GET' library initialised [ Download Target: {} ] [ Current Libs: {} ]"; .rrg.location.root; count existingLibs); |
| 34 | + }; |
| 35 | + |
| 36 | + |
| 37 | +.rrg.get:{[request] |
| 38 | + details:.rrg.i.parseGetRequest request; |
| 39 | + |
| 40 | + versions:details[`url],"/",.rrg.cfg.relativeUrls[details[`source],`releases]`relativeUrl; |
| 41 | + |
| 42 | + verResp:.http.get[versions; ()!()]; |
| 43 | + |
| 44 | + if[not `success = verResp`statusType; |
| 45 | + .log.if.error "Failed to query API for repository information [ Request: ",request," ]"; |
| 46 | + '"InvalidRepositoryException"; |
| 47 | + ]; |
| 48 | + |
| 49 | + releases:select from verResp[`body] where not draft, not prerelease; |
| 50 | + |
| 51 | + if[0 = count releases; |
| 52 | + .log.if.error "No published releases available for repository [ Request: ",request," ]"; |
| 53 | + '"NoRepositoryVersionsException"; |
| 54 | + ]; |
| 55 | + |
| 56 | + $["latest" ~ details`version; |
| 57 | + theRelease:first releases; |
| 58 | + / else |
| 59 | + theRelease:first select from releases where tag_name like "*",details[`version],"*" |
| 60 | + ]; |
| 61 | + |
| 62 | + if[0 = count theRelease `tarball_url; |
| 63 | + .log.if.error "Invalid version specified (or no releases available) [ Request: ",request," ]"; |
| 64 | + '"InvalidRepositoryVersionException"; |
| 65 | + ]; |
| 66 | + |
| 67 | + tarTarget:` sv .rrg.location.root,`.staging,` sv details[`repo],`tar`gz; |
| 68 | + |
| 69 | + .log.if.info "Downloading repository version [ Request: ",request," ] [ Version: ",theRelease[`tag_name]," ] [ Target: ",string[tarTarget]," ]"; |
| 70 | + |
| 71 | + repo:.http.get[theRelease`tarball_url; ()!()]; |
| 72 | + tarTarget 1: repo`body; |
| 73 | + |
| 74 | + extractTarget:` sv .rrg.location.root,details`repo; |
| 75 | + |
| 76 | + .log.if.info "Extracting repostiory release [ Target: ",string[extractTarget]," ]"; |
| 77 | + |
| 78 | + if[.type.isFolder extractTarget; |
| 79 | + .log.if.debug "Removing existing download for repository [ Request: ",request," ]"; |
| 80 | + .os.run[`rmFolder; 1_ string extractTarget]; |
| 81 | + ]; |
| 82 | + |
| 83 | + .file.ensureDir extractTarget; |
| 84 | + |
| 85 | + .util.system "tar -xzf ",(1_ string tarTarget)," --strip-components=1 --directory ",1_ string extractTarget; |
| 86 | + (` sv extractTarget,`RRG_VERSION) 1: theRelease`tag_name; |
| 87 | + |
| 88 | + rrgTree:.file.tree extractTarget; |
| 89 | + kdbFiles:rrgTree where any rrgTree like/: "*",/:(".q"; ".k"; ".q_"; ".k_"); |
| 90 | + |
| 91 | + if[0 = count kdbFiles; |
| 92 | + .log.if.warn ("Downloaded repository contains no kdb+ files. Not added to path [ Repository: {} ]"; request); |
| 93 | + :(::); |
| 94 | + ]; |
| 95 | + |
| 96 | + .log.if.info ("Repository downloaded and adding to 'require' path [ Repository: {} ] [ Files: {} ]"; request; count kdbFiles) |
| 97 | + .require.addPath extractTarget; |
| 98 | + }; |
| 99 | + |
| 100 | +.rrg.list:{ |
| 101 | + list:flip `lib`libRoot`versionFile`version!"SSS*"$\:(); |
| 102 | + list:list upsert ([] lib:.file.ls .rrg.location.root; libRoot:.file.listFolderPaths .rrg.location.root); |
| 103 | + list:update versionFile:(` sv/:libRoot,\:`RRG_VERSION) from list; |
| 104 | + list:update version:first each .ns.protectedExecute[read0;] each versionFile from list; |
| 105 | + list:delete from list where version~\:.ns.const.pExecFailure; |
| 106 | + |
| 107 | + :list; |
| 108 | + }; |
| 109 | + |
| 110 | +.rrg.import:{[lib; repo; relPath] |
| 111 | + if[not .type.isFolder repo; |
| 112 | + '"InvalidRepositoryException"; |
| 113 | + ]; |
| 114 | + |
| 115 | + isGitRepo:not .ns.const.pExecFailure ~ first .ns.protectedExecute[`.util.system; "git rev-parse --is-inside-work-tree"]; |
| 116 | + |
| 117 | + if[not isGitRepo; |
| 118 | + '"InvalidRepositoryException"; |
| 119 | + ]; |
| 120 | + |
| 121 | + details:.rrg.i.parseGetRequest lib; |
| 122 | + |
| 123 | + repoDetail:.http.get[details`url; ()!()]; |
| 124 | + |
| 125 | + if[0 = count repoDetail[`body]`clone_url; |
| 126 | + '"InvalidRepositoryException"; |
| 127 | + ]; |
| 128 | + |
| 129 | + .log.if.info "Adding remote dependency as submodule [ Lib: ",lib," ] [ Local Git Repo: ",string[repo]," ] [ Relative Path: ",string[path]," ]"; |
| 130 | + |
| 131 | + -1 "git submodule add ",(repoDetail[`body]`clone_url)," ",1_ string relPath; |
| 132 | + }; |
| 133 | + |
| 134 | +.rrg.i.parseGetRequest:{[req] |
| 135 | + parsed:.http.i.getUrlDetails req; |
| 136 | + |
| 137 | + result:`source`owner`repo`version!(`$-3_ parsed`scheme; `$parsed`baseUrl; `$1_ first ":" vs parsed`path; last ":" vs parsed`path); |
| 138 | + result[`url]:.util.findAndReplace[.rrg.cfg.repoUrls result`source; ("{owner}"; "{repo}"); string result`owner`repo]; |
| 139 | + |
| 140 | + :result; |
| 141 | + }; |
0 commit comments