2021-07-13 08:40:16 +00:00
#! /bin/bash
2021-07-14 11:52:19 +00:00
# Do some prep work
command -v git >/dev/null 2>& 1 || {
echo >& 2 "We require git for this script to run, but it's not installed. Aborting."
exit 1
}
2021-07-15 10:29:14 +00:00
command -v curl >/dev/null 2>& 1 || {
echo >& 2 "We require curl for this script to run, but it's not installed. Aborting."
exit 1
}
2021-07-14 11:52:19 +00:00
2021-07-13 08:40:16 +00:00
# get start time
2021-08-31 10:22:57 +00:00
START_BUILD = $( date +"%s" )
2021-07-13 08:40:16 +00:00
# use UTC+00:00 time also called zulu
2021-08-31 10:22:57 +00:00
START_DATE = $( TZ = ":ZULU" date +"%m/%d/%Y @ %R (UTC)" )
2021-07-14 16:00:22 +00:00
# BOT name
2021-08-31 10:22:57 +00:00
BOT_NAME = "Octosync v1.0"
2021-07-13 08:40:16 +00:00
# main function ˘Ô≈ôﺣ
function main( ) {
2021-07-14 16:00:22 +00:00
# always show the config values
showConfValues
2021-07-13 08:40:16 +00:00
# check that all needed values are set
# clone all needed repos
2021-07-14 16:00:22 +00:00
if checkConfValues && cloneRepos; then
# move the files and folders
moveFoldersFiles
# crazy but lets check anyway
if [ -d " ${ ROOT_TARGET_FOLDER } " ] ; then
# move to root target folder
2021-08-31 10:22:57 +00:00
cd " ${ ROOT_TARGET_FOLDER } " || exit 24
2021-07-14 16:00:22 +00:00
# merge all changes
if mergeChanges; then
# check what action to take to get
# the changes into the target repository
if ( ( " $TARGET_REPO_ACTION " = = 1) ) ; then
# we must merge directly to target
makeMergeToTarget
else
# we should create a pull request
makePullRequestAgainstTarget
fi
# check if all went well
if [ $? -eq 0 ] ; then
# give the final success message
finalMessage "========= Successfully synced ========================" ">=>"
fi
else
# show that there was noting to do...
finalMessage "========= Tried to sync (but nothing changed) ========" "==="
fi
fi
2021-07-13 20:41:00 +00:00
fi
2021-07-14 16:00:22 +00:00
echo "There was a serious error."
exit 22
2021-07-14 05:51:01 +00:00
}
2021-07-13 08:40:16 +00:00
# show the configuration values
2021-07-14 16:00:22 +00:00
function checkConfValues( ) {
2021-07-13 08:40:16 +00:00
# check if we have found errors
local ERROR = 0
# make sure SOURCE_REPO is set
2021-08-31 10:22:57 +00:00
[ [ ! " ${ SOURCE_REPO } " = = *"/" * ] ] && _echo " SOURCE_REPO: ${ SOURCE_REPO } is not a repo path! " && ERROR = 1
2021-07-14 16:00:22 +00:00
[ [ ! $( wget -S --spider " https://github.com/ ${ SOURCE_REPO } " 2>& 1 | grep 'HTTP/1.1 200 OK' ) ] ] &&
2021-08-31 10:22:57 +00:00
_echo " SOURCE_REPO:https://github.com/ ${ SOURCE_REPO } is not set correctly, or the github user does not have access! " &&
2021-07-14 16:00:22 +00:00
ERROR = 1
2021-07-13 08:40:16 +00:00
# make sure SOURCE_REPO_BRANCH is set
2021-08-31 10:22:57 +00:00
[ ${# SOURCE_REPO_BRANCH } -le 1 ] && _echo " SOURCE_REPO_BRANCH: ${ SOURCE_REPO_BRANCH } is not set correctly! " && ERROR = 1
2021-07-13 08:40:16 +00:00
# make sure SOURCE_REPO_FOLDERS is set
2021-08-31 10:22:57 +00:00
[ ${# SOURCE_REPO_FOLDERS } -le 1 ] && _echo " SOURCE_REPO_FOLDERS: ${ SOURCE_REPO_FOLDERS } is not set correctly! " && ERROR = 1
2021-07-13 08:40:16 +00:00
# make sure TARGET_REPO is set
2021-08-31 10:22:57 +00:00
[ [ ! " ${ TARGET_REPO } " = = *"/" * ] ] && _echo " TARGET_REPO: ${ TARGET_REPO } is not a repo path! " && ERROR = 1
2021-07-14 16:00:22 +00:00
[ [ ! $( wget -S --spider " https://github.com/ ${ TARGET_REPO } " 2>& 1 | grep 'HTTP/1.1 200 OK' ) ] ] &&
2021-08-31 10:22:57 +00:00
_echo " TARGET_REPO:https://github.com/ ${ TARGET_REPO } is not set correctly, or the github user does not have access! " &&
2021-07-14 16:00:22 +00:00
ERROR = 1
2021-07-13 08:40:16 +00:00
# make sure TARGET_REPO_BRANCH is set
2021-08-31 10:22:57 +00:00
[ ${# TARGET_REPO_BRANCH } -le 1 ] && _echo " TARGET_REPO_BRANCH: ${ TARGET_REPO_BRANCH } is not set correctly! " && ERROR = 1
2021-07-13 08:40:16 +00:00
# make sure TARGET_REPO_FOLDERS is set
2021-08-31 10:22:57 +00:00
[ ${# TARGET_REPO_FOLDERS } -le 1 ] && _echo " TARGET_REPO_FOLDERS: ${ TARGET_REPO_FOLDERS } is not set correctly! " && ERROR = 1
2021-07-13 08:40:16 +00:00
# check that the correct action is set
2021-08-31 10:22:57 +00:00
! ( ( " $TARGET_REPO_ACTION " = = 1) ) && ! ( ( " $TARGET_REPO_ACTION " = = 0) ) && _echo " TARGET_REPO_ACTION: ${ TARGET_REPO_ACTION } is not set correctly! " && ERROR = 1
2021-07-13 08:40:16 +00:00
# make sure TARGET_REPO_FORK is set correctly if set
if [ ${# TARGET_REPO_FORK } -ge 1 ] ; then
2021-08-31 10:22:57 +00:00
[ [ ! " ${ TARGET_REPO_FORK } " = = *"/" * ] ] && _echo " TARGET_REPO_FORK: ${ TARGET_REPO_FORK } is not a repo path! " && ERROR = 1
2021-07-14 16:00:22 +00:00
[ [ ! $( wget -S --spider " https://github.com/ ${ TARGET_REPO_FORK } " 2>& 1 | grep 'HTTP/1.1 200 OK' ) ] ] &&
2021-08-31 10:22:57 +00:00
_echo " TARGET_REPO_FORK:https://github.com/ ${ TARGET_REPO_FORK } is not set correctly, or the github user does not have access! " &&
2021-07-14 16:00:22 +00:00
ERROR = 1
2021-07-13 08:40:16 +00:00
fi
# if error found exit
2021-07-14 08:08:38 +00:00
( ( " $ERROR " = = 1) ) && exit 19
2021-07-14 16:00:22 +00:00
return 0
2021-07-13 08:40:16 +00:00
}
# clone the repo
2021-07-14 16:00:22 +00:00
function cloneRepos( ) {
2021-07-13 08:40:16 +00:00
# clone the source repo (we don't need access on this one)
2021-07-14 11:52:19 +00:00
[ [ " ${ SOURCE_REPO } " = = *"/" * ] ] && cloneRepo " https://github.com/ ${ SOURCE_REPO } .git " " ${ SOURCE_REPO_BRANCH } " " ${ ROOT_SOURCE_FOLDER } "
2021-07-13 08:40:16 +00:00
# clone the forked target repo if set
if [ [ " ${ TARGET_REPO_FORK } " = = *"/" * ] ] ; then
# we need access on this one, so we use git@github.com:
2021-07-14 11:52:19 +00:00
cloneRepo " git@github.com: ${ TARGET_REPO_FORK } .git " " ${ TARGET_REPO_BRANCH } " " ${ ROOT_TARGET_FOLDER } "
# only rebase if fresh clone
2021-07-14 16:00:22 +00:00
if [ $? -eq 0 ] ; then
2021-07-14 11:52:19 +00:00
# rebase with upstream (we don't need access on this one)
rebaseWithUpstream " https://github.com/ ${ TARGET_REPO } .git " " ${ TARGET_REPO_BRANCH } " " ${ ROOT_TARGET_FOLDER } "
fi
2021-07-13 08:40:16 +00:00
# we must have merge set if we directly work with target repo
elif ( ( " $TARGET_REPO_ACTION " = = 1) ) ; then
# we need access on this one, so we use git@github.com:
2021-07-14 11:52:19 +00:00
cloneRepo " ${ TARGET_REPO } " " git@github.com: ${ TARGET_REPO_BRANCH } .git " " ${ ROOT_TARGET_FOLDER } "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo "You use a forked target (target.repo.fork=org/forked_repo) or set the (target.repo.merge=1) to merge directly into target."
2021-07-14 08:08:38 +00:00
exit 20
2021-07-13 08:40:16 +00:00
fi
2021-07-14 16:00:22 +00:00
return 0
2021-07-13 08:40:16 +00:00
}
# clone the repo
2021-07-14 16:00:22 +00:00
function cloneRepo( ) {
2021-07-13 08:40:16 +00:00
# set local values
local git_repo = " $1 "
local git_branch = " $2 "
local git_folder = " $3 "
2021-07-14 08:08:38 +00:00
# with test we don't clone again
2021-07-14 11:52:19 +00:00
# if folder already exist (if you dont want this behaviour manually remove the folders)
2021-07-14 08:08:38 +00:00
if ( ( " $TEST " = = 1) ) && [ -d " ${ git_folder } " ] ; then
2021-08-31 10:22:57 +00:00
_echo " folder: ${ git_folder } already exist, repo: ${ git_repo } was not cloned again. (test mode) "
2021-07-14 11:52:19 +00:00
return 1
2021-07-13 08:40:16 +00:00
else
2021-07-14 08:08:38 +00:00
# make sure the folder does not exist
[ -d " ${ git_folder } " ] && rm -fr " ${ git_folder } "
# clone the repo (but only a single branch)
2021-07-14 11:52:19 +00:00
git clone -b " $git_branch " --single-branch " $git_repo " " $git_folder "
2021-07-14 16:00:22 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " ${ git_repo } was cloned successfully. "
2021-07-14 08:08:38 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " ${ git_repo } failed to cloned successfully, check that the GitHub user has access to this repo! "
2021-07-14 08:08:38 +00:00
exit 21
fi
2021-07-13 08:40:16 +00:00
fi
2021-07-14 16:00:22 +00:00
2021-07-14 11:52:19 +00:00
return 0
2021-07-13 08:40:16 +00:00
}
2021-07-14 16:00:22 +00:00
# rebase repo with its upstream
function rebaseWithUpstream( ) {
2021-07-13 08:40:16 +00:00
# current folder
local current_folder = $PWD
# set local values
local git_repo_upstream = " $1 "
local git_branch = " $2 "
local git_folder = " $3 "
# just a random remote name
local git_upstream = "stroomOp"
# go into repo folder
2021-08-31 10:22:57 +00:00
cd " ${ git_folder } " || exit 23
2021-07-14 11:52:19 +00:00
# check out the upstream repository
git checkout -b " ${ git_upstream } " " $git_branch "
2021-08-31 10:22:57 +00:00
git pull " ${ git_repo_upstream } " " $git_branch "
2021-07-14 16:00:22 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " upstream: ${ git_repo_upstream } was pulled successfully. "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " Failed to pull upstream: ${ git_repo_upstream } successfully, check that the GitHub user has access to this repo! "
2021-07-14 08:08:38 +00:00
exit 10
2021-07-13 08:40:16 +00:00
fi
2021-07-13 20:41:00 +00:00
# make sure we are on the targeted branch
2021-07-13 08:40:16 +00:00
git checkout " $git_branch "
2021-07-14 11:52:19 +00:00
# rebase to upstream
git rebase " ${ git_upstream } "
2021-07-14 16:00:22 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " upstream: ${ git_repo_upstream } was rebased into the forked repo successfully. "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " Failed to rebase upstream: ${ git_repo_upstream } successfully! "
2021-07-14 08:08:38 +00:00
exit 12
2021-07-13 08:40:16 +00:00
fi
# make sure this is not a test
if ( ( " $TEST " = = 1) ) ; then
2021-08-31 10:22:57 +00:00
_echo " The forked repo of upstream: ${ git_repo_upstream } not updated, as this is a test. "
2021-07-13 08:40:16 +00:00
else
# force update the forked repo
2021-07-14 11:52:19 +00:00
git push origin " $git_branch " --force
2021-07-14 16:00:22 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " The forked repo of upstream: ${ git_repo_upstream } successfully updated. "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo "Failed to update the forked repo, check that the GitHub user has access to this repo!"
2021-07-14 08:08:38 +00:00
exit 13
2021-07-13 08:40:16 +00:00
fi
fi
# return to original folder
2021-07-15 10:29:14 +00:00
cd " ${ current_folder } " || exit 24
return 0
2021-07-13 08:40:16 +00:00
}
# move the source folders and files to the target folders
2021-07-14 16:00:22 +00:00
function moveFoldersFiles( ) {
2021-07-14 11:52:19 +00:00
# with test we show in what folder
# we are in when we start moving stuff
if ( ( " $TEST " = = 1) ) ; then
2021-08-31 10:22:57 +00:00
_echo " Location: [ $PWD ] "
2021-07-14 11:52:19 +00:00
fi
2021-07-13 08:40:16 +00:00
# check if we have an array of folders
if [ [ " ${ SOURCE_REPO_FOLDERS } " = = *";" * ] ] && [ [ " ${ TARGET_REPO_FOLDERS } " = = *";" * ] ] ; then
# set the folders array
IFS = ';' read -ra source_folders <<< " ${ SOURCE_REPO_FOLDERS } "
IFS = ';' read -ra target_folders <<< " ${ TARGET_REPO_FOLDERS } "
# check if we have files array
local has_files = 0
if [ [ " ${ SOURCE_REPO_FILES } " = = *";" * ] ] ; then
IFS = ';' read -ra source_files <<< " ${ SOURCE_REPO_FILES } "
has_files = 1
fi
# now we loop over the source folder
for key in " ${ !source_folders[@] } " ; do
# check that the target folder is set
if [ ${ target_folders [key]+abc } ] ; then
# check of we have files
if ( ( " $has_files " = = 1) ) ; then
if [ ${ source_files [key]+abc } ] ; then
moveFolderFiles " ${ source_folders [key] } " " ${ target_folders [key] } " " ${ source_files [key] } "
else
2021-08-31 10:22:57 +00:00
_echo " Source folder: ${ source_folders [key] } file mismatched! "
2021-07-14 08:08:38 +00:00
exit 14
2021-07-13 08:40:16 +00:00
fi
# just move all the content of the folder
else
moveFolder " ${ source_folders [key] } " " ${ target_folders [key] } "
fi
else
2021-08-31 10:22:57 +00:00
_echo " Source folder: ${ source_folders [key] } mismatched! "
2021-07-14 08:08:38 +00:00
exit 15
2021-07-13 08:40:16 +00:00
fi
done
2021-07-13 20:41:00 +00:00
# move just one folder (so it has no semicolons)
elif [ [ " ${ SOURCE_REPO_FOLDERS } " != *";" * ] ] && [ [ " ${ TARGET_REPO_FOLDERS } " != *";" * ] ] ; then
# check if we have source files and it has no semicolons like the folders
if [ ${# SOURCE_REPO_FILES } -ge 2 ] && [ [ " ${ SOURCE_REPO_FILES } " != *";" * ] ] ; then
moveFolderFiles " ${ SOURCE_REPO_FOLDERS } " " ${ TARGET_REPO_FOLDERS } " " ${ SOURCE_REPO_FILES } "
else
moveFolder " ${ SOURCE_REPO_FOLDERS } " " ${ TARGET_REPO_FOLDERS } "
fi
else
2021-08-31 10:22:57 +00:00
_echo " Source folder: ${ SOURCE_REPO_FOLDERS } -> Target folder: ${ TARGET_REPO_FOLDERS } mismatched! "
2021-07-14 08:08:38 +00:00
exit 16
2021-07-13 08:40:16 +00:00
fi
}
2021-07-13 20:41:00 +00:00
# move the source folder's files to the target folders
2021-07-14 16:00:22 +00:00
function moveFolderFiles( ) {
2021-07-13 08:40:16 +00:00
local source_folder = " $1 "
local target_folder = " $2 "
local source_files = " ${ 3 : =0 } "
# prep folders to have no trailing or leading forward slashes
source_folder = " ${ source_folder %/ } "
source_folder = " ${ source_folder #/ } "
target_folder = " ${ target_folder %/ } "
target_folder = " ${ target_folder #/ } "
# make sure the source folder exist
2021-07-14 11:52:19 +00:00
if [ ! -d " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } " ] ; then
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] since source folder does not exist. (failure) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
else
# make sure the target folder exist
2021-07-14 11:52:19 +00:00
if [ ! -f " ${ ROOT_TARGET_FOLDER } / ${ target_folder } " ] ; then
2021-07-13 08:40:16 +00:00
# create this folder if it does not exist
2021-07-14 11:52:19 +00:00
mkdir -p " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
fi
# check if we have number command
re = '^[0-9]+$'
if [ [ " $source_files " = ~ $re ] ] ; then
# 0 = all
if ( ( " $source_files " = = 0) ) ; then
# copy both files and sub-folders recursive by force
2021-07-14 11:52:19 +00:00
cp -fr " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / " * " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " copied [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } /* -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (success) "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } /* -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (failure [0]) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
fi
# 1 = only all files (no sub-folders)
elif ( ( " $source_files " = = 1) ) ; then
# copy only the file by force
2021-07-14 11:52:19 +00:00
cp -f " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / " * " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " copied [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } /* -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (success) "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } /* -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (failure [1]) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
fi
# 2 = only all sub-folders and their files
elif ( ( " $source_files " = = 2) ) ; then
2021-08-31 10:22:57 +00:00
_echo "This command:2 means to copy only all sub-folders and their files."
_echo " Yet this file command: ${ source_files } for ${ ROOT_SOURCE_FOLDER } / ${ source_folder } is not ready to be used... so nothing was copied! "
2021-07-13 08:40:16 +00:00
# could be a file (name as number) so we try to copy it
else
# copy file/folder recursive by force
2021-07-14 11:52:19 +00:00
cp -fr " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ source_files } " " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " copied [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ source_files } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (success) "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ source_files } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (failure [.]) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
fi
fi
else
if [ [ " ${ source_files } " = = *"," * ] ] ; then
# convert this to an array of files names
IFS = ',' read -ra source_multi_files <<< " ${ source_files } "
# now we loop over the files
for file in " ${ source_multi_files [@] } " ; do
# prep the file
file = " ${ file %/ } "
file = " ${ file #/ } "
# copy file/folder recursive by force
2021-07-14 11:52:19 +00:00
cp -fr " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ file } " " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " copied [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ file } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (success) "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ file } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (failure [..]) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
fi
done
else
# prep the file
source_files = " ${ source_files %/ } "
source_files = " ${ source_files #/ } "
# copy file/folder recursive by force
2021-07-14 11:52:19 +00:00
cp -fr " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ source_files } " " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " copied [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ source_files } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (success) "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / ${ source_files } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (failure [...]) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
fi
fi
fi
fi
}
# move the source folder and all content to the target folder
2021-07-14 16:00:22 +00:00
function moveFolder( ) {
2021-07-13 08:40:16 +00:00
local source_folder = " $1 "
local target_folder = " $2 "
# prep folders to have no trailing or leading forward slashes
source_folder = " ${ source_folder %/ } "
source_folder = " ${ source_folder #/ } "
target_folder = " ${ target_folder %/ } "
target_folder = " ${ target_folder #/ } "
# make sure the source folder exist
2021-07-14 11:52:19 +00:00
if [ ! -d " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } " ] ; then
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] since source folder does not exist. (failure ) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
else
# make sure the target folder exist
2021-07-14 11:52:19 +00:00
if [ ! -f " ${ ROOT_TARGET_FOLDER } / ${ target_folder } " ] ; then
2021-07-13 08:40:16 +00:00
# create this folder if it does not exist
2021-07-14 11:52:19 +00:00
mkdir -p " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
fi
# copy both files and sub-folders recursive by force
2021-07-14 11:52:19 +00:00
cp -fr " ${ ROOT_SOURCE_FOLDER } / ${ source_folder } / " * " ${ ROOT_TARGET_FOLDER } / ${ target_folder } "
2021-07-13 08:40:16 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo " copied [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } /* -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (success) "
2021-07-13 08:40:16 +00:00
else
2021-08-31 10:22:57 +00:00
_echo " failed to copy [ ${ ROOT_SOURCE_FOLDER } / ${ source_folder } /* -> ${ ROOT_TARGET_FOLDER } / ${ target_folder } ] (failure [*]) "
_echo " current_folder: ${ PWD } "
2021-07-13 08:40:16 +00:00
fi
fi
}
2021-07-14 16:00:22 +00:00
# merge changes
function mergeChanges( ) {
# we first check if there are changes
if [ [ -z $( git status --porcelain) ] ] ; then
2021-08-31 10:22:57 +00:00
_echo "There has been no changes to the target repository, so noting to commit."
2021-07-14 16:00:22 +00:00
return 1
else
# make a commit of the changes
git add .
2021-08-31 10:22:57 +00:00
git commit -am" $BOT_NAME [merge: ${ START_DATE } ] "
2021-07-14 16:00:22 +00:00
if [ $? -eq 0 ] ; then
2021-08-31 10:22:57 +00:00
_echo "Changes were committed."
2021-07-14 16:00:22 +00:00
return 0
else
2021-08-31 10:22:57 +00:00
_echo "Failed to commit changed"
2021-07-14 16:00:22 +00:00
retunr 1
fi
fi
}
# merge the changes into the target repository
function makeMergeToTarget( ) {
# we dont make changes to remote repos while testing
if ( ( " $TEST " = = 1) ) ; then
2021-08-31 10:22:57 +00:00
_echo "changes where not merged (test mode)"
2021-07-14 16:00:22 +00:00
return 0
fi
# push the changes
git push
# check if this is a fork (since then we are not done)
if [ [ " ${ TARGET_REPO_FORK } " = = *"/" * ] ] ; then
# in a fork we must create a pull request against the target repo, and then merge it.
createPullRequest && return 0
fi
return 0
}
# create a pull request against the target repository
function makePullRequestAgainstTarget( ) {
# we dont make changes to remote repos while testing
if ( ( " $TEST " = = 1) ) ; then
2021-08-31 10:22:57 +00:00
_echo "pull request was not made (test mode)"
2021-07-14 16:00:22 +00:00
return 0
fi
# check if this is a fork (should always be)
if [ [ " ${ TARGET_REPO_FORK } " = = *"/" * ] ] ; then
# we need to push the changes up
git push
# creat the pull request
createPullRequest && return 0
fi
return 1
}
# create the pull request
function createPullRequest( ) {
2021-08-31 10:22:57 +00:00
_echo "we need github CLI to do this"
2021-07-14 16:00:22 +00:00
return 0
}
2021-08-31 10:22:57 +00:00
# give the echo messages
# only if not set to be quiet
function _echo( ) {
if ( ( " $QUIET " = = 0) ) ; then
echo " $1 "
fi
}
2021-07-14 16:00:22 +00:00
# give the final
function finalMessage( ) {
# set the build time
2021-08-31 10:22:57 +00:00
END_BUILD = $( date +"%s" )
SECONDS_BUILD = $(( END_BUILD - START_BUILD))
cat <<EOF
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
$1
( selected folders/files)
source:${ SOURCE_REPO }
$2
target:${ TARGET_REPO }
= = = = > date:${ START_DATE }
= = = = > duration:${ SECONDS_BUILD } seconds
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
EOF
2021-07-14 16:00:22 +00:00
exit 0
}
2021-07-13 08:40:16 +00:00
# set any/all configuration values
function setConfValues( ) {
2021-08-31 10:22:57 +00:00
if [ -f " $CONFIG_FILE " ] ; then
2021-07-13 08:40:16 +00:00
# set all configuration values
# see: conf/example (for details)
SOURCE_REPO = $( getConfVal "source\.repo\.path" " ${ SOURCE_REPO } " )
SOURCE_REPO_BRANCH = $( getConfVal "source\.repo\.branch" " ${ SOURCE_REPO_BRANCH } " )
SOURCE_REPO_FOLDERS = $( getConfVal "source\.repo\.folders" " ${ SOURCE_REPO_FOLDERS } " )
SOURCE_REPO_FILES = $( getConfVal "source\.repo\.files" " ${ SOURCE_REPO_FILES } " )
TARGET_REPO = $( getConfVal "target\.repo\.path" " ${ TARGET_REPO } " )
TARGET_REPO_BRANCH = $( getConfVal "target\.repo\.branch" " ${ TARGET_REPO_BRANCH } " )
TARGET_REPO_FOLDERS = $( getConfVal "target\.repo\.folders" " ${ TARGET_REPO_FOLDERS } " )
2021-07-14 16:00:22 +00:00
# To merge or just make a PR (0 = PR; 1 = Merge)
2021-07-13 08:40:16 +00:00
TARGET_REPO_ACTION = $( getConfVal "target\.repo\.merge" " ${ TARGET_REPO_ACTION } " )
2021-07-14 16:00:22 +00:00
# Target fork is rebased to upstream target then updated and used to make a PR or Merge
2021-07-13 08:40:16 +00:00
TARGET_REPO_FORK = $( getConfVal "target\.repo\.fork" " ${ TARGET_REPO_FORK } " )
fi
}
# get default properties from config file
function getConfVal( ) {
local PROP_KEY = " $1 "
2021-08-31 10:22:57 +00:00
local PROP_VALUE
# get the value if set
PROP_VALUE = $( cat " $CONFIG_FILE " | grep " $PROP_KEY " | cut -d'=' -f2)
2021-07-13 08:40:16 +00:00
echo " ${ PROP_VALUE :- $2 } "
}
# show the configuration values
2021-07-14 16:00:22 +00:00
function showConfValues( ) {
2021-08-31 10:22:57 +00:00
cat <<EOF
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
${ BOT_NAME }
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CONFIG_FILE: ${ CONFIG_FILE }
TEST: ${ TEST }
SOURCE_REPO: ${ SOURCE_REPO }
SOURCE_REPO_BRANCH: ${ SOURCE_REPO_BRANCH }
SOURCE_REPO_FOLDERS: ${ SOURCE_REPO_FOLDERS }
SOURCE_REPO_FILES: ${ SOURCE_REPO_FILES }
TARGET_REPO: ${ TARGET_REPO }
TARGET_REPO_BRANCH: ${ TARGET_REPO_BRANCH }
TARGET_REPO_FOLDERS: ${ TARGET_REPO_FOLDERS }
TARGET_REPO_ACTION: ${ TARGET_REPO_ACTION }
TARGET_REPO_FORK: ${ TARGET_REPO_FORK }
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
EOF
2021-07-13 08:40:16 +00:00
}
# help message ʕ•ᴥ•ʔ
function show_help( ) {
cat <<EOF
Usage: ${ 0 ##*/ :- } [ OPTION...]
Options
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--conf= <path>
set all the config properties with a file
properties examples are:
2021-08-31 10:22:57 +00:00
source.repo.path= [ org] /[ repo]
source.repo.branch= [ branch]
source.repo.folders= [ folder/path_a; folder/path_b]
source.repo.files= [ 0; a-file.js,b-file.js]
target.repo.path= [ org] /[ repo]
target.repo.branch= [ branch]
target.repo.folders= [ folder/path_a; folder/path_b]
# To merge or just make a PR (0 = PR; 1 = Merge)
target.repo.merge= 1
# Target fork is rebased then updated and used to make a PR or Merge
target.repo.fork= [ org] /[ repo]
see: conf/example
2021-07-13 08:40:16 +00:00
example: ${ 0 ##*/ :- } --conf= /home/$USER /.config/repos-to-sync.conf
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2021-08-31 10:22:57 +00:00
--source-path= [ org] /[ repo]
set the source repository path as found on github ( for now)
example: ${ 0 ##*/ :- } --source-path= Octoleo/Octosync
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--source-branch= [ branch-name]
set the source repository branch name
example: ${ 0 ##*/ :- } --source-branch= master
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--source-folders= [ folder-path]
set the source folder path
separate multiple paths with a semicolon
example: ${ 0 ##*/ :- } --source-folders= folder/path1; folder/path2
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--source-files= [ files]
set the source files
omitting this will sync all files in the folders
separate multiple folders files with a semicolon
separate multiple files in a folder with a comma
each set of files will require the same number( position) path in the --source-folders
[ dynamic options]
setting a 0 in a position will allow all files & sub-folders of that folder to be synced
setting a 1 in a position will allow only all files in that folder to be synced
setting a 2 in a position will allow only all sub-folders in that folder to be synced
see: conf/example ( more details)
example: ${ 0 ##*/ :- } --source-files= file.txt,file2.txt; 0
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--target-path= [ org] /[ repo]
set the target repository path as found on github ( for now)
example: ${ 0 ##*/ :- } --target-path= MyOrg/Octosync
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--target-branch= [ branch-name]
set the target repository branch name
example: ${ 0 ##*/ :- } --target-branch= master
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--target-folders= [ folder-path]
set the target folder path
separate multiple paths with a semicolon
example: ${ 0 ##*/ :- } --target-folders= folder/path1; folder/path2
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--target-fork= [ org] /[ repo]
set the target fork repository path as found on github ( for now)
the target fork is rebased then updated and used to make a PR or Merge
example: ${ 0 ##*/ :- } --target-fork= MyOrg/Octosync
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-m | --target-repo-merge | --target-merge
force direct merge behaviour if permissions allow
example: ${ 0 ##*/ :- } -m
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-pr | --target-repo-pull-request | --target-pull-request
create a pull request instead of a direct merge if permissions allow
example: ${ 0 ##*/ :- } -pr
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--target-token= xxxxxxxxxxxxxxxxxxxxxxx
pass the token needed to merge or create a pull request on the target repo
example: ${ 0 ##*/ :- } --target-token= xxxxxxxxxxxxxxxxxxxxxxx
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2021-07-13 08:40:16 +00:00
--test
activate the test behaviour
example: ${ 0 ##*/ :- } --test
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
--dry
To show all configuration, and not update repos
example: ${ 0 ##*/ :- } --dry
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-h| --help
display this help menu
example: ${ 0 ##*/ :- } -h
example: ${ 0 ##*/ :- } --help
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2021-07-14 16:00:22 +00:00
${ BOT_NAME }
2021-07-13 08:40:16 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
EOF
}
# DEFAULTS/GLOBALS
CONFIG_FILE = ""
TEST = 0
2021-08-31 10:22:57 +00:00
DRY_RUN = 0
QUIET = 0
TARGET_REPO_TOKEN = ""
2021-07-13 08:40:16 +00:00
2021-07-14 11:52:19 +00:00
# local repo folders
ROOT_SOURCE_FOLDER = "source_repo"
ROOT_TARGET_FOLDER = "target_repo"
2021-07-13 08:40:16 +00:00
# CONFIG VALUES
# see: conf/example (for details)
SOURCE_REPO = ""
SOURCE_REPO_BRANCH = ""
SOURCE_REPO_FOLDERS = ""
SOURCE_REPO_FILES = ""
TARGET_REPO = ""
TARGET_REPO_BRANCH = ""
TARGET_REPO_FOLDERS = ""
TARGET_REPO_ACTION = 0 # To merge or just make a PR (0 = PR; 1 = Merge)
2021-07-14 16:00:22 +00:00
TARGET_REPO_FORK = "" # Target fork is rebased then updated and used to make a PR or Merge
2021-07-13 08:40:16 +00:00
# check if we have options
while :; do
case $1 in
-h | --help)
show_help # Display a usage synopsis.
exit
; ;
--dry)
2021-08-31 10:22:57 +00:00
DRY_RUN = 1
; ;
-q | --quiet)
QUIET = 1
2021-07-13 08:40:16 +00:00
; ;
--test) # set the test behaviour
TEST = 1
; ;
2021-07-14 05:51:01 +00:00
--conf | --config) # Takes an option argument; ensure it has been specified.
2021-07-13 08:40:16 +00:00
if [ " $2 " ] ; then
CONFIG_FILE = $2
shift
else
echo 'ERROR: "--conf" requires a non-empty option argument.'
2021-07-14 08:08:38 +00:00
exit 17
2021-07-13 08:40:16 +00:00
fi
; ;
2021-07-14 05:51:01 +00:00
--conf= ?* | --config= ?*)
2021-07-13 08:40:16 +00:00
CONFIG_FILE = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
2021-07-14 11:52:19 +00:00
--conf= | --config= ) # Handle the case of an empty --conf=
echo 'ERROR: "--conf=" requires a non-empty option argument.'
2021-07-14 08:08:38 +00:00
exit 17
2021-07-13 08:40:16 +00:00
; ;
2021-08-31 10:22:57 +00:00
--source-repo-path | --source-path) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
SOURCE_REPO = $2
shift
else
echo 'ERROR: "--source-repo-path" requires a non-empty option argument.'
exit 17
fi
; ;
--source-repo-path= ?* | --source-path= ?*)
SOURCE_REPO = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--source-repo-path= | --source-path= ) # Handle the case of an empty --source-repo-path=
echo 'ERROR: "--source-repo-path=" requires a non-empty option argument.'
exit 17
; ;
--source-repo-branch | --source-branch) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
SOURCE_REPO_BRANCH = $2
shift
else
echo 'ERROR: "--source-repo-branch" requires a non-empty option argument.'
exit 17
fi
; ;
--source-repo-branch= ?* | --source-branch= ?*)
SOURCE_REPO_BRANCH = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--source-repo-branch= | --source-branch= ) # Handle the case of an empty --source-repo-branch=
echo 'ERROR: "--source-repo-branch=" requires a non-empty option argument.'
exit 17
; ;
--source-repo-folders | --source-folders) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
SOURCE_REPO_FOLDERS = $2
shift
else
echo 'ERROR: "--source-repo-folders" requires a non-empty option argument.'
exit 17
fi
; ;
--source-repo-folders= ?* | --source-folders= ?*)
SOURCE_REPO_FOLDERS = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--source-repo-folders= | --source-folders= ) # Handle the case of an empty --source-repo-folders=
echo 'ERROR: "--source-repo-folders=" requires a non-empty option argument.'
exit 17
; ;
--source-repo-files | --source-files) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
SOURCE_REPO_FILES = $2
shift
else
echo 'ERROR: "--source-repo-files" requires a non-empty option argument.'
exit 17
fi
; ;
--source-repo-files= ?* | --source-files= ?*)
SOURCE_REPO_FILES = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--source-repo-files= | --source-files= ) # Handle the case of an empty --source-repo-files=
echo 'ERROR: "--source-repo-files=" requires a non-empty option argument.'
exit 17
; ;
--target-repo-path | --target-path) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
TARGET_REPO = $2
shift
else
echo 'ERROR: "--target-repo-path" requires a non-empty option argument.'
exit 17
fi
; ;
--target-repo-path= ?* | --target-path= ?*)
TARGET_REPO = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--target-repo-path= | --target-path= ) # Handle the case of an empty --target-repo-path=
echo 'ERROR: "--target-repo-path=" requires a non-empty option argument.'
exit 17
; ;
--target-repo-branch | --target-branch) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
TARGET_REPO_BRANCH = $2
shift
else
echo 'ERROR: "--target-repo-branch" requires a non-empty option argument.'
exit 17
fi
; ;
--target-repo-branch= ?* | --target-branch= ?*)
TARGET_REPO_BRANCH = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--target-repo-branch= | --target-branch= ) # Handle the case of an empty --target-repo-branch=
echo 'ERROR: "--target-repo-branch=" requires a non-empty option argument.'
exit 17
; ;
--target-repo-folders | --target-folders) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
TARGET_REPO_FOLDERS = $2
shift
else
echo 'ERROR: "--target-repo-folders" requires a non-empty option argument.'
exit 17
fi
; ;
--target-repo-folders= ?* | --target-folders= ?*)
TARGET_REPO_FOLDERS = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--target-repo-folders= | --target-folders= ) # Handle the case of an empty --target-repo-folders=
echo 'ERROR: "--target-repo-folders=" requires a non-empty option argument.'
exit 17
; ;
--target-repo-fork | --target-fork) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
TARGET_REPO_FORK = $2
shift
else
echo 'ERROR: "--target-repo-fork" requires a non-empty option argument.'
exit 17
fi
; ;
--target-repo-fork= ?* | --target-fork= ?*)
TARGET_REPO_FORK = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--target-repo-fork= | --target-fork= ) # Handle the case of an empty --target-repo-fork=
echo 'ERROR: "--target-repo-fork=" requires a non-empty option argument.'
exit 17
; ;
-m | --target-repo-merge | --target-merge) # To merge changes into target repository
TARGET_REPO_ACTION = 1 # (1 = merge)
; ;
-pr | --target-repo-pull-request | --target-pull-request) # To make a pull request into target repository
TARGET_REPO_ACTION = 0 # (0 = pull request)
; ;
--target-repo-token | --target-token) # Takes an option argument; ensure it has been specified.
if [ " $2 " ] ; then
TARGET_REPO_TOKEN = $2
shift
else
echo 'ERROR: "--target-repo-token" requires a non-empty option argument.'
exit 17
fi
; ;
--target-repo-token= ?* | --target-token= ?*)
TARGET_REPO_TOKEN = ${ 1 #*= } # Delete everything up to "=" and assign the remainder.
; ;
--target-repo-token= | --target-token= ) # Handle the case of an empty --target-repo-token=
echo 'ERROR: "--target-repo-token=" requires a non-empty option argument.'
exit 17
; ;
2021-07-13 08:40:16 +00:00
*) # Default case: No more options, so break out of the loop.
break ; ;
esac
shift
done
2021-07-15 10:29:14 +00:00
# check if the config is passed via a URL
if [ [ " ${ CONFIG_FILE } " = ~ ^"http:" ] ] || [ [ " ${ CONFIG_FILE } " = ~ ^"https:" ] ] ; then
if [ [ $( wget -S --spider " ${ CONFIG_FILE } " 2>& 1 | grep 'HTTP/1.1 200 OK' ) ] ] ; then
wget --quiet " ${ CONFIG_FILE } " -O config_file_from_url
CONFIG_FILE = "config_file_from_url"
else
echo >& 2 " The config: ${ CONFIG_FILE } is not a valid URL. Aborting. "
exit 18
fi
fi
2021-07-13 08:40:16 +00:00
# set the configuration values
2021-08-31 10:22:57 +00:00
# config file can override commands passed
2021-07-13 08:40:16 +00:00
setConfValues
# show the config values ¯\_(ツ)_/¯
2021-08-31 10:22:57 +00:00
if ( ( " $DRY_RUN " = = 1) ) ; then
2021-07-13 08:40:16 +00:00
showConfValues
exit 0
fi
# run Main ┬┴┬┴┤(・_├┬┴┬┴
main
exit 0