我想自动拉取 git repo 并在无人值守的情况下构建该 repo。
有什么方法可以让我克隆存储库并在运行 git clone 后立即运行 make 吗?例如:
git clone << myrepo >> && make
答案1
之后的无人值守构建git clone
实际上没有什么意义。大多数情况下,您需要事先安装其他库。部分情况下,配置也是必要的。
如果经过这些调整后,项目可以构建,那么您可以自动化该过程,例如git pull
使用 git hooks 之后。
要使用 git hooks,请在项目文件夹post-merge
中放置或链接一个同名的脚本。.git/hooks
一个简单的post-merge
脚本如下所示:
#!/bin/bash
./configure
make
sudo make install
我有两个自己用过的例子可以给你。这些脚本并不完美。它们仅供参考。:
Atom 编辑器的合并后 git hook
#!/bin/bash
#
# A post-merge git hook for
# https://github.com/atom/atom
#
# ln -s [your_source_folder]/githooks/post-merge/post-merge_4_atom [your_source_folder]/atom/.git/hooks/post-merge
#
# Trap the INT signal (ctrl-c, for example)
trap trapint 2
packageConfig="package.json"
green="\e[0;32m"
red="\e[0;31m"
TOA="\e[0m" # Turn off character attributes
# Prints OK or FAILED! depending on previous command return value
function okfail () {
if [ $? -gt 0 ]; then
logError "There was an error. Aborting."
return 1
else
logInfo "OK"
return 0
fi
}
function trapint {
echo
echo
echo "$(basename "$0") SIGINT received"
cleanup
}
function cleanup {
echo "Cleaning up..."
removeRelease
echo "Bye."
echo
exit 1
}
function logInfo () {
echo -e "${green}$1${TOA}"
}
function logError () {
echo -e "${red}$1${TOA}"
}
function addRelease () {
version=$(jshon -e 'version' < "package.json" | tr -d "\"" | tr -d "\\\\")
release=$(git log | grep -c "^commit")
logInfo "Version: $version"
logInfo "Release: $release"
newVersion="$version-$release"
if [ -f "$packageConfig" ]; then
logInfo "Create backup file $packageConfig.bak"
cp "$packageConfig" "$packageConfig.bak"
okfail; [ $? -gt 0 ] && cleanup
if [ -f "$packageConfig.bak" ]; then
logInfo "Update $packageConfig with $newVersion"
sed -i "s/\"version\" *: *\"$version\"/\"version\": \"$newVersion\"/g" "$packageConfig"
okfail; [ $? -gt 0 ] && cleanup
fi
fi
}
function removeRelease () {
if [ -f "$packageConfig.bak" ]; then
logInfo "Restore file $packageConfig"
mv "$packageConfig.bak" "$packageConfig"
okfail
fi
}
exec < /dev/tty
while true; do
read -n 1 -p "Compile and install? [y/n]: " yn
echo;
case $yn in
[Yy]* )
break;;
[Nn]* ) exit;;
* ) echo "Please respond with [y]es or [n]o.";;
esac
done
cd ~/src/atom
addRelease
echo -e "${green}compile${TOA}"
script/build
echo -e "${green}build debian packge${TOA}"
script/grunt mkdeb
removeRelease
echo -e "${green}You can find the deb package here: \"/tmp/atom-build\"${TOA}"
ls -la /tmp/atom-build
echo -e "${green}Please install with \"sudo dpkg -i /tmp/atom-build/[deb-package]\"${TOA}"
用于配置、构建和安装的合并后脚本checkinstall
#!/bin/bash
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the version 2 of the GNU General Public License
# as published by the Free Software Foundation
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Thanks to Felipe Eduardo Sanchez Diaz Duran <[email protected]>,
# the author of checkinstall for the many ideas
#
#
# Trap the INT signal (ctrl-c, for example)
trap trapint 2
red="\e[0;31m"
green="\e[0;32m"
yellow="\e[0;33m"
TOA="\e[0m" # Turn off character attributes
bold="\e[0;1m"
# Enable alias expansion in command substitution
shopt -s expand_aliases
# Vefify that we have gettext available
gettext "Bye." &> /dev/null
if [ $? -gt 0 ]; then
alias ck_gettext="echo -e"
else
alias ck_gettext="gettext -s --"
fi
## echo with newline at the end
function echog() {
local format="$1"
shift
printf -- "$(ck_gettext "$format")\n" "$@" >&2
}
## echo with NO newline at the end
function echogn() {
local format="$1"
shift
printf -- "$(ck_gettext "$format")" "$@" >&2
}
# Prints OK or FAILED! depending on previous command return value
function okfail () {
if [ $? -gt 0 ]; then
logError "There was an error. Aborting."
return 1
else
logInfo "OK"
return 0
fi
}
function logInfo () {
green="\e[0;32m"
echog "${green}$1${TOA}"
}
function logWarn () {
yellow="\e[0;33m"
echog "${yellow}$1${TOA}"
}
function logError () {
red="\e[0;31m"
echog "${red}$1${TOA}"
}
function trapint {
echo
echo
echog "$(basename "$0") SIGINT received"
cleanup
}
function cleanup {
echogn "Cleaning up..."
okfail
echog "Bye."
echo
exit 1
}
function writeDescriptionPak {
if [ "$1" != "" ]
then
echo "$1" > description-pak
fi
}
function logArchitecture {
echog "\tArchitecture: ${green}$1${TOA}"
}
function logRequires {
echog "\tRequires: ${green}$1${TOA}"
}
function logMaintainer {
echog "\tMaintainer: ${green}$1${TOA}"
}
function logGroup {
echog "\tGroup: ${green}$1${TOA}"
}
function logSummary {
echog "\tSummary: ${green}$1${TOA}"
}
function logVersion {
echog "\tVersion: ${green}$1${TOA}"
}
function logName {
echog "\tName: ${green}$1${TOA}"
}
function logLicense {
echog "\tLicense: ${green}$1${TOA}"
}
if [ "$(command -v checkinstall)" == "" ]
then
logError "checkinstall not installed. Aborting."
cleanup
fi
if [ "$(command -v jshon)" == "" ]
then
logError "jshon not installed. Aborting."
cleanup
fi
isGit="1"
if [ ! -d ".git" ]
then
logWarn "No GIT project."
isGit="0"
#cleanup
fi
autogenParam=""
configureParam=""
checkinstallParam=""
projectBasename=$(basename "${PWD}")
configPath="$HOME/.config/postmergerc/$projectBasename"
# Found an old configuration
if [ -f ".git/hooks/postmergerc" ]
then
exec < /dev/tty
while true; do
read -n 1 -p "Old configuration \".git/hooks/postmergerc\" found. Should I copy it to the new location.? [y/n]: " yn
echo;
case $yn in
[Yy]* ) mv ".git/hooks/postmergerc" "$configPath";
okfail; [ $? -gt 0 ] && exit 1
break;;
[Nn]* )
break;;
* ) echo "Please respond with [y]es or [n]o.";;
esac
done
fi
if [ ! -f "$configPath" ]
then
logWarn "\"$configPath\" not found, create a default configuration."
mkdir -p "$HOME/.config/postmergerc"
echo -e "{\n \"autogen\": \"\",\n \"configure\": \"\",\n \"make\": \"\",\n \"checkinstall\": \"\"\n}" > "$configPath"
okfail; [ $? -gt 0 ] && exit 1
else
logInfo "\"$configPath\" found"
autogenParam=$(jshon -e 'autogen' < "$configPath" | tr -d "\"" | tr -d "\\\\")
if [ "$autogenParam" != "" ]; then echog "Additional parameters for ${bold}autogen${TOA}"; echog "\t${green}$autogenParam${TOA}"; fi
configureParam=$(jshon -e 'configure' < "$configPath" | tr -d "\"" | tr -d "\\\\")
if [ "$configureParam" != "" ]; then echog "Additional parameters for ${bold}configure${TOA}"; echog "\t${green}$configureParam${TOA}"; fi
makeParam=$(jshon -e 'make' < "$configPath" | tr -d "\"" | tr -d "\\\\")
if [ "$makeParam" != "" ]; then echog "Additional parameters for ${bold}make${TOA}"; echog "\t${green}$makeParam${TOA}"; fi
checkinstallParam=$(jshon -e 'checkinstall' < "$configPath" | tr -d "\"" | tr -d "\\\\")
if [ "$checkinstallParam" != "" ]; then echog "Additional parameters for ${bold}checkinstall${TOA}"; echog "\t${green}$checkinstallParam${TOA}"; fi
echo
fi
# GIT
if [ "$isGit" == "1" ]
then
source=$(git config --get remote.origin.url)
#name=$(echo $source | gawk -F "/" '{print $5}' | sed -e 's/\.git$//')
#name=$(git remote -v | head -n1 | awk '{print $2}' | sed -e 's,.*:\(.*/\)\?,,' -e 's/\.git$//')
name=$(basename $(git config --get remote.$(git config --get branch.master.remote).url) .git)
gitowner=$(echo "$source" | gawk -F "/" '{ print ( $(NF-1) ) }' | gawk -F ":" '{ print ( $(NF) ) }')
#release=$(($(git rev-list HEAD --count)))
release=$(git log | grep -c "^commit")
responseGitHub=$(curl -s "https://api.github.com/search/repositories?q=+repo:$gitowner/$name")
responseGitHubError=$(echo "$responseGitHub" | jshon -Q -e "errors")
if [ "$responseGitHubError" == "" ]
then
isGitHub="true"
else
isGitHub="false"
fi
fi
if [ "$(command -v easy_install)" != "" ]
then
logWarn "The program \"easy_install\" from the package \"python-setuptools\" is installed. This can make problems with \"checkinstall\"."
fi
exec < /dev/tty
#while true; do
# read -n 1 -p "Show diff? [y/n]: " yn
# echo;
# case $yn in
# [Yy]* ) git diff HEAD^ HEAD;
# break;;
# [Nn]* )
# break;;
# * ) echo "Please respond with [y]es or [n]o.";;
# esac
#done
while true; do
read -n 1 -p "Compile and install $name? [y/n]: " yn
echo;
case $yn in
[Yy]* )
break;;
[Nn]* ) exit;;
* ) echo "Please respond with [y]es or [n]o.";;
esac
done
if [ -f description-pak ]
then
logWarn "Delete description-pak"
if [ -w description-pak ]
then
rm description-pak
else
sudo rm description-pak
fi
fi
if [ -f autogen.sh ]
then
logInfo "Starting autogen.sh"
./autogen.sh "$autogenParam"
okfail; [ $? -gt 0 ] && exit 1
fi
if [ -f autogen.sh ] && [ -f configure ]
then
exec < /dev/tty
while true; do
read -n 1 -p "\"autogen.sh\" and \"configure\" found. Should I also run \"configure\"? [y/n]: " yn
echo;
case $yn in
[Yy]* ) logInfo "Starting configure";
./configure "$configureParam"
okfail; [ $? -gt 0 ] && exit 1
break;;
[Nn]* )
break;;
* ) echo "Please respond with [y]es or [n]o.";;
esac
done
elif [ -f configure ]
then
logInfo "Starting configure"
./configure "$configureParam"
okfail; [ $? -gt 0 ] && exit 1
fi
if [ -f "Makefile.PL" ]
then
logInfo "Starting perl Makefile.PL"
perl Makefile.PL
okfail; [ $? -gt 0 ] && exit 1
fi
if [ -f "Makefile" ]
then
optionRule=-1
while [ "$optionRule" -ne "0" ]
do
makeRules=$(grep "^[a-zA-Z_\-]*:" Makefile | cut -d: -f1)
ruleCount=0
echog "[$ruleCount] continue with \"make\""
for rule in $makeRules
do
ruleCount=$((ruleCount+1))
if [ "$rule" == "install" ]
then
echogn "[$ruleCount] make $rule"
echog " ${yellow}(this is a bad idea)${TOA}"
else
echog "[$ruleCount] make $rule"
fi
done
logInfo "$ruleCount rules found"
echogn "Make your choice or hit return to continue with \"make\": "
read optionRule
if [ -z "$optionRule" ]
then
optionRule=0
else
selectedRule=$(echo "$makeRules" | awk NR=="$optionRule")
logInfo "Starting \"make $selectedRule\""
make "$selectedRule"
fi
done
logInfo "Starting make"
if [ "$makeParam" == "" ]
then
make
else
make "$makeParam"
fi
okfail; [ $? -gt 0 ] && exit 1
fi
version=""
maintainer=""
license=""
requires=""
summary=""
group=""
architecture=""
sourceHtmlUrl=""
if [ "$isGitHub" == "true" ]
then
sourceHtmlUrl=$(echo "$responseGitHub" | jshon -e "items" -e 0 -e "html_url")
fi
####################
# DEBIAN/CHANGELOG
####################
if [ -f "debian/changelog" ]
then
echog "Search for information via ${bold}debian/changelog${TOA}"
versionDebianChangelog=$(head -1 "debian/changelog" | gawk -F " " '{print $2}' | tr -d "()")
logVersion "$versionDebianChangelog"
if [ "$version" == "" ]; then version=$versionDebianChangelog; fi
fi
####################
# DEBIAN/CONTROL
####################
if [ -f "debian/control" ]
then
echog "Search for information via ${bold}debian/control${TOA}"
architectureDebianControl=$(grep '^ *Architecture *' "debian/control" | gawk -F ":" '{print $2}' | tr -d " ")
logArchitecture "$architectureDebianControl"
if [ "$architecture" == "" ]; then architecture=$architectureDebianControl; fi
requiresDebianControl=$(grep '^ *Depends *' "debian/control" | gawk -F ":" '{print $2}' | tr -d " ")
logRequires "$requiresDebianControl"
if [ "$requires" == "" ]; then requires=$requiresDebianControl; fi
maintainerDebianControl=$(grep '^ *Maintainer *' "debian/control" | gawk -F ":" '{print $2}' | sed -e 's/^ *//' -e 's/ *$//')
logMaintainer "$maintainerDebianControl"
if [ "$maintainer" == "" ]; then maintainer=$maintainerDebianControl; fi
groupDebianControl=$(grep '^ *Section *' "debian/control" | gawk -F ":" '{print $2}' | sed -e 's/^ *//' -e 's/ *$//')
logGroup "$groupDebianControl"
if [ "$group" == "" ]; then group=$groupDebianControl; fi
summaryDebianControl=$(grep '^ *Description *' "debian/control" | gawk -F ":" '{print $2}' | sed -e 's/^ *//' -e 's/ *$//')
logSummary "$summaryDebianControl"
if [ "$summary" == "" ]
then
summary=$summaryDebianControl
writeDescriptionPak "$summaryDebianControl"
fi
fi
####################
# MAKEFILE
####################
if [ -f "Makefile" ]
then
echog "Search for information via ${bold}Makefile${TOA}"
versionMakefile=$(grep '^ *PACKAGE_VERSION *= *' Makefile | gawk -F "=" '{print $2}' | tr -d " ")
logVersion "$versionMakefile"
if [ "$version" == "" ]; then version=$versionMakefile; fi
fi
####################
# *.DOAP
####################
if [ -f "$name.doap" ]
then
echog "Search for information via ${bold}$name.doap${TOA}"
lengthMaintainerDoap=$(xpath -q -e "count(//maintainer)" "$name.doap" 2>/dev/null)
for ((i = 1; i <= $lengthMaintainerDoap; i++)); do
if [ "$maintainerDoap" == "" ]
then
maintainerDoap="$(xpath -q -e "//maintainer[$i]/foaf:Person/foaf:name/text()" "$name.doap")"
else
maintainerDoap="$maintainerDoap, $(xpath -q -e "//maintainer[$i]/foaf:Person/foaf:name/text()" "$name.doap")"
fi
maintainerDoap="$maintainerDoap ($(xpath -q -e "string(//maintainer[$i]/foaf:Person/foaf:mbox/@rdf:resource)" "$name.doap" 2>/dev/null | sed 's/^.*mailto:\(.*\)$/\1/'))"
done
logMaintainer "$maintainerDoap"
if [ "$maintainer" == "" ]; then maintainer=$maintainerDoap; fi
summaryDoap=$(xpath -q -e "*/shortdesc/text()" "$name.doap" | tr -d '\n')
logSummary "$summaryDoap"
if [ "$summary" == "" ]
then
summary=$summaryDoap
writeDescriptionPak "$summaryDoap"
fi
fi
####################
# *.SPEC
####################
if [ -f "$name.spec" ]
then
echog "Search for information via ${bold}$name.spec${TOA}"
licenseSpec=$(grep '^ *License *' "$name.spec" | gawk -F ":" '{print $2}' | tr -d " ")
logLicense "$licenseSpec"
if [ "$license" == "" ]; then license=$licenseSpec; fi
groupSpec=$(grep '^ *Group *' "$name.spec" | gawk -F ":" '{print $2}' | tr -d " ")
logGroup "$groupSpec"
if [ "$group" == "" ]; then group=$groupSpec; fi
summarySpec=$(grep '^ *Summary *' "$name.spec" | gawk -F ":" '{print $2}' | sed -e 's/^ *//' -e 's/ *$//')
logSummary "$summarySpec"
if [ "$summary" == "" ]
then
summary=$summarySpec
writeDescriptionPak "$summarySpec"
fi
requiresSpec=$(grep '^ *Requires *' "$name.spec" | gawk -F ":" '{print $2}' | tr -d " " | tr '\n' ',' | sed -e 's/^,*//' -e 's/,*$//')
logRequires "$requiresSpec"
if [ "$requires" == "" ]; then requires=$requiresSpec; fi
fi
####################
# SETUP.PY
####################
if [ -f "setup.py" ]
then
if [ ! -x "setup.py" ]
then
echog "${red}setup.py is not executable. Aborting.${TOA}"
exit 1
else
echog "Search for information via ${bold}setup.py${TOA}"
maintainerSetupPy="$(./setup.py --author) ($(./setup.py --author-email))"
logMaintainer "$maintainerSetupPy"
if [ "$maintainer" == "" ]; then maintainer=$maintainerSetupPy; fi
versionSetupPy=$(./setup.py --version)
logVersion "$versionSetupPy"
if [ "$version" == "" ]; then version=$versionSetupPy; fi
licenseSetupPy=$(./setup.py --license)
logLicense "$licenseSetupPy"
if [ "$license" == "" ]; then license=$licenseSetupPy; fi
requiresSetupPy=$(./setup.py --requires)
logRequires "$requiresSetupPy"
if [ "$requires" == "" ]; then requires=$requiresSetupPy; fi
summarySetupPy=$(./setup.py --description)
logSummary "$summarySetupPy"
if [ "$summary" == "" ]
then
summary=$summarySetupPy
writeDescriptionPak "$summarySetupPy"
fi
fi
fi
####################
# GITHUB API
####################
if [ "$isGitHub" == "true" ]
then
echog "Search for information via ${bold}GitHub-API${TOA}"
summaryGitHubApi=$(echo "$responseGitHub" | jshon -e "items" -e 0 -e "description" | sed -e 's/^"*//' -e 's/"*$//' | tr -d "\\\\")
logSummary "$summaryGitHubApi"
if [ "$summary" == "" ]
then
summary=$summaryGitHubApi
writeDescriptionPak "$summaryGitHubApi"
fi
fi
####################
# PATH
####################
firstParts=$(echo "$projectBasename" | awk -F "-" '{ for (i=1; i<NF; i++) printf $i"-"}')
lastPart=$(echo "$projectBasename" | awk -F "-" '{ print $NF }')
if [[ ${lastPart:0:1} =~ ^[0-9] ]]
then
versionPath=$lastPart
namePath=${firstParts%?}
else
versionPath=""
namePath=$projectBasename
fi
echog "Search for information via ${bold}Path${TOA}"
logVersion "$versionPath"
if [ "$version" == "" ]; then version=$versionPath; fi
logName "$namePath"
if [ "$name" == "" ]; then name=$namePath; fi
####################
# Set standard values if nothing
####################
if [ "$version" == "" ] || [[ ${version:0:1} =~ ^[^0-9] ]]
then
version="$(date +%Y%m%d)"
fi
if [ "$sourceHtmlUrl" == "" ]
then
sourceHtmlUrl="$source"
fi
if [ "$name" == "" ]
then
name=$projectBasename
fi
if [ "$name" == "" ]
then
name=$(basename $(git config --get remote.$(git config --get branch.master.remote).url) .git)
fi
requires=$(echo "$requires" | tr ',' '\n' | sed 's/\([<<>>==].*\)/(\1)/' | sed -e $'s/((/(/g' | sed -e $'s/))/)/g')
requires=$(echo "$requires" | tr '\n' ',' | sed -e 's/^,*//' -e 's/,*$//')
if [ -f "setup.py" ]
then
echo
echog "Install with ${green}checkinstall ... python setup.py install${TOA}"
sudo checkinstall --spec foo --maintainer \""$maintainer"\" --pkglicense \""$license"\" --pkgname \""$name"\" --pkgrelease \""$release"\" --pkgversion \""$version"\" --pkgsource \""$sourceHtmlUrl"\" --pkggroup \""$group"\" --requires \""$requires"\" --pkgarch \""$architecture"\" $(if [ "$checkinstallParam" != "" ]; then echo "$checkinstallParam"; fi) python setup.py install
else
echo
echog "Install with ${green}checkinstall ...${TOA}"
sudo checkinstall --spec foo --maintainer \""$maintainer"\" --pkglicense \""$license"\" --pkgname \""$name"\" --pkgrelease \""$release"\" --pkgversion \""$version"\" --pkgsource \""$sourceHtmlUrl"\" --pkggroup \""$group"\" --requires \""$requires"\" --pkgarch \""$architecture"\" $(if [ "$checkinstallParam" != "" ]; then echo "$checkinstallParam"; fi)
fi