-- cgit v1.2.3 From 5c7f7d4c41d78c3a7ba986e65a697410ca0b219f Mon Sep 17 00:00:00 2001 From: merakor Date: Sun, 25 Apr 2021 06:02:46 +0000 Subject: pkg_repository_info: Add function that returns repository information FossilOrigin-Name: 6e5c41e40438e00decab65e1dcbb577274f06069ba2b8dd5b4d124cd6dc2880b --- src/cpt-lib.in | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/cpt-lib.in b/src/cpt-lib.in index bf58fbe..2da51bb 100644 --- a/src/cpt-lib.in +++ b/src/cpt-lib.in @@ -1643,6 +1643,49 @@ pkg_install() { log "$pkg_name" "Installed successfully" } +pkg_repository_info() { + # Finds and returns repository information for the current directory. It + # will return current directory, repository root, and the type of repository + # in a colon separated format. + + if rootdir=$(git rev-parse --show-toplevel 2>/dev/null); then + # Git repository + backend=git + + elif rootdir=$(hg root 2>/dev/null); then + # Mercurial repository + backend=hg + + elif rootdir=$(fossil info 2>/dev/null | grep local-root:); then + # Fossil repository + backend=fossil + + # We want to remove the initial spacing before the root directory. + read -r _ rootdir < Date: Sun, 25 Apr 2021 06:07:47 +0000 Subject: pkg_repository_info: make stricter grep call for fossil FossilOrigin-Name: 1139782a2f958ea86a02eb3b252c8fc8fe75786510ef73e65d9e03eb5d4a2f44 --- src/cpt-lib.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpt-lib.in b/src/cpt-lib.in index 2da51bb..64f2869 100644 --- a/src/cpt-lib.in +++ b/src/cpt-lib.in @@ -1656,7 +1656,7 @@ pkg_repository_info() { # Mercurial repository backend=hg - elif rootdir=$(fossil info 2>/dev/null | grep local-root:); then + elif rootdir=$(fossil info 2>/dev/null | grep ^local-root:); then # Fossil repository backend=fossil -- cgit v1.2.3 From fb98eac3bb4060100c174247446d72dafc075112 Mon Sep 17 00:00:00 2001 From: merakor Date: Sun, 25 Apr 2021 09:17:38 +0000 Subject: pkg_repository_info: cache repository information for later use FossilOrigin-Name: c0bbaed4949169d212ece054db5c9f278abb57f1242043bcb18409a286e3cb45 --- src/cpt-lib.in | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cpt-lib.in b/src/cpt-lib.in index 64f2869..55553e4 100644 --- a/src/cpt-lib.in +++ b/src/cpt-lib.in @@ -1648,14 +1648,18 @@ pkg_repository_info() { # will return current directory, repository root, and the type of repository # in a colon separated format. - if rootdir=$(git rev-parse --show-toplevel 2>/dev/null); then + : "${repo_file:=$cac_dir/repository-cache}" + + if information=$(grep "^$PWD:" "$repo_file" 2>/dev/null); then + # Repository information is already cached. + printf '%s\n' "$information" | sed 1q + return + elif rootdir=$(git rev-parse --show-toplevel 2>/dev/null); then # Git repository backend=git - elif rootdir=$(hg root 2>/dev/null); then # Mercurial repository backend=hg - elif rootdir=$(fossil info 2>/dev/null | grep ^local-root:); then # Fossil repository backend=fossil @@ -1665,7 +1669,6 @@ pkg_repository_info() { $rootdir EOF rootdir=${rootdir%/} - elif [ -f .rsync ]; then backend=rsync rootdir=$PWD @@ -1683,7 +1686,7 @@ EOF backend=local rootdir=$PWD fi - printf '%s:%s:%s\n' "$PWD" "$rootdir" "$backend" + printf '%s:%s:%s\n' "$PWD" "$rootdir" "$backend" | tee -a "$repo_file" } pkg_fetch() { -- cgit v1.2.3 From 97ce9d326789160e6de54140ac586fe22e1f9c83 Mon Sep 17 00:00:00 2001 From: merakor Date: Mon, 26 Apr 2021 08:18:35 +0000 Subject: pkg_repository_info: Use cut instead of heredoc for fossil FossilOrigin-Name: 7f6535ab78b05c31f751fa763ff988ace8d4c6bda99fddeb2bc7638e2c07d221 --- src/cpt-lib.in | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cpt-lib.in b/src/cpt-lib.in index 55553e4..25ac106 100644 --- a/src/cpt-lib.in +++ b/src/cpt-lib.in @@ -1664,10 +1664,9 @@ pkg_repository_info() { # Fossil repository backend=fossil - # We want to remove the initial spacing before the root directory. - read -r _ rootdir < Date: Mon, 26 Apr 2021 08:33:07 +0000 Subject: cpt-lib: add and use new backends for fetching repositories FossilOrigin-Name: 2ded60ede324d5b94db96a5267b22263281e611b1662f327c31da3c21b6acf48 --- src/cpt-lib.in | 236 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 116 insertions(+), 120 deletions(-) diff --git a/src/cpt-lib.in b/src/cpt-lib.in index 25ac106..2e8c262 100644 --- a/src/cpt-lib.in +++ b/src/cpt-lib.in @@ -1643,14 +1643,113 @@ pkg_install() { log "$pkg_name" "Installed successfully" } +pkg_repository_pull_fossil() { + # Pull function for Fossil. + [ "$(fossil remote 2>/dev/null)" != off ] || { + log "$repo" " " + printf '%s\n' "No remote, skipping." + return 0 + } + + # Ensure we have proper permissions to do the pull operation. + if [ -w "$PWD" ] && [ "$uid" != 0 ]; then + fossil update + else + pkg_repository_as_root "fossil update" + fi +} + +pkg_repository_pull_git() { + # Pull function for Git. + [ "$(git remote 2>/dev/null)" ] || { + log "$repo" " " + printf '%s\n' "No remote, skipping." + return 0 + } + + # Display a message if signing is enabled for this repository. + case $(git config merge.verifySignatures) in + true) log "$PWD" "[signed] " ;; + *) log "$PWD" " " ;; + esac + + # Ensure we have proper permissions to do the pull operation. + if [ -w "$PWD" ] && [ "$uid" != 0 ]; then + git fetch + git merge + git submodule update --remote --init -f + else + pkg_repository_as_root \ + "git fetch && git merge && git submodule update --remote --init -f" + fi +} + +pkg_repository_pull_hg() { + # Pull function for Mercurial. + [ "$(hg showconfig paths 2>/dev/null)" ] || { + log "$repo" " " + printf '%s\n' "No remote, skipping." + return 0 + } + + if [ -w "$PWD" ] && [ "$uid" != 0 ]; then + hg pull + hg update + else + pkg_repository_as_root "hg pull && hg update" + fi +} + +pkg_repository_pull_rsync() { + # Pull function for rsync repositories. The details of our rsync + # repositories are explained in the user manual. + + # Read remote repository address from the '.rsync' file. + read -r remote < .rsync + if [ -w "$PWD" ] && [ "$uid" != 0 ]; then + rsync -acvzzC --include=core --delete "$remote/" "$PWD" + else + pkg_repository_as_root "rsync -acvzzC --include=core --delete \"$remote/\" \"$PWD\"" + fi +} + +pkg_repository_pull_local() { + # Local repository. We don't do a "pull" here, we just notify the user that + # this is the case. + log "$repo" " " + printf '%s\n' "Not a remote repository, skipping." +} + +pkg_repository_as_root() ( + # Helper function for pkg_repository_pull* functions used for proper + # privilege escalation. + [ "$uid" = 0 ] || log "$PWD" "Need root to update" + + # Find out the owner of the repository and spawn the operation as the user + # below. + # + # This prevents the VCS from changing the original ownership of files and + # directories in the rare case that the repository is owned by a third user. + user=$(_stat "$PWD") + + [ "$user" = root ] || log "Dropping permissions to $user for pull" + case ${su##*/} in su) set -- "'$1'"; esac + + # Spawn a subhsell to run multiple commands as root at once. This makes + # things easier on users who aren't using persist/timestamps for auth + # caching. + as_root sh -c "$@" +) + pkg_repository_info() { # Finds and returns repository information for the current directory. It # will return current directory, repository root, and the type of repository # in a colon separated format. : "${repo_file:=$cac_dir/repository-cache}" + set -- - if information=$(grep "^$PWD:" "$repo_file" 2>/dev/null); then + if [ "$CPT_REPO_CACHE" != 0 ] && information=$(grep "^$PWD:" "$repo_file" 2>/dev/null); then # Repository information is already cached. printf '%s\n' "$information" | sed 1q return @@ -1685,7 +1784,12 @@ pkg_repository_info() { backend=local rootdir=$PWD fi - printf '%s:%s:%s\n' "$PWD" "$rootdir" "$backend" | tee -a "$repo_file" + + # We cache all these information, so that we don't have to spend much time + # looking these up the next time we are doing it. If CPT_REPO_CACHE is set + # to 0, we will not write this cache. + [ "$CPT_REPO_CACHE" = 0 ] || set -- "$repo_file" + printf '%s:%s:%s\n' "$PWD" "$rootdir" "$backend" | tee -a "$@" } pkg_fetch() { @@ -1701,125 +1805,17 @@ pkg_fetch() { # Update each repository in '$CPT_PATH'. It is assumed that # each repository is 'git' tracked. for repo; do - # Go to the root of the repository (if it exists). + # Go to the root of the repository. cd "$repo" - cd "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || - cd "$(hg root 2>/dev/null)" 2>/dev/null ||: - - if [ -d .git ]; then - - [ "$(git remote 2>/dev/null)" ] || { - log "$repo" " " - printf '%s\n' "No remote, skipping." - continue - } - - contains "$repos" "$PWD" || { - repos="$repos $PWD " - - # Display a tick if signing is enabled for this - # repository. - case $(git config merge.verifySignatures) in - true) log "$PWD" "[signed] " ;; - *) log "$PWD" " " ;; - esac - - if [ -w "$PWD" ] && [ "$uid" != 0 ]; then - git fetch - git merge - git submodule update --remote --init -f - - else - [ "$uid" = 0 ] || log "$PWD" "Need root to update" - - # Find out the owner of the repository and spawn - # git as this user below. - # - # This prevents 'git' from changing the original - # ownership of files and directories in the rare - # case that the repository is owned by a 3rd user. - ( - user=$(_stat "$PWD") - - [ "$user" = root ] || - log "Dropping permissions to $user for pull" - - git_cmd="git fetch && git merge && git submodule update --remote --init -f" - case $su in *su) git_cmd="'$git_cmd'"; esac - - # Spawn a subshell to run multiple commands as - # root at once. This makes things easier on users - # who aren't using persist/timestamps for auth - # caching. - user=$user as_root sh -c "$git_cmd" - ) - fi - } - elif [ -d .hg ]; then - - [ "$(hg showconfig paths 2>/dev/null)" ] || { - log "$repo" " " - printf '%s\n' "No remote, skipping." - continue - } - - contains "$repos $PWD" || { - repos="$repos $PWD" - - if [ -w "$PWD" ] && [ "$uid" != 0 ]; then - hg pull - hg update - else - [ "$uid" ] || log "$PWD" "Need root to update" - - # We are going to do the same operation as above, to - # find the owner of the repository. - ( - user=$(_stat "$PWD") - - [ "$user" = root ] || - log "Dropping permissions to $user for pull" - - hg_cmd="hg pull && hg update" - - case $su in *su) hg_cmd="'$hg_cmd'"; esac - user=$user as_root sh -c "$hg_cmd" - ) - fi - } - elif [ -f .rsync ]; then - # If an .rsync_root file exists, we check that the repository root - # exists. If it does, we change to that directory to do the fetch. - # This way, we allow for partial repositories while making sure that - # we can fetch the repository in a single operation. - [ -f .rsync_root ] && { - read -r rsync_root < .rsync_root - [ -f "$rsync_root/.rsync" ] && cd "$rsync_root" - } - contains "$repos" "$PWD" || { - repos="$repos $PWD" - read -r remote < .rsync - if [ -w "$PWD" ] && [ "$uid" != 0 ]; then - rsync -acvzzC --include=core --delete "$remote/" "$PWD" - else - [ "$uid" = 0 ] || log "$PWD" "Need root to update" - - # Similar to the git update, we find the owner of - # the repository and spawn rsync as that user. - ( - user=$(_stat "$PWD") - - [ "$user" = root ] || - log "Dropping permissions to $user for pull" - - user=$user as_root rsync -acvzzC --include=core --delete "$remote/" "$PWD" - ) - fi - } - else - log "$repo" " " - printf '%s\n' "Not a remote repository, skipping." - fi + repo_type=$(pkg_repository_info) + repo_root=${repo_type#$PWD:} + repo_type=${repo_type##*:} repo_root=${repo_root%:*} + contains "$repos" "$repo_root" || { + repos="$repos $repo_root " + cd "$repo_root" + + "pkg_repository_pull_$repo_type" + } done run_hook post-fetch -- cgit v1.2.3 From c4c99c6ee7d7d20067cd3d6e2ddcd8e138ca1300 Mon Sep 17 00:00:00 2001 From: merakor Date: Mon, 26 Apr 2021 08:33:44 +0000 Subject: docs: update FossilOrigin-Name: ce40806183f3218daf6aed02b69dfb9cc7300ac94999f0cedfe6fe2f06adf65f --- docs/cpt.org | 2 ++ docs/cpt.texi | 2 ++ docs/cpt.txt | 3 +++ 3 files changed, 7 insertions(+) diff --git a/docs/cpt.org b/docs/cpt.org index 3949cea..0a442d3 100644 --- a/docs/cpt.org +++ b/docs/cpt.org @@ -179,6 +179,8 @@ to provide detailed information. Set the temporary build directory name. - ~CPT_PROMPT~ :: If set to 0, =cpt= will not prompt you for anything. +- ~CPT_REPO_CACHE~ :: + If set to 0, =cpt= will not use or write repository information cache. - ~CPT_ROOT~ :: If this variable is set, =cpt= will assume the given path as the system root. - ~CPT_TEST~ :: diff --git a/docs/cpt.texi b/docs/cpt.texi index c39b393..0ff0e8d 100644 --- a/docs/cpt.texi +++ b/docs/cpt.texi @@ -293,6 +293,8 @@ If set to 1, @samp{cpt} will keep logs regardless of operation success. Set the temporary build directory name. @item @code{CPT_PROMPT} If set to 0, @samp{cpt} will not prompt you for anything. +@item @code{CPT_REPO_CACHE} +If set to 0, @samp{cpt} will not use or write repository information cache. @item @code{CPT_ROOT} If this variable is set, @samp{cpt} will assume the given path as the system root. @item @code{CPT_TEST} diff --git a/docs/cpt.txt b/docs/cpt.txt index c04a52f..8620539 100644 --- a/docs/cpt.txt +++ b/docs/cpt.txt @@ -249,6 +249,9 @@ development manual for *Carbs Packaging Tools*. For development logs see Set the temporary build directory name. `CPT_PROMPT' If set to 0, `cpt' will not prompt you for anything. + `CPT_REPO_CACHE' + If set to 0, `cpt' will not use or write repository information + cache. `CPT_ROOT' If this variable is set, `cpt' will assume the given path as the system root. -- cgit v1.2.3