-
Notifications
You must be signed in to change notification settings - Fork 0
/
UpdateGitHub.R
191 lines (174 loc) · 7.12 KB
/
UpdateGitHub.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# This process will be defined in a function ----
# It is saved in the location: paste0(getwd(),"/","UpdateGitHub.R")
UpdateGitHub <- function(repo=getwd(), untracked=TRUE, stage=TRUE, commit=TRUE, pull=TRUE, push=TRUE) {
# Input: ----
# - 'repo' must be an atomic string value which is a valid directory that contains the files for this repository. It will be validated by the rprojroot package.
# - 'untracked' must be an atomic logical value which is used for determining whether or not to process the untracked files.
# - 'stage' must be an atomic logical value which is used for determining whether or not to stage the files.
# - 'commit' must be an atomic logical value which is used for determining whether or not to commit the files.
# - 'pull' must be an atomic logical value which is used for determining whether or not to pull from the repo.
# - 'push' must be an atomic logical value which is used for determining whether or not to push to the repo.
# Output: ----
# - Will print updates from the different stages.
# Validate parameters: ----
stopifnot(is.character(repo))
stopifnot(dir.exists(repo))
stopifnot(is.atomic(repo))
stopifnot(is.atomic(untracked))
stopifnot(is.atomic(stage))
stopifnot(is.atomic(commit))
stopifnot(is.atomic(pull))
stopifnot(is.atomic(push))
stopifnot(is.logical(untracked))
stopifnot(is.logical(stage))
stopifnot(is.logical(commit))
stopifnot(is.logical(pull))
stopifnot(is.logical(push))
# Loop through the required packages. If not installed, then install it. If not loaded, then load it. ----
packages <- c("git2r","rprojroot")
for (package in packages) {
if (!package %in% installed.packages()) {
install.packages( package
, quiet = TRUE
, verbose = FALSE
, dependencies = TRUE
)
}
if (!package %in% .packages()) {
suppressPackageStartupMessages(
suppressWarnings(
suppressMessages(
library( package
, character.only = TRUE
, quietly = TRUE
, warn.conflicts = FALSE
, verbose = FALSE
)
)
)
)
}
}
# Check the Project Root directory. This is to ensure that the entire repo is captured. ----
if (getwd() == find_rstudio_root_file()) {
repo <- getwd()
} else {
repo <- find_rstudio_root_file()
}
# Check if there is anything to do. ####
if (is.null(unlist(status()))) {
return (writeLines(paste0("There is nothing to do.")))
}
# Set credentials. This will require input in the Console. ----
username <- readline(prompt = "Please enter your GitHub Username: ") #ALWAYS BE CAREFUL ABOUT STORING YOUR CREDENTIALS ON GITHUB!!
password <- readline(prompt = "Please enter your GitHub Password: ") #ALWAYS BE CAREFUL ABOUT STORING YOUR CREDENTIALS ON GITHUB!!
credentials <- cred_user_pass(username = username, password = password)
# NOTE: values returned from the status() command are as follows ----
# 1. "untracked" means new files which have not yet been added to GitHub.
# 2. "unstaged" means existing files which have been modified but not yet ready to be committed to GitHub.
# 3. "staged" means files that are staged and ready to be committed.
# Check the Untracked items. The intention is to just push these straight through. So this will Add, Commit, then Push them. ----
if (untracked == TRUE) {
num <- length(unlist(status()["untracked"]))
if (num > 0) {
writeLines(paste0("There are ", num, " Untracked items to be processed."))
for (i in 1:num) {
writeLines(paste0(" ", i, ": ",unlist(status()["untracked"])[i]))
}
add(repo, unlist(status()["untracked"]))
writeLines(paste0("Items have been Staged."))
commit(message = paste(Sys.time(), "Initial commit", sep = " - "))
writeLines(paste0("Items have been Committed."))
push(credentials = credentials)
writeLines(paste0("Items have been Pushed."))
}
}
# Process the Unstaged items. Add them. ----
if (stage == TRUE) {
num <- length(unlist(status()["unstaged"]))
if (num > 0) {
writeLines(paste0("There are ", num, " Tracked items to be processed."))
for (i in 1:num) {
writeLines(paste0(" ", i, ": ", unlist(status()["unstaged"])[i]))
}
}
if (!is.null(unlist(status()["unstaged"]))) {
add(repo, unlist(status()["unstaged"]))
num2 <- length(unlist(status()["unstaged"]))
if (num2 == 0) {
writeLines(paste0("Items have been Staged."))
} else if (num == num2) {
stop ("Something went wrong with the Staging.")
}
}
}
# Process the Staged items. Commit them. ----
if (commit == TRUE) {
if (!is.null(unlist(status()["staged"]))) {
commit(message = paste(Sys.time(), "Update", sep = " - ")) # Generic message, including timestamp.
num2 <- length(unlist(status()["staged"]))
if (num2 == 0) {
writeLines(paste0("Items have been Committed."))
} else if (num == num2) {
stop ("Something went wrong with Committing.")
}
}
}
# Do the Pull step. ----
if (pull == TRUE) {
pull <- tryCatch ( #tryCatch is utilised because the error message when executing pull() or push() is not very helpful: "too many redirects or authentication replays". The main issue is usually that the credentials are incorrect or missing.
expr = {
pull(credentials = credentials)
},
error = function (err) {
message (paste0("Error when Pulling from GitHub. Try checking your credentials and try again.","\n","Message thrown: "))
stop (err)
},
warning = function (war) {
message ("There was a Warning when Pulling from GitHub.")
return (war)
},
finally = {
# It was successful. Move on.
}
)
if (unlist(pull["up_to_date"]) == TRUE) {
writeLines(paste0("There are no discrepancies with the Master branch."))
} else {
stop ("Something went wrong with pulling the repo. Please manually check, merge the code, validate discrepancies, then re-try.")
}
}
# Process the Committed items. Push them. ----
if (push == TRUE) {
if (num > 0) {
tryCatch(
expr = {
push(credentials = credentials)
},
error = function(err) {
message (paste0("Error when Pushing to GitHub. Try checking your credentials and try again.","\n","Message thrown: "))
stop (err)
},
warning = function (war) {
message ("There was a Warning when Pushing to GitHub.")
return (war)
},
finally = {
# It was successful. Move on.
}
)
num2 <- length(unlist(status()))
if (num2 == 0) {
writeLines(paste0("Items have been Pushed."))
} else if (num == num2) {
stop ("Something went wrong with Pushing.")
}
}
}
return(writeLines(paste0("Successfully updated.")))
}
# Run the function.
UpdateGitHub()
# Run this script in the Console
#bookdown::publish_book(render = 'local')
# source(paste0(getwd(),"/","UpdateGitHub.R"))