-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d1a5bab
Showing
4 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
.PHONY: all install | ||
|
||
# Customisable | ||
SCHEDULE=0 */4 * * * # any valid cron expression | ||
CONFIG_FILE=$(XDG_CONFIG_HOME)/mirror-elpa.sh | ||
|
||
# Non-customisable | ||
path=$(PWD)/mirror-elpa | ||
job:=$(SCHEDULE) $(path) $(CONFIG_FILE) | ||
tmp:=$(shell mktemp) | ||
|
||
all: | ||
# no-op | ||
# specified so that `make && make install` won't accidentally install twice | ||
|
||
install: | ||
-crontab -l 2> /dev/null > $(tmp) | ||
@if grep -Eq "/mirror-elpa $(CONFIG_FILE)$$" $(tmp); then \ | ||
echo "\033[1;33mWARN: crontab already contains a reference to mirror-elpa with $(CONFIG_FILE)."; \ | ||
echo "This is likely to result in the job being run more often than" \ | ||
"expected.\033[0m"; \ | ||
fi | ||
echo "$(job)" >> $(tmp) | ||
crontab $(tmp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
* =mirror-elpa= | ||
|
||
(To) Mirror Emacs Lisp package archives. Used to create and maintain mirrors | ||
under Git repository. | ||
|
||
Note that currently only GitHub is supported out of box as a remote for the | ||
mirror. Though you can use =mirror-elpa= to maintain local mirror or mirror on | ||
any other Git hosting. | ||
|
||
** Prerequisites | ||
|
||
The following software must be installed on your system: | ||
|
||
- [[https://stedolan.github.io/jq/][jq]] | ||
- [[http://git-scm.org/][Git]] | ||
- [[http://curl.haxx.se/][cURL]] | ||
- [[https://www.gnu.org/software/emacs/][Emacs]] | ||
|
||
** Usage | ||
|
||
#+BEGIN_SRC bash | ||
$ git clone https://github.com/d12frosted/mirror-elpa | ||
$ cd mirror-elpa | ||
$ ./configure | ||
$ make install | ||
#+END_SRC | ||
|
||
You can also specify how often to sync mirror when running make install | ||
(defaults to every 4 hours) and location to resulting configuration file | ||
(defaults to =$XDG_CONFIG_HOME/mirror-elpa.sh=: | ||
|
||
#+BEGIN_SRC bash | ||
$ make install SCHEDULE="0 0 * * *" CONFIG_FILE="~/mirror-elpa.sh" | ||
#+END_SRC | ||
|
||
=SCHEDULE= can be set to any valid [[https://en.wikipedia.org/wiki/Cron#CRON_expression][CRON expression]]. | ||
|
||
Resulting configuration file can be used for more grained control over | ||
=mirror-elpa= behaviour. | ||
|
||
- Set value of =mirror_path= to avoid using temporary folder for mirror. | ||
- Set value of =mirror_repo_branch_name= to change branch name (default is | ||
=master=). | ||
- Define =git_config_hook= function that is called before changes to repository | ||
are committed. This is a good place to configure Git. | ||
- Set value of =mirror_repo= if you wish to use local mirror or mirror hosted | ||
somewhere else rather than on GitHub. Empty string means local mirror (script | ||
doesn't push). | ||
|
||
** Credits | ||
|
||
- [[https://github.com/dochang][Desmond O. Chang]], thanks for [[https://github.com/dochang/elpa-clone][elpa-clone]]. | ||
- [[https://github.com/ninrod][Filipe Silva]], thanks for keeping this project alive. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Exit script on errors | ||
set -ue | ||
|
||
# Read arguments | ||
show_help= | ||
for arg in "$@"; do | ||
case "$arg" in | ||
"-h"|--help) | ||
show_help=stdin | ||
;; | ||
*) | ||
>&2 echo "Unrecognised argument: $arg" | ||
show_help=stderr | ||
break | ||
;; | ||
esac | ||
done | ||
|
||
# Display help if necessary | ||
help() { | ||
echo "Usage: $(basename "$0") [options]" | ||
echo " -h, --help print this message and exit" | ||
echo | ||
echo "Report bugs at https://github.com/d12frosted/mirror-elpa/issues" | ||
exit | ||
} | ||
[ "$show_help" = "stdin" ] && help | ||
[ "$show_help" = "stderr" ] && >&2 help | ||
|
||
config_file=$XDG_CONFIG_HOME/mirror-elpa.sh | ||
|
||
printf "Config file location: " | ||
[ -n "$config_file" ] && printf "%s " "$config_file" | ||
read -r i_config_file | ||
[ -z "$i_config_file" ] && i_config_file="$config_file" | ||
[ -n "$i_config_file" ] && config_file="$i_config_file" | ||
|
||
# Declare config variables in case $config_file doesn't | ||
owner= | ||
repo= | ||
name= | ||
email= | ||
message= | ||
access_token= | ||
|
||
[ -f "$config_file" ] && source "$config_file" | ||
|
||
check() { | ||
"$@" > /dev/null 2>&1; | ||
local ret="$?" | ||
if [ "$ret" = 0 ]; then | ||
echo "\033[32;32mok\033[0m" # ok | ||
else | ||
echo "\033[31;31merror\033[0m" | ||
fi | ||
return $ret | ||
} | ||
|
||
while :; do | ||
printf "GitHub repository owner: " | ||
[ -n "$owner" ] && printf "%s " "$owner" | ||
read -r i_owner | ||
[ -z "$i_owner" ] && i_owner="$owner" | ||
[ -n "$i_owner" ] && break | ||
done | ||
|
||
while :; do | ||
printf "GitHub repository name: " | ||
[ -n "$repo" ] && printf "%s " "$repo" | ||
read -r i_repo | ||
[ -z "$i_repo" ] && i_repo="$repo" | ||
[ -n "$i_repo" ] && break | ||
done | ||
|
||
owner="$i_owner" | ||
repo="$i_repo" | ||
|
||
while :; do | ||
echo "mirror-elpa needs to be authorized to access $i_owner/$i_repo." | ||
echo "Please create a token with 'repo' permissions here:" | ||
echo "https://github.com/settings/tokens/new" | ||
echo "Alternatively, hit return without entering anything to have mirror-elpa create one for you." | ||
printf "GitHub API token: " | ||
read -r i_access_token | ||
[ -n "$i_access_token" ] && break | ||
|
||
# Generate an API token | ||
read -rp "Your GitHub username: ($i_owner) " i_auth_user | ||
read -rsp "Your GitHub password: " i_auth_password | ||
echo # output blank line after password | ||
|
||
[ "$i_auth_user" ] || i_auth_user="$i_owner" | ||
|
||
github() { | ||
curl -s "https://api.github.com/$1" \ | ||
-u "$i_auth_user:$i_auth_password" \ | ||
-H "Content-Type: application/json" \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
$(shift 1; echo "$@") | ||
} | ||
response=$(github authorizations -X POST -d @- <<-JSON | ||
{ | ||
"scopes": [ | ||
"repo" | ||
], | ||
"note": "mirror-elpa@$(hostname)$(pwd)", | ||
"note_url": "https://github.com/d12frosted/mirror-elpa" | ||
} | ||
JSON | ||
) | ||
if echo "$response" | grep '"token"'; then | ||
echo "$response" | jq -r .token | read i_access_token | ||
else | ||
printf "\033[31;31mError: \033[0m" | ||
echo "$response" | jq -r .message | ||
echo "You'll need to create a GitHub API token manually." | ||
fi | ||
|
||
[ -n "$i_access_token" ] && break | ||
done | ||
|
||
[ -n "$i_access_token" ] && access_token="$i_access_token" | ||
|
||
[ -z "$name" ] && name="A Friendly Bot" | ||
printf "Bot name: ($name) " | ||
read i_name | ||
[ -n "$i_name" ] && name="$i_name" | ||
|
||
[ -z "$email" ] && | ||
email="$(echo "$name" | sed "s/ /./g" | tr '[:upper:]' '[:lower:]')@example" | ||
printf "Bot email: ($email) " | ||
read i_email | ||
[ -n "$i_email" ] && email="$i_email" | ||
|
||
[ -z "$message" ] && message="Sync archives" | ||
printf "Commit message: ($message) " | ||
read i_message | ||
[ -n "$i_message" ] && message="$i_message" | ||
|
||
printf "owner=%q\n" "$owner" > "$config_file" | ||
printf "repo=%q\n" "$repo" >> "$config_file" | ||
printf "name=%q\n" "$name" >> "$config_file" | ||
printf "email=%q\n" "$email" >> "$config_file" | ||
printf "message=%q\n" "$message" >> "$config_file" | ||
printf "access_token=%q\n" "$access_token" >> "$config_file" | ||
|
||
echo "Successfully wrote configuration to $config_file" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -ue | ||
|
||
# defaults | ||
mirror_path="" | ||
mirror_repo_remote_name="origin" | ||
mirror_repo_branch_name="master" | ||
elpa_clone_path="$HOME/.cache/elpa-clone" | ||
elpa_clone_url="https://github.com/dochang/elpa-clone.git" | ||
email="" | ||
name="" | ||
access_token="" | ||
|
||
PATH=/usr/local/bin:/usr/bin:/bin | ||
|
||
function git_config_hook { | ||
log "Git config hook" | ||
} | ||
|
||
# load configs | ||
config_file=$1 | ||
[ -f "$config_file" ] && source "$config_file" | ||
|
||
# setup url | ||
MIRROR_REPO="https://${owner}:${access_token}@github.com/${owner}/${repo}.git" | ||
|
||
function log { | ||
echo "[$(date '+%d/%m/%y %H:%M:%S')]" "$@" | ||
} | ||
|
||
function clone { | ||
log "Updating mirror for $2 ($1)" | ||
emacs -l "$elpa_clone_path/elpa-clone.el" -nw --batch --eval="(elpa-clone \"$1\" \"$mirror_path/$2\")" | ||
} | ||
|
||
if [[ "$mirror_path" = "" ]]; then | ||
mirror_path="$(mktemp -d)" | ||
fi | ||
|
||
trap '[ "$?" -eq 0 ] || log Error! Could not update elpa mirrors!' EXIT | ||
|
||
log "Start updating elpa mirrors" | ||
log "mirror_path: $mirror_path" | ||
log "MIRROR_REPO: $MIRROR_REPO" | ||
log "elpa_clone_path: $elpa_clone_path" | ||
log "PATH: $PATH" | ||
|
||
if [[ ! -d $elpa_clone_path ]]; then | ||
log "elpa-clone tool is missing, installing it..." | ||
git clone --depth 1 "$elpa_clone_url" "$elpa_clone_path" | ||
else | ||
log "updating elpa-clone" | ||
cd "$elpa_clone_path" | ||
git fetch origin | ||
git reset --hard origin/master | ||
fi | ||
|
||
if [[ ! -d "$mirror_path" ]]; then | ||
log "cloning mirror repository" | ||
git clone --depth 1 "$MIRROR_REPO" "$mirror_path" | ||
fi | ||
|
||
cd "$mirror_path" | ||
|
||
# if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1; then | ||
# log "updating mirror repository" | ||
# git fetch "$mirror_repo_remote_name" | ||
# git reset --hard "${mirror_repo_remote_name}/${mirror_repo_branch_name}" | ||
# fi | ||
|
||
clone "http://orgmode.org/elpa/" "org" | ||
clone "https://elpa.gnu.org/packages/" "gnu" | ||
clone "rsync://melpa.org/packages/" "melpa" | ||
clone "rsync://stable.melpa.org/packages/" "stable-melpa" | ||
|
||
if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1; then | ||
log "Configure repository" | ||
git config user.name "$name" | ||
git config user.email "$email" | ||
git_config_hook | ||
git add --all | ||
log "Committing and pushing all changes to mirror repository" | ||
git commit -m "snapshot $(date '+%d/%m/%y %H:%M:%S')" | ||
if [[ $"MIRROR_REPO" != "" ]]; then | ||
git push "$MIRROR_REPO" "$mirror_repo_branch_name" | ||
fi | ||
fi | ||
|
||
log "Done updating elpa mirrors" |