Commit dd92f589 authored by The Real Fun's avatar The Real Fun
Browse files

import

parent 42f20f25
prtcheckedits - see prtcheckedits.pod
upkgmk - same as pkgmk(1) - https://crux.nu/gitweb/?p=tools/pkgutils.git;a=blob_plain;f=COPYING;hb=HEAD
other - Public Domain
DESTDIR =
PREFIX = /usr
VERSION = 1.90.1
POD_CMD := pod2man --utf8 --center=oprt --release=$(VERSION)
SRC_MAN1 := $(wildcard src/*.1.pod)
SRC_MAN8 := $(wildcard src/*.8.pod)
SRC_BIN := $(filter-out $(SRC_MAN1) $(SRC_MAN8),$(wildcard src/*))
DEST_BASE := $(DESTDIR)$(PREFIX)
DEST_BIN := $(DEST_BASE)/bin
DEST_MAN1 := $(DEST_BASE)/share/man/man1
DEST_MAN8 := $(DEST_BASE)/share/man/man8
DEST_BIN_FILES := $(addprefix $(DEST_BIN)/,$(notdir $(SRC_BIN)))
DEST_MAN1_FILES := $(addprefix $(DEST_MAN1)/,$(basename $(notdir $(SRC_MAN1))))
DEST_MAN8_FILES := $(addprefix $(DEST_MAN8)/,$(basename $(notdir $(SRC_MAN8))))
.PHONY = all install
all: $(patsubst src/%.pod,build/%,$(SRC_MAN1) $(SRC_MAN8))
install: $(DEST_BIN_FILES) $(DEST_MAN1_FILES) $(DEST_MAN8_FILES)
$(DEST_BIN)/%: src/% ; install -Dm755 $< $@
$(DEST_MAN1)/%: build/% ; install -Dm644 $< $@
$(DEST_MAN8)/%: build/% ; install -Dm644 $< $@
build/%.1: src/%.1.pod ; $(POD_CMD) --section=1 $< $@
build/%.8: src/%.8.pod ; $(POD_CMD) --section=8 $< $@
$(DEST_BIN_FILES): $(DEST_BIN)
$(DEST_MAN1_FILES): $(DEST_MAN1) build
$(DEST_MAN8_FILES): $(DEST_MAN8) build
$(DEST_BIN) $(DEST_MAN1) $(DEST_MAN8): $(DEST_BASE) build
install -d $@
$(DEST_BASE) build:
install -d $@
$(SRC_MAN1) $(SRC_MAN8): build
# oprt
\ No newline at end of file
# oprt
oprt-cleanup (1) - cleanup stuff
oprt-collections (1) - better alternative to "echo /usr/ports/*/port"
oprt-depinst (8) - better alternative to "prt-get depinst"
oprt-deporder (1) - post-processed deptree
oprt-depsearch (1) - better alternative to "grep '# Depends.*port' /usr/ports/*/Pkgfile"
oprt-deptree (1) - show dependencies tree
oprt-diff (1) - show outdated ports
oprt-dsearch (1) - better alternative to "grep '^# Description.*expr' /usr/ports/*/Pkgfile"
oprt-fsearch (1) - better alternative to "grep expr /usr/ports/*/.footprint"
oprt-info (1) - better alternative to "cat /usr/ports/*/port/Pkgfile"
oprt-info-all (1) - better alternative to "cat /usr/ports/*/port/*"
oprt-install (8) - better alternative to "pkgmk -d -i"
oprt-pkgfile-deps (1) - better alternative to "awk FS='Depends on:' '(1 < NF) {print $2}' Pkgfile"
oprt-reinstall (8) - better alternative to "pkgmk -d -f -u"
oprt-remove (8) - better alternative to "pkgrm port"
oprt-search (1) - better alternative to "echo /usr/ports/*/*expr*"
oprt-update (8) - better alternative to "prt-get sysup"
oprt-watch (8) - better alternative to "ck4up"
pp (1) - patch CRUX ports
prtcheckedits (1) - print modified files
prtchecknew (1) - print local/new files (not installed)
upkgmk (1) - micro pkgmk, the easiest way to build a port
#!/bin/bash
main() {
export FUNC_ROOT=/
export FUNC_DONT_EXPORT_CWD=1
export FUNC_BIND
local _PKGMK_DIRS=($(
. /etc/pkgmk.conf
echo $PKGMK_PACKAGE_DIR
echo $PKGMK_SOURCE_DIR
echo $PKGMK_WORK_DIR
))
add_write_access "${_PKGMK_DIRS[@]}"
export OPRT_DONT_LOG=1
add_write_access $HOME/.cache/oprt
[[ ${CCACHE_DIR+defined} && -x /usr/bin/ccache ]] \
&& add_write_access "$CACHE_DIR"
[[ ${OPRT_REVDEP+defined} ]] \
|| OPRT_REVDEP="-i libreoffice"
export OPRT_REVDEP="${OPRT_REVDEP//[^a-zA-Z0-9 -]/}"
# we need fakeroot because of ports like dcron, dbus
export OPRT_BUILD_WITH_FAKEROOT=1
# we don't care in container
export OPRT_INSTALL_WITH_FORCE=1
# we don't need rejmerge in container
export OPRT_SKIP_REJMERGE=1
func bash <(
declare -f \
ccache_reset_stats \
ccache_show_stats \
is_ccache_enabled \
copy_back_oprt_stuff \
run_oprt
echo run_oprt "$@"
)
}
add_write_access() {
# this is needed in order to avoid the copy-on-write
FUNC_BIND+=" $@"
}
ccache_reset_stats() {
is_ccache_enabled \
&& ccache --zero-stats
}
ccache_show_stats() {
is_ccache_enabled \
&& ccache --show-stats
}
is_ccache_enabled() {
[[ ${CCACHE_DIR+defined} && -x /usr/bin/ccache ]]
}
run_oprt() {
ccache_reset_stats
( set -o xtrace; oprt "$@" ) || exit 1
ccache_show_stats
true
}
main "$@"
=pod
=head1 NAME
coprt - run oprt command in container
=head1 SYNOPSIS
coprt tool ...
=head1 DESCRIPTION
B<coprt> runs any C<oprt> command in a container based on the F</> using func(1).
For example, the command C<coprt depinst port> will execute C<oprt-depinst port> in a temporary container, based on the real F</>, and the only changes done to the real F</> will be to source, package, build and .cache/oprt directories.
It is a simple way to build ports without installing them and ask for the root password.
It is somehow similar to sysupc(1) from func package.
=cut
#!/bin/bash
maybe_exec_tool() {
(( $# > 0 )) || return
bin="$BASH_SOURCE-$1"
[[ -x "$bin" ]] && exec $bin "${@:2}"
}
show_help() {
for bin in ${BASH_SOURCE}-*; do
name=${bin##*/}
whatis "$name"
done
}
maybe_exec_tool "$@"
show_help
(( $# == 0 )) || [[ $1 == help ]]
#!/bin/bash
. ${BASH_SOURCE%/*}/oprt_lib
main() {
(( $# == 0 )) \
|| (( $# == 2 )) \
|| lib_fatal_errorf '%s' "two arguments are required, or none"
remove_old_source_files "${1:-default}"
remove_old_packages "${2:-default}"
}
remove_old_source_files() {
local _SRC_DIR=$1
[[ $_SRC_DIR == default ]] && {
_SRC_DIR=$(. /etc/pkgmk.conf; echo $PKGMK_SOURCE_DIR)
[[ $_SRC_DIR == "" || $_SRC_DIR == $PWD ]] \
&& return
}
[[ $_SRC_DIR == none ]] \
&& return
echo "Remove old sources..."
declare -A _USED
local _PORT _INSTALLED
readarray -t _INSTALLED < <( pkginfo --installed | awk '{print $1}' )
for _PORT in "${_INSTALLED[@]}"; do
local _SRC _SOURCES
readarray -t _SOURCES < <( get_remote_sources "$_PORT" )
for _SRC in "${_SOURCES[@]}"; do
_USED["$_SRC"]=1
done
done
remove_unused_old_files_from_dir "$_SRC_DIR" 30
}
get_remote_sources() {
local _PORT=$1
lib_set_PORT_DIR_and_COLLECTIONS "$_PORT"
. "$_PORT_DIR/Pkgfile"
local _SRC
local _REMOTE_FILE="^(http|https|ftp|file)://.*/(.+)"
local _DUMB_FILE="^v?[0-9]"
for _SRC in "${source[@]}"; do
[[ $_SRC =~ $_REMOTE_FILE ]] || continue
local _FILE=${BASH_REMATCH[2]}
printf '%s\n' "$_FILE"
[[ $_FILE =~ $_DUMB_FILE ]] && printf '%s\n' "$_PORT-$_FILE"
done
}
remove_unused_old_files_from_dir() {
local _DIR=$1
local _DAYS=$2
local _FILE
for _FILE in $_DIR/*; do
[[ -f $_FILE ]] \
|| continue
[[ ${_USED["${_FILE##*/}"]+defined} ]] \
&& continue
is_newer_than_n_days "$_FILE" $_DAYS \
|| ( set -x; lib_run_cmd rm -- "$_FILE" )
done
}
remove_old_packages() {
local _PKG_DIR=$1
[[ $_PKG_DIR == default ]] && {
_PKG_DIR=$(. /etc/pkgmk.conf; echo $PKGMK_PACKAGE_DIR)
[[ $_PKG_DIR == "" || $_PKG_DIR == $PWD ]] \
&& return
}
[[ $_PKG_DIR == none ]] \
&& return
echo "Remove old packages..."
local _PORT _FILE
declare -A _INSTALLED
while read -r _PORT _; do
_INSTALLED["$_PORT"]=1
done < <( pkginfo --installed )
declare -A _SEEN
for _FILE in $_PKG_DIR/*\#*; do
[[ -e $_FILE ]] || continue
_PORT=${_FILE##*/}
_PORT=${_PORT%%\#*}
_SEEN["$_PORT"]=1
done
declare -A _USED
for _PORT in "${!_SEEN[@]}"; do
return_port_packages_sorted "$_PORT"
local _KEEP=()
if [[ ${_INSTALLED["$_PORT"]+defined} ]]; then
_KEEP=( ${return[@]:0:3} )
else
[[ $return[0] != "" ]] \
&& is_newer_than_an_year "$_PKG_DIR/${return[0]}" \
&& _KEEP=( ${return[0]} )
fi
for _FILE in "${_KEEP[@]}"; do
# Keeping the .sig files too
local _F
for _F in $_PKG_DIR/${_FILE}*; do
[[ -e "$_F" ]] && _USED["${_F##*/}"]=1
done
done
done
remove_unused_old_files_from_dir "$_PKG_DIR" 30
}
return_port_packages_sorted() {
return=()
local _TIME _FILE
while read -r _TIME _FILE; do
return+=( "${_FILE##*/}" )
done < <(
find "$_PKG_DIR" \
-maxdepth 1 \
-name "${_PORT}#*[.]pkg[.]tar[.][^.]*" \
-printf '%T@ %p\n' \
| sort -nr
)
}
is_newer_than_an_year() {
is_newer_than_n_days "$1" 365
}
is_newer_than_n_days() {
local _FILE=$1
local _DAYS=$2
local _NOW="$(date +%s)"
local _LIMIT=$(( $_NOW - $_DAYS * 24 * 60 * 60 ))
# Using change time (%Z) instead of modification time (%Y)
# because wget creates files with the original modification time
local _TIME="$(stat --format='%Z' "$_FILE")"
(( $_TIME > $_LIMIT ))
}
main "$@"
=pod
=head1 NAME
oprt-cleanup - cleanup sources and packages
=head1 SYNOPSIS
oprt-cleanup [src_dir pkg_dir]
Both directories can be replaced with one of the words: I<none> or I<default>.
When I<default> is used as a directory name, or is missing from the command line, the directory will be extracted from F</etc/pkgmk.conf>.
When I<none> is used as a directory name, the cleanup is skipped for that directory.
When invoked without arguments, I<default> will considered for both directories.
=head1 DESCRIPTION
B<oprt-cleanup> removes the old sources and the old packages.
The sources are considered old if its coresponding port is not installed. However, only the files older than 30 days are removed.
The packages are considered old if the port is not installed (unless this is the latest build and it is not older than an year), or is installed but the packages is not in the last 3 builds. However, only the files older than 30 days are removed.
=head1 SEE ALSO
ports(8), pkgmk(8)
=cut
#!/bin/bash
. ${BASH_SOURCE%/*}/oprt_lib
USER_COL="$OPRT_DIR/user_collections"
STATS_COL="$OPRT_DIR/stats_collections"
collections=()
show_port_collections() {
printf '%s\n' "${collections[@]}"
(( ${#collections[@]} > 0 ))
}
is_pathname_present() {
[[ -e $1 ]]
}
is_empty_file() {
[[ ! -s $1 ]]
}
is_full_pathname() {
[[ $1 == /* ]]
}
is_symlink() {
[[ -L $1 ]]
}
maybe_add_collection() {
local _COL=$1
local _PORT=$2
local _DIR="$_COL/$_PORT"
is_pathname_present "$_DIR/Pkgfile" || return
if is_symlink "$_DIR"; then
_DIR="$(readlink -f "$_DIR")"
_COL=${_DIR%/*}
else
_COL=${_COL%/}
fi
local re=" $_COL "
[[ " ${collections[@]} " =~ $re ]] && return
collections+=( "$_COL" )
[[ ${OPRT_COLLECTION_ONE+defined} ]] && exit
}
maybe_add_collections_from_file() {
local _FILE=$1
local _PORT=$2
is_pathname_present "$_FILE" || return
readarray -t <"$_FILE"
local _COL
for _COL in "${MAPFILE[@]}"; do
maybe_add_collection "$_COL" "$_PORT"
done
}
is_stats_file_up_to_date() {
local not_up_to_date=1
is_pathname_present "$STATS_COL" || return $not_up_to_date
is_empty_file "$STATS_COL" && return $not_up_to_date
local now="$(date +%s)"
local cache="$(stat --format='%Y' "$STATS_COL")"
local age=$(( $now - $cache ))
local one_day=$(( 60*60*24 ))
(( $age < $one_day ))
}
generate_collections_stats() {
declare -A _SINGLE
local _NAME
# count every collection being the only one
# having one of the installed ports
while read -r _NAME _ ; do
local _FOUND=( $PORTS_DIR/*/$_NAME/ )
[[ ${#_FOUND[@]} == 1 ]] || continue
is_pathname_present "${_FOUND[0]}" || continue
local _COL="${_FOUND[0]%/*/}"
_SINGLE["$_COL"]+="."
done < <(
pkginfo --installed
)
# select the collections having more than one unique port installed
# sorted by this number
local _COL
for _COL in "${!_SINGLE[@]}"; do
local _PORTS=${_SINGLE["$_COL"]}
(( ${#_PORTS} > 1 )) && printf '%s %d\n' "$_COL" ${#_PORTS}
done \
| sort --key=2 --numeric --reverse \
| awk '{print $1}' \
>"$STATS_COL.$$"
sync
mv "$STATS_COL.$$" "$STATS_COL"
}
main() {
local _ARG=${1:-$PWD}
local _PORT
if is_full_pathname "$_ARG"; then
local _COL=${_ARG%/*}
_PORT=${_ARG##*/}
maybe_add_collection "$_COL" "$_PORT"
else
_PORT=$_ARG
fi
maybe_add_collection "$PP_PORTS" "$_PORT"
maybe_add_collections_from_file "$USER_COL" "$_PORT"
is_stats_file_up_to_date || generate_collections_stats
maybe_add_collections_from_file "$STATS_COL" "$_PORT"
local _DIR
for _DIR in $PORTS_DIR/*/$_PORT; do
local _COL="${_DIR%/*}"
maybe_add_collection "$_COL" "$_PORT"
done
return 0
}
trap "show_port_collections" EXIT
main "$@"
=pod
=head1 NAME
oprt-collections - better alternative to C<echo /usr/ports/*/port>
=head1 SYNOPSIS
oprt-collections [port]
I<port> can be a port name, a port directory, or missing (and the current directory will be used instead).
=head1 DESCRIPTION
Why is this tool more useful than C<echo /usr/ports/*/port>?
Because it shows the collections in order of priority:
1) Personal preference regarding a specific port.
Use pp(1) or make a symlink:
mkdir $PP_PORTS
ln -s /usr/ports/collection/port $PP_PORTS/port
2) Personal preference regarding collections.
Add the collection pathnames to F<$OPRT_DIR/user_collections> file (line by line).
3) By statistics, based on the installed packages.
You probably won't need to run this tool. It is used by all the other tools.
=head1 ENVIRONMENT AND FILES
=over 4
=item B<OPRT_COLLECTION_ONE> (default: not set)
If set, it will show only the first (priority) collection.
=item B<OPRT_DIR> (default: $HOME/.cache/oprt)
The directory keeping the user settings.
=item B<OPRT_DIR/stats_collections>
A file containing the list of all the collections having unique installed ports (automaticaly regenerated if older than one day).
=item B<OPRT_DIR/user_collections>
A file containing the list with user preferred collections.
=item B<PP_PORTS> (default: $HOME/.cache/pp)
The collection with personal selections of ports. See pp(1).
=back
=head1 SEE ALSO
pp(1), ports(8), prt-get(8)
=cut
#!/bin/bash
libdir=${BASH_SOURCE%/*}
. $libdir/oprt_lib
main() {
local _ARGS=() _TO_INSTALL=() _INSTALLED=() _PORT_DIR
save_args_as_ports_dir "$@"
readarray -t _TO_INSTALL < <( $libdir/oprt-deporder "${_ARGS[@]}" )
for _PORT_DIR in "${_TO_INSTALL[@]}"; do
lib_ask_about_install_scripts "$_PORT_DIR"
done
export OPRT_DONT_ASK_SCRIPT=1
for _PORT_DIR in "${_TO_INSTALL[@]}"; do
install_port "$_PORT_DIR" || {
lib_rollback_installs "${_INSTALLED[@]}"
lib_fatal_errorf '%s' "some ports failed"
}
done