autospec/plugins/spec-create.in

1004 lines
34 KiB
Bash

#!/bin/bash
# pck-create -- plugin for @package@
# Copyright (C) 2004-2015 Davide Madrisan <davide.madrisan@gmail.com>
[ -z "$BASH" ] || [ ${BASH_VERSION:0:1} -lt 3 ] &&
{ echo $"this script requires bash version 3 or better" >&2 && exit 1; }
me=(${0##*/} "@version@" "@date@")
[ -r @libdir@/libmsgmng.lib ] ||
{ echo "$me: "$"library not found"": @libdir@/libmsgmng.lib" 1>&2
exit 1; }
. @libdir@/libmsgmng.lib
[ -r @libdir@/libnetwork.lib ] ||
{ echo "$me: "$"library not found"": @libdir@/libnetwork.lib" 1>&2
exit 1; }
. @libdir@/libnetwork.lib
# set default variables
# output verbosity
let "verbose = 1"
spec_type=standard
spec_first_release=1
spec_run_ldconfig="/sbin/ldconfig"
spec_changelog_date="$(LC_ALL="C" date "+%a %b %d %Y")"
spec_changelog_comment="package created by @package@"
spec_default_summary="..."
spec_default_group="..."
spec_default_url="..."
spec_default_license="..."
spec_default_source="..."
spec_default_description="..."
spec_default_description_devel="..."
spec_setup_macro=
spec_cmd_configure_autotools="%configure"
spec_cmd_make_autotools="%make"
spec_cmd_makeinstall_autotools="%makeinstall"
spec_cmd_configure_autogen="./autogen.sh\n%configure"
spec_cmd_make_autogen="%make"
spec_cmd_makeinstall_autogen="%makeinstall"
spec_cmd_configure_cmake="%cmake"
spec_cmd_make_cmake="%cmake_build"
spec_cmd_makeinstall_cmake="%cmake_install"
spec_cmd_configure_scons=""
spec_cmd_make_scons="scons"
spec_cmd_makeinstall_scons="scons install DESTDIR=%{buildroot}/<ADDME>"
spec_cmd_configure_makefileonly=""
spec_cmd_make_makefileonly="%make"
spec_cmd_makeinstall_makefileonly="%makeinstall"
spec_cmd_configure_default=""
spec_cmd_make_default=""
spec_cmd_makeinstall_default=""
spec_cmd_configure_meson="%meson"
spec_cmd_make_meson="%meson_build"
spec_cmd_makeinstall_meson="%meson_install"
[ "$perl_Makefile_generator" ] || perl_Makefile_generator="Makefile.PL"
preserve_dot_git=0
# load the configuration file(s)
[ -r @libdir@/libcfg.lib ] ||
{ echo "$me: "$"library not found"": @libdir@/libcfg.lib" 1>&2
exit 1; }
. @libdir@/libcfg.lib
[ -r @libdir@/libtranslate.lib ] ||
{ echo "$me: "$"library not found"": @libdir@/libtranslate.lib" 1>&2
exit 1; }
. @libdir@/libtranslate.lib
function copying() {
echo "\
"$"This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2 as published by the
Free Software Foundation. There is NO warranty; not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE."
}
function version() {
echo "\
${me[0]} ${me[1]}
Copyright (C) 2004-2013 Davide Madrisan <davide.madrisan@gmail.com>"
}
# $1: optional exit code (default is '1')
function usage() {
version
echo "\
"$"Try to create a specfile for the specified source archive"".
"$"Usage"":
@frontend@ -s <source-archive> [-n <name>] [-v <ver>] [-t <type>] \\
[-o <outfile>] [--changelog \""$"message""\"] [<"$"git-opts"">] \\
[--packager-fullname \"Full Name\" ] [--packager-email \"email@domain\" ] \\
[-C <conf_file>]
"$"where the above options mean"":
-s, --source "$"Try to create a specfile for the specified source archive""
-n, --pck-name "$"Name of the package (default: taken from <source-archive> name)""
-v, --pck-version "$"Version of the package (default: taken from <source-archive> name)""
-t, --type "$"Typology of the specfile to be created""
standard : "$"standard specfile (default)""
ghc : "$"specfile for ghc packages""
gnome : "$"specfile for gnome packages""
kde5 : "$"specfile for kde5 packages""
library : "$"specfile for common library packages""
ocaml-libs : "$"specfile for OCaml library packages""
perl : "$"specfile for single-package perl modules""
python : "$"specfile for python modules""
standard-daemon : "$"standard specfile for system/network services""
web : "$"specfile for web packages""
-o, --output "$"Redirect the output to the file <outfile>""
--changelog "$"Set change information for the package""
--packager-fullname
"$"Override packager full name""
--packager-email
"$"Override packager email""
--git-branch "$"Specify a git branch or tag and (optionally) a commit by appending @commit_id""
--preserve-dot-git "$"Do not remove git files""
--colors "$"Select the theme to be used for the colorized output""
-C, --config "$"Use an alternate user configuration file"" <conf_file>""
"$"Default files:"" $default_cfg_strlist""
"$"Default user files:"" $default_cfg_user_strlist""
"$"Operation modes"":
-h, --help "$"Print this help, then exit""
-V, --version "$"Print version number, then exit""
-q, --quiet "$"Run in quiet mode""
-D, --debug "$"Run in debugging mode (very verbose output)""
"$"Samples"":
@frontend@ -s ~/software/@package@-@version@.tar.bz2 -t standard -o @package@.spec
@frontend@ -s http://ftp.openmamba.org/devel/tools/@package@/@package@-@version@.tar.bz2
@frontend@ -s @package@-@version@.tar.bz2 --changelog \"First build\"
@frontend@ -s git://anongit.freedesktop.org/gstreamer/gst-omx \\
--git-branch=\"raspberry\" --preserve-dot-git -o gst-omx.spec
"$"Report bugs to <davide.madrisan@gmail.com>."
exit ${1:-1}
}
case $1 in
--autospec-args-file*)
if [[ "$1" =~ = ]]; then
argsfile=`echo $1 | sed 's/^--autospec-args-file=//'`
else
argsfile=$2
fi
[ -r "$argsfile" ] || notify.error $"cannot read"": \`$argsfile'"
. $argsfile && rm -f $argsfile
;;
esac
for arg in $@; do
case $arg in
-h|--help) usage 0 ;;
-V|--version) version; echo; copying; exit 0 ;;
esac
done
# the user configuration file for @package@ is required
config.check4user
exec_options=`LC_ALL=C getopt \
-o s:n:v:t:o:C:DqrhV \
--long \
source:,pck-name:,pck-version:,type:,output:,changelog:,\
packager-fullname:,packager-email:,\
git-branch:,preserve-dot-git,\
colors:,config:,debug,quiet,help,version,\
frontend_opts: \
-n "$me" -- "$@"`
[ $? = 0 ] || exit 1
notify.debug "[ ${0} ${exec_options} ]\n"
eval set -- "$exec_options"
cmdline_vars=()
while :; do
case $1 in
-s|--source)
[ "$2" = "--help" ] && usage 0
[ "$2" = "-h" ] && usage 0
pck_tarball=$2; shift
;;
-n|--pck-name)
pck_name=$2; shift ;;
-v|--pck-version)
shift; pck_version=$1 ;;
-t|--type)
spec_type=$2; shift ;;
-o|--output)
outfile=$2; shift ;;
--changelog)
spec_changelog_comment="$2"; shift ;;
--packager-fullname)
packager_fullname="$2"; shift
cmdline_vars[${#cmdline_vars[*]}]="packager_fullname=\"$packager_fullname\"" ;;
--packager-email)
packager_email="$2"; shift
cmdline_vars[${#cmdline_vars[*]}]="packager_email=\"$packager_email\"" ;;
--git-branch)
git_branch=$2; shift ;;
--preserve-dot-git)
preserve_dot_git=1 ;;
-D|--debug)
let "verbose = 2" ;;
-q|--quiet)
let "verbose = 0" ;;
--colors)
color_scheme="$2"; shift
notify.debug "color_scheme = \"$color_scheme\""
cmdline_vars[${#cmdline_vars[*]}]="color_scheme=\"$color_scheme\""
;;
-C|--config)
cfgfile_list_cmdline="$2"; shift
notify.debug "cfgfile_list_cmdline = \"$cfgfile_list_cmdline\""
cmdline_vars[${#cmdline_vars[*]}]="\
cfgfile_list_cmdline=\"$cfgfile_list_cmdline\""
;;
-h|--help)
usage 0 ;;
-V|--version)
version; echo; copying; exit 0 ;;
--) shift; break ;;
*) notify.error $"unrecognized option"" -- \`$1'" ;;
esac
shift
done
for arg in $@; do
notify.error $"unrecognized option"" -- \`$arg'"
done
cfg_load_files "$cfgfile_list_cmdline"
# otherwrite the configuration variables by set them again using
# the values defined via the commanline options
for i in ${!cmdline_vars[@]}; do
notify.debug "eval \"${cmdline_vars[i]}\""
eval "${cmdline_vars[i]}"
done
notify.enable_colors "$color_scheme"
function specfile.ckeck_defvalues() {
# $1: name of the specfile
local specfile="$1" currvalue
check_values=(
"Summary" spec_default_summary
"Group" spec_default_group
"URL" spec_default_url
"Source" spec_default_source
"License" spec_default_license
"%description" spec_default_description
"%description devel" spec_default_description_devel
)
for i in `seq 1 1 $(( ${#check_values[@]} / 2 ))`; do
id="${check_values[($i-1)*2]}"
value="${check_values[($i-1)*2+1]}"
case "$id" in
# when id begins by a '%' character, the two lines below the id must
# be taken into account (three lines: the line containing the id, the
# following one and the following (blank) line)
%*) sed -n "/^$id$/,/^$/p" $specfile | sed 3q | grep -q "${!value}"
[ $? -eq 0 ] && notify.warning $"\
remember to modify the value for \`${NOTE}$id${NORM}'" ;;
*) currvalue="\
$(sed -n "/%description/q;{/^[ \t]*$id[ \t]*:[ \t]*/{s,.*:[ \t]*,,p}}" $specfile)"
notify.debug "[[ \"$currvalue\" =~ \"${!value}\" ]]"
[[ "$currvalue" =~ "${!value}" ]] && notify.warning $"\
remember to modify the value for \`${NOTE}$id${NORM}'" ;;
esac
done
}
function template.expand() {
local OPTIONS=`LC_ALL=C getopt \
-o t:T:n:v:s:l:S:b: \
--long template:,type:,pckname:,pckversion:,setupmacro:,summary:,license:,\
source:,source-comment:,standard-docs:,standard-docs-devel:,\
build-technology:,i18n:,icons-mimetypes:,infopages:,manpages:,\
pck-devel:,pck-library:,pck-apidocs:,pck-tools:,\
shared-libraries:,debug-package:,\
-n "${0}" -- "$@"`
[ $? = 0 ] || exit 1
notify.debug "$FUNCNAME: ${OPTIONS}"
eval set -- "${OPTIONS}"
local templatefile spec_type
local pck_name pck_version
local pck_name_devel
local pck_name_tools
local pck_name_apidocs
local spec_setup_macro
local spec_summary="$spec_default_summary"
local spec_license="$spec_default_license"
local spec_source
local spec_source_comment
local standard_docs
local standard_docs_devel
local build_technology
local buildrequires_buildtool
local i18n="0"
local icons_mimetypes="0"
local infopages="0"
local manpages="0"
local pck_devel="0"
local pck_library="0"
local pck_apidocs="0"
local pck_tools="0"
local shared_libraries="0"
local debug_package="0"
while :; do
case $1 in
-t|--template)
templatefile=$2; shift ;;
-T|--type)
spec_type=$2; shift ;;
-n|--pckname)
pck_name=$2; shift ;;
-v|--pckversion)
pck_version=$2; shift ;;
-s|--setupmacro)
spec_setup_macro="$2"; shift ;;
--summary)
spec_summary="$2"; shift ;;
-l|--license)
spec_license="$2"; shift ;;
-S|--source)
spec_source="$2"; shift ;;
--source-comment)
spec_source_comment="$2"; shift ;;
--standard-docs)
standard_docs="$2"; shift ;;
--standard-docs-devel)
standard_docs_devel="$2"; shift ;;
-b|--build-technology)
build_technology="$2"; shift ;;
--i18n)
i18n="$2"; shift ;;
--icons-mimetypes)
icons_mimetypes="$2"; shift ;;
--infopages)
infopages="$2"; shift ;;
--manpages)
manpages="$2"; shift ;;
--pck-devel)
pck_devel="$2"; shift ;;
--pck-library)
pck_library="$2"; shift ;;
--pck-apidocs)
pck_apidocs="$2"; shift ;;
--pck-tools)
pck_tools="$2"; shift ;;
--shared-libraries)
shared_libraries="$2"; shift ;;
--debug-package)
debug_package="$2"; shift ;;
--) shift; break ;;
*) notify.error $"unrecognized option"" -- \`$1'" ;;
esac
shift
done
notify.debug "$FUNCNAME: build_technology = $build_technology"
local spec_cmd_configure
local spec_cmd_make
local spec_cmd_makeinstall
case "$build_technology" in
cmake)
spec_cmd_configure="$spec_cmd_configure_cmake"
spec_cmd_make="$spec_cmd_make_cmake"
spec_cmd_makeinstall="$spec_cmd_makeinstall_cmake"
buildrequires_buildtool="cmake"
;;
autotools)
spec_cmd_configure="$spec_cmd_configure_autotools"
spec_cmd_make="$spec_cmd_make_autotools"
spec_cmd_makeinstall="$spec_cmd_makeinstall_autotools"
;;
autogen)
spec_cmd_configure="$spec_cmd_configure_autogen"
spec_cmd_make="$spec_cmd_make_autogen"
spec_cmd_makeinstall="$spec_cmd_makeinstall_autogen"
;;
makefile)
spec_cmd_configure="$spec_cmd_configure_makefileonly"
spec_cmd_make="$spec_cmd_make_makefileonly"
spec_cmd_makeinstall="$spec_cmd_makeinstall_makefileonly"
;;
scons)
spec_cmd_configure="$spec_cmd_configure_scons"
spec_cmd_make="$spec_cmd_make_scons"
spec_cmd_makeinstall="$spec_cmd_makeinstall_scons"
buildrequires_buildtool="scons"
;;
meson)
spec_cmd_configure="$spec_cmd_configure_meson"
spec_cmd_make="$spec_cmd_make_meson"
spec_cmd_makeinstall="$spec_cmd_makeinstall_meson"
buildrequires_buildtool="meson"
;;
unknown)
notify.warning $"unknown build techonology"
spec_cmd_configure="$spec_cmd_configure_default"
spec_cmd_make="$spec_cmd_make_default"
spec_cmd_makeinstall="$spec_cmd_makeinstall_default"
;;
esac
notify.debug "$FUNCNAME: spec_cmd_configure = \"$spec_cmd_configure\""
notify.debug "$FUNCNAME: spec_cmd_make = \"$spec_cmd_make\""
notify.debug "$FUNCNAME: spec_cmd_makeinstall = \"$spec_cmd_makeinstall\""
notify.debug "\
$FUNCNAME: buildrequires_buildtool = \"$buildrequires_buildtool\""
[ -r "$templatefile" ] || notify.error $"file not found"": $templatefile"
local pck_name_tail="<FIXME>"
case "$pck_name" in *-*) pck_name_tail="${pck_name#*-}" ;; esac
notify.debug "$FUNCNAME: pck_name_tail = \"$pck_name_tail\""
local currvar line if_value if_level=0
# FIXME: at most two nested @if statements are supported
if_value[0]='N/A'; if_value[1]='1'; if_value[2]='1';
local template_linenum=0
while read line; do
template_linenum=$(($template_linenum + 1))
case "$line" in
@if:*)
[ $if_level -ge 2 ] && notify.error "\
$spec_type ("$"line""#$template_linenum): "$"too many nested @if blocks"
if_level=$(($if_level + 1))
currvar="$(echo "$line" | sed "s,@if:\([^ \t]*\).*,\1,")"
[[ "${!currvar}" = 1 || \
( -n "${!currvar}" && "${!currvar}" != 0 ) ]] || \
if_value[$if_level]='0'
notify.debug "\
$FUNCNAME: @if:$currvar lev:$if_level val:${if_value[$if_level]})"
continue
;;
@else:*)
[ "$if_level" = '0' ] && notify.error "\
$spec_type ("$"line""#$template_linenum): "$"@else without @if statement"
if_value[$if_level]=$(( ! ${if_value[$if_level]} ))
notify.debug "\
$FUNCNAME: @else:$currvar lev:$if_level val:${if_value[$if_level]})"
continue
;;
@fi:*)
[ "$if_level" = '0' ] && notify.error "\
$spec_type ("$"line""#$template_linenum): "$"@fi without @if statement"
if_value[$if_level]='1'
if_level=$(($if_level - 1))
notify.debug "\
$FUNCNAME: @fi:$currvar lev:$if_level val:${if_value[$if_level]})"
continue
;;
@configure@*)
[ "${if_value[1]}" = '1' -a ${if_value[2]} = '1' ] || continue
[ "$spec_cmd_configure" ] && echo "$line" | \
sed "s,@configure@,$spec_cmd_configure,"
;;
*) [ "${if_value[1]}" = '1' -a ${if_value[2]} = '1' ] &&
echo "$line" | sed "\
s,@DISTRO@,${DISTRO:-?DISTRO?},
s,@DISTRO_rpm@,${DISTRO_rpm:-?DISTRO_rpm?},
s,@VENDOR@,${VENDOR:-?VENDOR?},
s,@packager_fullname@,${packager_fullname:-?packager_fullname?},
s,@packager_email@,${packager_email:-?packager_email?},
s,@rpm_default_buildroot@,${rpm_default_buildroot:-?rpm_default_buildroot?},
s,@pck_name@,$pck_name,
s,@pck_name_tail@,$pck_name_tail,
s,@pck_version@,$pck_version,
s,@spec_first_release@,${spec_first_release:-1},
s,@spec_run_ldconfig@,$spec_run_ldconfig,
s,^\(%setup.*\),${spec_setup_macro},
/^[ \t]*Summary[ \t]*:[ \t]*\.\.\..*$/{
s,\(^[ \t]*Summary[ \t]*:[ \t]*\).*,\1${spec_summary},}
/^[ \t]*License[ \t]*:[ \t]*\.\.\.$/{
s,\(^[ \t]*License[ \t]*:[ \t]*\).*,\1${spec_license},}
s,^\([ \t]*Source[ \t]*:[ \t]*\).*,\
${spec_source_comment:+$spec_source_comment\n}\1${spec_source},
s,@make@,$spec_cmd_make,
s,@makeinstall@,$spec_cmd_makeinstall,
s,@build_tool@,$buildrequires_buildtool,
s,@standard_docs@,${standard_docs:+%doc $standard_docs},
s,@standard_docs_devel@,${standard_docs_devel:+%doc $standard_docs_devel},
s,@spec_changelog_date@,$spec_changelog_date,
s,@spec_changelog_comment@,$spec_changelog_comment,
"
#/$spec_i18n/{ # if spec_i18n
# s,@i18n@\([^@]*\)@.*,\1,;be;} #select 1st arg
#:e s,@i18n@[^@]*@\([^@]*\)[@]*,\1, #select 2nd arg
;;
esac
done < $templatefile | \
sed '/^$/{n;/^$/d}' # remove duplicate blank lines
}
# specfile.create()
# Parameters:
# $1 : try to create a specfile from this tarball
# $2 : source (with or without path; can be a remote url)
# $3 : package name
# $4 : package version
# $5 : output file
# Description:
# Create an initial specfile to help packaging activities
#
function specfile.create() {
notify.debug "[ ${0}${exec_options} ]\n"
# check if all the needed tools are available
# note: uncompress has been removed from the mandatory list
for tool in chmod find grep mktemp sed bunzip2 gunzip unzip; do
[ "$(type -p $tool)" ] ||
notify.error $"utility not found"": \`$tool'"
done
local spec_type="$1"
# collect informations from the tarball name and the source files
# 1. pck_tarball, pck_name , pck_version
# 2. pck_rootdir (where the package has been decompressed) --> pck_rootdir_4spec
# 'pck_tarball' = absolute path of '$1'
local pck_tarball
local pck_name
local pck_version="$4"
case "$2" in
git://*|http://*.git|https://*.git)
git.create_tarball \
--pck-version="$pck_version" \
--git-branch="$git_branch" \
--preserve-dot-git="$preserve_dot_git" \
--destdir="$source_dir" "$2"
spec_source="$2/${git_branch:-master}/$spec_source"
pck_tarball="$source_dir/${spec_source##*/}"
;;
http://*|https://*|ftp://*)
pck_tarball="${2##*/}"
spec_source="$2"
curl.download \
--options "$curl_options" \
${proxy:+--proxy $proxy} ${proxy_user:+--proxy-user $proxy_user} \
--exit-on-err --destdir="$source_dir" "$spec_source"
pck_tarball=$source_dir/$pck_tarball
;;
*://*)
notify.error $"unsupported protocol"": \`${2//\:*}'"
;;
/*) pck_tarball="$2" ;;
*) pck_tarball="$(pwd)/$2" ;;
esac
notify.debug "$FUNCNAME: pck_tarball = $pck_tarball"
notify.debug "$FUNCNAME: spec_source = $spec_source"
notify.debug "$FUNCNAME: spec_source_comment = $spec_source_comment"
[ "$pck_tarball" ] || notify.error $"missing tarball name"
[ -e $pck_tarball ] ||
notify.error $"cannot find the package $pck_tarball"
# get the package name from the tarball name
[ "$pck_name" ] || pck_name=${3:-`echo $pck_tarball | sed -n "\
s/.*\/// # remove directory name, if any
s/\.[^0-9].*// # remove trailing stuff (.tar.gz, ...)
/-[0-9]*/{s/-[0-9].*//p;q} # <pck_name>-<pck_ver>
/[^-\.][0-9]\./{s/\(.*[^-\.]\)[0-9]\..*/\1/p;q} # <pck_name><pck_ver>
# <pck_name> (no version, but <pck_name> can end with numbers)
/^[^0-9]*[0-9]*$/p"`}
notify.debug "pck_name = \"$pck_name\""
[ "$pck_name" ] ||
notify.error $"cannot get the package name, use the \`-n' option"
[ "$pck_version" ] || pck_version=${4:-`echo $pck_tarball | sed -n "\
/[0-9]/!q # return nothing if no number is found in the package name
s,.*/,, # remove directory name, if any
s/\.[^0-9].*// # remove trailing stuff (.tar.gz, ...)
/-[0-9]*/{s/.*-\([0-9]*.*\)/\1/p;q} # <pck_name>-<pck_ver>
/[^-\.][0-9]\./{s/.*[^-\.]\([0-9]\..*\)/\1/p;q} # <pck_name><pck_ver>
# <pck_name> (no version, but <pck_name> can end with numbers)
/^[^0-9]*[0-9]*$/q"`}
notify.debug "$FUNCNAME: pck_version = \"$pck_version\""
[ "$pck_version" ] ||
notify.error $"cannot get the package version, use the \`-v' option"
local outfile="$5"
if [ "$outfile" ]; then
notify.debug "$FUNCNAME: output file"": ${NOTE}$outfile${NORM}"
> $outfile || notify.error $"can't create output file"" $outfile"
# do not chmod a non-regular file (for instance /dev/null)
[ -f "$outfile" ] && chmod ${rpm_specfile_mode:-644} $outfile
fi
notify.note "${NOTE}"$"generating specfile""${NORM}""...""
* "$"source"": ${NOTE}$pck_tarball${NORM}""
* "$"mode"": ${NOTE}$spec_type${NORM}"
case "$spec_type" in
ghc)
[[ "$pck_name" =~ $ghc_module_name_structure ]] || notify.error $"\
ghc modules must have this name structure (use \`-n'):"" \
\`$ghc_module_name_structure'"
;;
library)
[[ "$pck_name" =~ $library_name_structure ]] || notify.error $"\
libraries must have this name structure (use \`-n'):"" \
\`$library_name_structure'"
;;
ocaml-libs)
[[ "$pck_name" =~ $ocaml_module_name_structure ]] || notify.error $"\
ocaml modules must have this name structure (use \`-n'):"" \
\`$ocaml_module_name_structure'"
;;
perl)
[[ "$pck_name" =~ $perl_module_name_structure ]] || notify.error $"\
perl modules must have this name structure (use \`-n'):"" \
\`$perl_module_name_structure'"
;;
python)
[[ "$pck_name" =~ $python_module_name_structure ]] || notify.error $"\
python modules must have this name structure (use \`-n'):"" \
\`$python_module_name_structure'"
;;
esac
# link fd#3 with stdout and redirect stdout to the log file
[ "$outfile" ] && { exec 3<&1; exec 1>>$outfile; }
local tmpdir=`mktemp -q -d -t $me.XXXXXXXX`
[ $? -eq 0 ] ||
notify.error $"can't create temporary directory"
# decompress the tarball in the 'tmpdir' directory
cp -f $pck_tarball $tmpdir
pushd $tmpdir >/dev/null
case $pck_tarball in
*.tar.gz|*.tgz)
gunzip -c $pck_tarball | tar xf - ;;
*.tar.bz2|*.tbz2)
bunzip2 -c $pck_tarball | tar xf - ;;
*.tar.Z)
[ "$(type -p uncompress)" ] ||
notify.error $"utility not found"": \`uncompress'"
uncompress -c $pck_tarball | tar xf - ;;
*.shar.gz)
gunzip -c $pck_tarball | unshar ;;
*.zip)
unzip -q $pck_tarball ;;
*.tar.xz|*.tar.lzma)
[ "$(type -p xz)" ] ||
notify.error $"utility not found"": \`xz'"
xz -d --stdout $pck_tarball | tar xf - ;;
*.tar.lz)
[ "$(type -p lzip)" ] ||
notify.error $"utility not found"": \`lzip'"
lzip -cd $pck_tarball | tar -xf - ;;
*.tar.7z)
[ "$(type -p 7za)" ] ||
notify.error $"utility not found"": \`7za'"
7za x -bd $pck_tarball >/dev/null | tar xf - ;;
*.7z)
[ "$(type -p 7za)" ] ||
notify.error $"utility not found"": \`7za'"
7za x -bd $pck_tarball >/dev/null ;;
*.jar)
[ "$(type -p jar)" ] ||
notify.error $"utility not found"": \`jar'"
jar -xf $pck_tarball >/dev/null ;;
*) notify.warning $"unsupported package compression method" ;;
esac
popd >/dev/null
rm -f $tmpdir/${pck_tarball##*/}
local pck_rootdir_dirs=(`\
LC_ALL=C find $tmpdir -mindepth 1 -maxdepth 1 -type d -printf "%f "`)
notify.debug "$FUNCNAME: pck_rootdir_dirs = \"$pck_rootdir_dirs\""
local pck_rootdir_files=(`\
LC_ALL=C find $tmpdir -mindepth 1 -maxdepth 1 -type f -printf "%f "`)
notify.debug "$FUNCNAME: pck_rootdir_files = \"$pck_rootdir_files\""
# 0. set 'spec_setup_macro'
local pck_rootdir local pck_rootdir_4spec spec_setup_macro
if [[ -n "$pck_rootdir_files" || \
( -z "$pck_rootdir_dirs" && -z "$pck_rootdir_files" ) ]]; then
# detected a package without a root directory
pck_rootdir=""
pck_rootdir_4spec="-c %{name}-%{version}"
spec_setup_macro="%setup -q $pck_rootdir_4spec"
else
pck_rootdir="$pck_rootdir_dirs"
pck_rootdir_4spec=`echo $pck_rootdir | \
sed "s/$pck_name/%{name}/;s/$pck_version/%{version}/"`
if [ "$pck_rootdir_4spec" = "%{name}-%{version}" ]; then
spec_setup_macro="%setup -q"
elif [ "$pck_rootdir_4spec" = "-c %{name}-%{version}" ]; then
spec_setup_macro="%setup -q $pck_rootdir_4spec"
else
spec_setup_macro="%setup -q -n $pck_rootdir_4spec"
fi
fi
notify.debug "$FUNCNAME: pck_rootdir = \"$pck_rootdir\""
notify.debug "$FUNCNAME: pck_rootdir_4spec = \"$pck_rootdir_4spec\""
notify.debug "$FUNCNAME: spec_setup_macro = \"$spec_setup_macro\""
# 1. preliminaries checks
case "$spec_type" in perl) ;;
*) [[ -e $tmpdir/$pck_rootdir/$perl_Makefile_generator ||
-e $tmpdir/$pck_rootdir/Build.PL ]] && notify.warning $"\
looks like a perl package (use \`-t perl' if this is true)" ;;
esac
case "$spec_type" in python) ;;
*) [[ -e $tmpdir/$pck_rootdir/setup.py ]] && notify.warning $"\
looks like a python module (use \`-t python' if this is true)" ;;
esac
# 2. set 'spec_summary'
local spec_summary="$spec_default_summary"
local perl_pckname_from_makefile=""
case "$spec_type" in
perl)
if [ -e $tmpdir/$pck_rootdir/Makefile.PL ]; then
# look for the variable `NAME' in Makefile.PL inside the
# 'WriteMakefile(' ... ')' block
perl_pckname_from_makefile=$(sed -n "\
/^[ \t]*WriteMakefile(/,/^)/{#
/^[ \t]*[']NAME['][ \t]*=>/{#
s|.*=>[ \t]*['\"]\(.*\)['\"].*|\1|;p}}" \
$tmpdir/$pck_rootdir/Makefile.PL)
# [ "$perl_pckname_from_makefile" ] ||
# perl_pckname_from_makefile=$(sed -n "\
#/name/{s,^[ \t]*name[ \t]*['\"]*\([a-zA-Z]*\)['\"]*.*,\1,p}" \
# $tmpdir/$pck_rootdir/Makefile.PL)
fi
[ -n "$perl_pckname_from_makefile" ] &&
spec_summary="$perl_pckname_from_makefile - ..."
;;
ocaml-libs)
local metafile
metafile=$(find $tmpdir/$pck_rootdir/ -type f -name "META" 2>/dev/null)
[ "$metafile" ] || metafile="$(\
find $tmpdir/$pck_rootdir/ -type f -name "META.in" 2>/dev/null)"
if [ "$metafile" ]; then
#notify.debug "$FUNCNAME: OCaml META file found"
while read line; do
if [[ "$line" =~ ^description[\ \t]*=[\ \t]*\".*\"$ ]]; then
spec_summary="... $(\
echo "$line" | sed "s|.*=[\ \t]*\"\(.*\)\"|\1|") ..." # vim highlight need a "
notify.debug "$FUNCNAME: spec_summary = \"$spec_summary\""
break
fi
#if [[ "$line" =~ ^description[\ \t]*=[\ \t]*$ ]]; then
# ... FIXME
done < $metafile
fi
;;
esac
# 3. set 'spec_license'
case "$spec_type" in perl)
spec_license="${perl_License_default:-$spec_default_license}"
esac
# find for package license info
# FIXME: currently GNU GPL, LGPL, and W3C licenses are supported
local spec_license="$spec_default_license"
if [[ -e $tmpdir/$pck_rootdir/COPYING ]]; then
[[ `grep -c "[ ]*GNU GENERAL PUBLIC LICENSE[ ]*" \
$tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="GPL"
[[ `grep -c "[ ]*GNU LIBRARY GENERAL PUBLIC LICENSE[ ]*" \
$tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="LGPL"
[[ `grep -c "[ ]*GNU LESSER GENERAL PUBLIC LICENSE[ ]*" \
$tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="LGPL"
[[ `grep -c "Copyright .* World Wide Web Consortium" \
$tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="W3C"
fi
notify.debug "$FUNCNAME: spec_license (1) = \"$spec_license\""
# 4. set 'spec_source'
local spec_preamble_tarball=`echo "${pck_tarball##*/}" |
sed "s,$pck_version,%{version},g"`
local spec_preamble_source=`echo "$spec_source" |
sed "s,$pck_version,%{version},g"`
[ "$spec_source" ] ||
spec_preamble_tarball="http://.../$spec_preamble_tarball"
notify.debug "$FUNCNAME: spec_preamble_tarball = \"$spec_preamble_tarball\""
notify.debug "$FUNCNAME: spec_preamble_source = \"$spec_preamble_source\""
# 5. discover basic documentation and set 'spec_basic_docs'
# standard text documentation files (see 'automake --help')
# + some other documentation files commonly found in several packages
local standard_docs_list='
AUTHORS
COPYING
COPYING.DOC
COPYING.LESSER
COPYING.LIB
CREDITS
LICENCE
LICENSE
MANUAL
THANKS'
local standard_docs_dirlist='
LICENSES'
local standard_docs_devel_list='
BACKLOG
BUGS
CHANGES
ChangeLog*
NEWS
README*
TODO
WHATSNEW
WHERE'
local standard_docs doc currdocs currdoc
for doc in $standard_docs_list; do
# `ls' if used to support strings like `ChangeLog*'
currdocs=$(cd $tmpdir/$pck_rootdir && ls $doc 2>/dev/null)
for currdoc in $currdocs; do
# ignore empty documentation files
[ -s $tmpdir/$pck_rootdir/$currdoc ] &&
standard_docs="\
${standard_docs:+$standard_docs }$currdoc"
done
done
for doc in $standard_docs_dirlist; do
currdocs=$(cd $tmpdir/$pck_rootdir && ls -d $doc 2>/dev/null)
for currdoc in $currdocs; do
[ -d $tmpdir/$pck_rootdir/$currdoc ] &&
standard_docs="\
${standard_docs:+$standard_docs }$currdoc"
done
done
for doc in $standard_docs_devel_list; do
currdocs=$(cd $tmpdir/$pck_rootdir && ls $doc 2>/dev/null)
for currdoc in $currdocs; do
[ -s $tmpdir/$pck_rootdir/$currdoc ] &&
standard_docs_devel="\
${standard_docs_devel:+$standard_docs_devel }$currdoc"
done
done
# split the list of docs into multiple lines if necessary
#[ "$docs" ] && docs=`echo $docs | fmt -u -w 77 | sed 's,.*,%doc &,'`
# 6. discover build technology
local build_techology="unknown"
case "$spec_type" in
perl|python)
build_techology="$spec_type"
;;
*) if [ -e $tmpdir/$pck_rootdir/meson.build ]; then
build_techology="meson"
elif [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ]; then
build_techology="cmake"
elif [ -x $tmpdir/$pck_rootdir/configure ]; then
build_techology="autotools"
elif [ -e $tmpdir/$pck_rootdir/Makefile -o \
-e $tmpdir/$pck_rootdir/makefile -o \
-e $tmpdir/$pck_rootdir/GNUmakefile ]; then
build_techology="makefile"
elif [ -x $tmpdir/$pck_rootdir/autogen.sh ]; then
build_techology="autogen"
elif [ -e $tmpdir/$pck_rootdir/SConstruct -o \
-e $tmpdir/$pck_rootdir/Sconstruct -o \
-e $tmpdir/$pck_rootdir/sconstruct ]; then
build_techology="scons"
fi
;;
esac
# 7. check for internationalization files
local spec_i18n="0"
# note: in the 'tar' tarball there is no 'intl' folder, so we use 'po'
[ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ -type d -name po 2>/dev/null)" ] &&
spec_i18n="1"
# 8. check for manpages
local spec_manpages="0"
[ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ -name Makefile.am \
-exec grep "MANS[ ]*=" {} \; 2>/dev/null)" ] && spec_manpages="1"
[ "$spec_manpages" = 0 ] &&
{ [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ \
-type f -name "*.[0-9]" 2>/dev/null)" ] && spec_manpages="1"; }
# 9. check for infopages
local spec_infopages="0"
[ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ -name Makefile.am \
-exec grep "info_TEXINFOS[ ]*=" {} \; 2>/dev/null)" ] && spec_infopages="1"
notify.debug "$FUNCNAME: spec_infopages = $spec_infopages"
[ "$spec_infopages" = 0 ] &&
{ [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ \
-type f -name "*.info" 2>/dev/null)" ] && spec_infopages="1"; }
notify.debug "$FUNCNAME: spec_infopages = $spec_infopages"
# 10. check for gtk-doc documentation
local spec_gtk_doc="0"
[ "$(LC_ALL=C $tmpdir/$pck_rootdir/configure --help 2>/dev/null | \
grep -e "enable-gtk-doc")" ] && {
spec_gtk_doc="1"
[ "$build_techology" = "autotools" ] && spec_cmd_configure="\
$spec_cmd_configure_autotools --enable-gtk-doc"
}
# 11. check for library packages
local pck_library="0"
local pck_tools="1"
case "$spec_type" in library)
[[ "$pck_name" =~ ^lib.* ]] ||
{ pck_library="1"; pck_tools="0"; }
esac
# 12. debug package
local debug_package="0"
[ -n "$rpm_macro_debug_package" ] && debug_package="1"
# FIXME: missing support for:
# pkgconfig files
# includedir files
template.expand \
--template "$templatedir/${spec_type}" \
--type "$spec_type" \
--pckname "$pck_name" \
--pckversion "$pck_version" \
--setupmacro "$spec_setup_macro" \
--summary="$spec_summary" \
--license "$spec_license" \
--source "${spec_preamble_source:-$spec_preamble_tarball}" \
--source-comment "$spec_source_comment" \
--standard-docs "$standard_docs" \
--standard-docs-devel "$standard_docs_devel" \
--build-technology "$build_techology" \
--i18n "$spec_i18n" \
--icons-mimetypes "1" \
--infopages "$spec_infopages" \
--manpages "$spec_manpages" \
--pck-apidocs "$spec_gtk_doc" \
--pck-devel "1" \
--pck-library "$pck_library" \
--pck-tools "$pck_tools" \
--shared-libraries "1" \
--debug-package "1"
[ "$outfile" ] && specfile.ckeck_defvalues "$outfile"
rm -fr $tmpdir
if [ "$outfile" ]; then
exec 1<&3 3<&- # restore stdout and close fd#3
[ -f "$outfile" ] &&
notify.note $"created specfile"": \`${NOTE}$outfile${NORM}'"
fi
}
specfile.create \
"$spec_type" "$pck_tarball" "$pck_name" "$pck_version" "$outfile"