git-barepo

Tools for sharing git bare repositories
git clone git://git.meso-star.com/git-repo.git
Log | Files | Refs | README | LICENSE

test_publish.sh (9362B)


      1 #!/bin/sh
      2 
      3 # Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com)
      4 #
      5 # This program is free software: you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as published by
      7 # the Free Software Foundation, either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
     17 
     18 set -ex
     19 
     20 die()
     21 {
     22   rm -rf "${tmpdir}" # cleanup temporary files
     23   return "${1:-1}" # return status code (default is 1)
     24 }
     25 
     26 # Configure signal processing
     27 trap 'die $?' EXIT
     28 trap 'die 1' TERM INT
     29 
     30 cookie='D3CAFBAD'
     31 name="repo"
     32 
     33 # Working directory
     34 tmpdir="$(mktemp -d "${TMPDIR:-/tmp}"/git_publish_test_XXXXXX)"
     35 repo="${tmpdir}/${name}"
     36 git="${tmpdir}/git/${name}.git"
     37 srv="${tmpdir}/srv"
     38 
     39 # Use the local git-publish
     40 export PATH="${PWD}:${PATH}"
     41 
     42 ########################################################################
     43 # Helper functions
     44 ########################################################################
     45 check_git_content() # repo-url
     46 {
     47   git clone "$1" "${tmpdir}/${name}"
     48 
     49   [ -f "${tmpdir}/${name}/README" ]
     50   [ -f "${tmpdir}/${name}/cookie.txt" ]
     51 
     52   str="$(cat "${tmpdir}/${name}/cookie.txt")"
     53   [ "${str}" = "${cookie}" ]
     54 
     55   rm -rf "${tmpdir:?}/${name}"
     56 }
     57 
     58 get_group() # file
     59 {
     60   # shellcheck disable=SC2012
     61   ls -dl "$1" | cut -d' ' -f4
     62 }
     63 
     64 get_group_perms() # file
     65 {
     66   # shellcheck disable=SC2012
     67   ls -dl "$1" | cut -d' ' -f1 | cut -c5-7
     68 }
     69 
     70 check_www_content_perm() # group, [fperm, dperm]
     71 {
     72   # Check file permissions
     73   find -L "${srv}/www/" \
     74     -path "${srv}/www/${name}/*" -o -name "index.html" \
     75   | while read -r i; do
     76     _group="$(get_group "${i}")"
     77     _perm="$(get_group_perms "${i}")"
     78 
     79     if [ -L "${i}" ]; then # Do not check symbolic links
     80       continue
     81     fi
     82 
     83     [ "${_group}" = "$1" ] || return 1
     84 
     85     if [ -z "$2" ] || [ -z "$3" ]; then
     86       # Do not check group's permissions
     87       continue
     88     fi
     89 
     90     # Check group's permissions
     91     if [ -d "${i}" ]; then
     92       [ "${_perm}" = "$3" ] || return 1 # Directory
     93     else
     94       _p="$(printf '%s\n' "${_perm}" | cut -c1,2)"
     95       [ "${_p}" = "$2" ] || return 1 # File
     96     fi
     97   done
     98 }
     99 
    100 check_www_content()
    101 {
    102   [ -f "${srv}/www/index.html" ]
    103   [ -d "${srv}/www/${name}" ]
    104   [ -f "${srv}/www/${name}/index.html" ]
    105 }
    106 
    107 ########################################################################
    108 # Setup repository
    109 ########################################################################
    110 # Create bare repository
    111 mkdir -p "${git}"
    112 git init --initial-branch=master --bare "${git}"
    113 
    114 # Create the repository content
    115 mkdir -p "${repo}"
    116 printf 'Repository to be published\n'  > "${repo}/README"
    117 printf '%s' "${cookie}" > "${repo}/cookie.txt"
    118 
    119 # Configure the directory as a git working directory, commit its
    120 # content and push it to the remote repository
    121 cd "${repo}"
    122 git init --initial-branch=master
    123 git config --local user.name "Mr Untel"
    124 git config --local user.email "mr@untel.fr"
    125 git add README cookie.txt
    126 git commit -m "Test content for publishing a repository"
    127 git remote add origin "file://${git}"
    128 git push origin master
    129 
    130 cd "${OLDPWD}"
    131 rm -rf "${repo}" # Remove temporary directory
    132 
    133 ########################################################################
    134 # Basic tests
    135 ########################################################################
    136 # Publish the repository
    137 mkdir -p "${srv}/git" "${srv}/www"
    138 git publish \
    139   -g "${srv}/git" \
    140   -w "${srv}/www" \
    141   -u "http://mr.untel.fr/" \
    142   "${git}"
    143 
    144 [ -L "${srv}/git/${name}.git" ] # The published repository is a symlink
    145 
    146 check_git_content "file://${srv}/git/${name}.git"
    147 check_git_content "file://${git}"
    148 check_www_content
    149 
    150 # Try to publish an already published repository
    151 git publish \
    152   -g "${srv}/git" \
    153   -w "${srv}/www" \
    154   -u "http://mr.untel.fr/" \
    155   "${git}"
    156 
    157 # Unpublish
    158 GIT_PUBLISH_DIR_GIT="${srv}/git" \
    159 GIT_PUBLISH_DIR_WWW="${srv}/www" \
    160 git publish -d "${git}"
    161 
    162 # Attempting to unpublish a non-published repository results in an error
    163 ! git publish -d "${git}" -g "${srv}/git" -w "${srv}/www" || die 1
    164 
    165 # The published content should be removed
    166 [ ! -e "${srv}/git/${name}.git" ]
    167 [ ! -e "${srv}/www/${name}" ]
    168 [ ! -e "${srv}/www/index.html" ] # No more index since no more repo
    169 
    170 check_git_content "file://${git}" # Original repository should be OK
    171 
    172 ########################################################################
    173 # Test the publication by moving the source repository
    174 ########################################################################
    175 export GIT_PUBLISH_DIR_GIT="${srv}/git"
    176 export GIT_PUBLISH_DIR_WWW="${srv}/www"
    177 export GIT_PUBLISH_BASE_URL="http://mr.untel.fr"
    178 
    179 # Publish the repository by moving it to the publicly accessible
    180 # directory and converting the original repository into a symbolic link
    181 # to the public repository
    182 git publish -m "${git}"
    183 
    184 # The public repository is a directory, not a symbolic link
    185 [ -d "${srv}/git/${name}.git" ] && [ ! -L "${srv}/git/${name}.git" ]
    186 
    187 # The original repository is a symbolic link to the public repository
    188 [ -L "${git}" ]
    189 
    190 check_git_content "file://${srv}/git/${name}.git"
    191 check_git_content "file://${git}"
    192 check_www_content
    193 
    194 # Republish the same repo but without the -m option.
    195 # Check that the public repo is thus a symbolic link to the original
    196 # repository
    197 git publish "${git}"
    198 [ -L "${srv}/git/${name}.git" ]
    199 [ -d "${git}" ] && [ ! -L "${git}" ]
    200 
    201 # Republish the same repo with the -m option.
    202 # Check that the original path is a symbolic link to the public
    203 # repository
    204 git publish -m "${git}"
    205 [ -d "${srv}/git/${name}.git" ] && [ ! -L "${srv}/git/${name}.git" ]
    206 [ -L "${git}" ]
    207 
    208 # Unpublish the repository
    209 git publish -d "${git}"
    210 
    211 # The published content should be removed
    212 [ ! -e "${srv}/git/${name}.git" ]
    213 [ ! -e "${srv}/www/${name}" ]
    214 [ ! -e "${srv}/www/index.html" ] # No more index since no more repo
    215 
    216 # And the original repository should be a directory, not a symbolic
    217 [ -d "${git}" ] && [ ! -L "${git}" ]
    218 
    219 check_git_content "file://${git}"
    220 
    221 ########################################################################
    222 # The repository cannot be [un]published
    223 ########################################################################
    224 # Prevent the publication of the repository
    225 touch "${git}/publication_ban"
    226 
    227 git publish "${git}"
    228 [ ! -e "${srv}/git/${name}.git" ]
    229 [ ! -e "${srv}/www/${name}" ]
    230 
    231 git publish -m "${git}"
    232 [ ! -e "${srv}/git/${name}.git" ]
    233 [ ! -e "${srv}/www/${name}" ]
    234 
    235 # Make the repository publishable
    236 rm "${git}/publication_ban"
    237 
    238 # The repository cannot be published if the public path exists and it is
    239 # not the result of an earlier publication of the reposite. It cannot
    240 # unpublised too.
    241 touch "${srv}/git/${name}.git"
    242 ! git publish    "${git}" || die 1
    243 ! git publish -d "${git}" || die 1
    244 rm "${srv}/git/${name}.git"
    245 mkdir "${srv}/git/${name}.git"
    246 ! git publish    "${git}" || die 1
    247 ! git publish -d "${git}" || die 1
    248 rmdir "${srv}/git/${name}.git"
    249 
    250 ########################################################################
    251 # Switch from the original repository to the published repository
    252 ########################################################################
    253 # Publish the repository and try to unpublish the original repository.
    254 # The original repository has been deleted! But the one that was
    255 # published should still be valid as it was considered as the original
    256 # one .
    257 git publish -g "${srv}/git/" "${git}"
    258 git publish -g "$(dirname "${git}")" -d "${srv}/git/${name}.git"
    259 [ ! -e "${git}" ]
    260 check_git_content "file://${srv}/git/${name}.git"
    261 mv "${srv}/git/${name}.git" "${git}"
    262 check_git_content "file://${git}"
    263 
    264 # Same as above but the published repository is the original one moved
    265 # to the public directory
    266 git publish -g "${srv}/git/" -m "${git}"
    267 git publish -g "$(dirname "${git}")" -d "${srv}/git/${name}.git"
    268 [ ! -e "${git}" ]
    269 check_git_content "file://${srv}/git/${name}.git"
    270 
    271 # Restore the original repository
    272 mv "${srv}/git/${name}.git" "${git}"
    273 
    274 ########################################################################
    275 # Grant write access to the WWW content
    276 ########################################################################
    277 # Find another group that is not the user's group, but to which the user
    278 # belongs. Fails if such group is not found, even though this situation
    279 # is perfectly valid from the system's perspective, because the test
    280 # cannot actually be performed.
    281 group="$(id -gn)"
    282 group="$(id -Gn | tr ' ' '\n' | grep -v "${group}" | head -n1)"
    283 [ -n "${group}" ]
    284 
    285 # Grant the group write access to the WWW content
    286 git publish -s "${group}" "${git}"
    287 check_www_content_perm "${group}" "rw" "rws"
    288 
    289 # Republishing without the -s option does not guarantee that the group's
    290 # write permissions will be preserved or that they will be reset
    291 git publish "${git}"
    292 # shellcheck disable=SC2310
    293 ! check_www_content_perm "${group}" "rw" "rws" || die 1
    294 group="$(id -gn)"
    295 # shellcheck disable=SC2310
    296 ! check_www_content_perm "${group}" || die 1
    297 
    298 # Republish with the -f option ensure that the file permissions are set
    299 # to the default values
    300 git publish -f "${git}"
    301 check_www_content_perm "${group}"
    302 
    303 die 0