-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an API to fetch repositories and list their branches. #12
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,48 @@ | ||
#' Get the storage path for a repository. | ||
#' | ||
#' Repositories are all stored as subdirectories of a common base path, | ||
#' using a hash of their URL as the directory name. | ||
#' | ||
#' @param base the base directory in which all repositories are stored. | ||
#' @param url the URL of the remote repository. | ||
#' @param check if TRUE and the repository does not exist locally yet, an error | ||
#' is raised. | ||
#' @return the path to the repository. | ||
repository_path <- function(base, url, check = TRUE) { | ||
hash <- openssl::sha1(url) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i dont mind this, but also makes it less easy for us to poke around, you said its to help with weird characters and stuff in the url, whats a character that would break it that github allows? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I do get the less pokeable argument and was a bit worried about it. It is still possible to get the URL from a cloned repo though by doing The "weird character" comes in large part from the fact that I did not want to assume anything about GitHub here, so we need to encode the full URL, not just org name and repo name. That include I suppose the alternative is to do a percent encoding of the URL, which would work to avoid all the special characters (but it would do nothing about Using a hash of the URL was a very easy to workaround all these problems by guaranteeing a fixed length, unique name using only safe characters. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah okay i was just thinking a very simple directory structure like but yh youre right about it being us relying on github i do think in practice however, none of these issues will ever affect us with the happy to leave it to your judgement! if we do it with the hashes though, i think it would be useful to do a tiny script in another pr that prints a mapping of hashes to origin url by doing a simple dir walk so that we can easily debug There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Just being able to use a file path as URL in unit tests is a pretty good use case, instead of having to mock GitHub or have some tedious fake setup
Sure can do |
||
path <- file.path(base, hash) | ||
if (check && !fs::dir_exists(path)) { | ||
porcelain::porcelain_stop( | ||
message = "Repository does not exist", | ||
code = "NOT_FOUND", | ||
status_code = 404) | ||
} | ||
path | ||
} | ||
|
||
|
||
#' Clone or fetch a remote repository. | ||
#' | ||
#' @param base the base directory in which all repositories are stored. | ||
#' @param url the URL of the remote repository. | ||
#' @return the path to the local clone of the repository. | ||
git_sync <- function(base, url) { | ||
repo <- repository_path(base, url, check = FALSE) | ||
if (!fs::dir_exists(repo)) { | ||
gert::git_clone(url = url, path = repo, bare = TRUE, verbose = FALSE) | ||
} else { | ||
gert::git_fetch(repo = repo, prune = TRUE, verbose = FALSE) | ||
} | ||
repo | ||
} | ||
|
||
git_remote_list_branches <- function(repo) { | ||
branches <- gert::git_branch_list(repo, local = FALSE) | ||
branches$name <- gsub("^refs/remotes/origin/", "", branches$ref) | ||
branches <- branches[branches$name != "HEAD", ] | ||
branches | ||
} | ||
|
||
git_run <- function(args, repo = NULL, check = FALSE) { | ||
git <- sys_which("git") | ||
if (!is.null(repo)) { | ||
|
@@ -12,7 +57,7 @@ git_run <- function(args, repo = NULL, check = FALSE) { | |
} | ||
|
||
|
||
git_get_default_branch <- function(repo = NULL) { | ||
git_remote_default_branch_ref <- function(repo) { | ||
# This is assuming remote origin exists. We'll get an error if it | ||
# doesn't. But this should be safe for us as we'll always have cloned | ||
# this from GitHub. | ||
|
@@ -21,10 +66,20 @@ git_get_default_branch <- function(repo = NULL) { | |
} | ||
|
||
|
||
git_remote_default_branch_name <- function(repo) { | ||
ref <- git_remote_default_branch_ref(repo) | ||
if (!is.null(ref)) { | ||
gsub("^refs/remotes/origin/", "", ref) | ||
} else { | ||
NULL | ||
} | ||
} | ||
|
||
|
||
git_get_modified <- function(ref, base = NULL, | ||
relative_dir = NULL, repo = NULL) { | ||
if (is.null(base)) { | ||
base <- git_get_default_branch(repo) | ||
base <- git_remote_default_branch_ref(repo) | ||
} | ||
if (is.null(relative_dir)) { | ||
relative <- "" | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,6 @@ | ||||||
parse_main <- function(args = commandArgs(TRUE)) { | ||||||
usage <- "Usage: | ||||||
orderly.runner.server [options] <path> | ||||||
orderly.runner.server [options] <path> <repositories> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here too right?
Suggested change
|
||||||
|
||||||
Options: | ||||||
--log-level=LEVEL Log-level (off, info, all) [default: info] | ||||||
|
@@ -12,12 +12,13 @@ Options: | |||||
validate = dat$validate, | ||||||
port = as.integer(dat$port), | ||||||
path = dat$path, | ||||||
repositories = dat$repositories, | ||||||
host = dat$host) | ||||||
} | ||||||
|
||||||
main <- function(args = commandArgs(TRUE)) { | ||||||
dat <- parse_main(args) | ||||||
api_obj <- api(dat$path, dat$validate, dat$log_level) | ||||||
api_obj <- api(dat$path, dat$repositories, dat$validate, dat$log_level) | ||||||
api_obj$run(host = dat$host, port = dat$port) | ||||||
} | ||||||
|
||||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"type": "object", | ||
"properties": { | ||
"branches": { | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"name": { | ||
"type": "string" | ||
}, | ||
"commit_hash": { | ||
"type": "string" | ||
}, | ||
"message": { | ||
"type": "string" | ||
}, | ||
"time": { | ||
"type": "number" | ||
plietar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}, | ||
"required": [ | ||
"name", | ||
"commit_hash", | ||
"message", | ||
"time" | ||
] | ||
} | ||
}, | ||
"default_branch": { | ||
"type": "string" | ||
} | ||
}, | ||
"required": [ | ||
"branches", | ||
"default_branch" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"type": "object", | ||
"properties": { | ||
"url": { "type": "string" } | ||
}, | ||
"required": [ "url" ] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"type": "object" | ||
plietar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a suggestion, just curious as to why you used
data.frame
instead oflist
, is it because it fills in the data frame and serialises each row and you dont have to wrap each branch name in scalar for example?also are we not worrying about the new line characters? rich was worrying about them for some reason in the past, i cant remember what we decided on that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Err, I don't know. It just works. I don't even know how what the easy way to turn this into a list would be.
If I just replace
data.frame
bylist
and do no other transformation then the result is radically different. It would be one object with fieldsname
,commit_hash
, ... where each entry is an array of strings, which is not idiomatic JSON at all. Usingdata.frame
gives the expected result because jsonlite has special support for it. Orderly2 does this all the time when serializing, eg. the list of files in a packet.The other way would be to do the pivot myself and generate a list of lists, where each nested list contains a bunch of scalars. Doable but way more tedious and verbose.
I never understood this concern. JSON can serialize newline characters just fine. But yeah you are right this breaks with the outpack_server API. I can go back to using a list of strings if you prefer, but it makes no sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yh i mean feel free to include newline characters, we can always fix it pretty easily if needed, do you think its worth having the type as an array of 1 though? just thinking about the fact that we may have to migrate the database to be just string and then if we implement a newline char change in the future itll have to be migrated again to string arrays, idm either way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't show up in the database does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe not, im not 100% sure but it shows up in the data class for the response, should be easy enough to change but might wanna make a quick ticket for it so we dont forget!