portcheck 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040
  1. #!/bin/ksh
  2. #
  3. # $OpenBSD: portcheck,v 1.112 2017/05/26 20:55:09 jca Exp $
  4. # Copyright (c) 2013 Vadim Zhukov
  5. #
  6. # Permission to use, copy, modify, and distribute this software for any
  7. # purpose with or without fee is hereby granted, provided that the above
  8. # copyright notice and this permission notice appear in all copies.
  9. #
  10. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. set -e
  18. set +X
  19. set -u
  20. usage() {
  21. echo "usage: ${0##*/} [-dNP] [-p portsdir] [-x glob]" >&2
  22. echo " ${0##*/} -A [-dP] [-p portsdir] [-x glob] [subdir ...]" >&2
  23. exit 1
  24. }
  25. ############################################################
  26. # Parsing command line options
  27. #
  28. existing_port=true
  29. ignore_cvs=true
  30. plist_checks=true
  31. portsdir=
  32. rootrun=false
  33. debugging=false
  34. ignore_list=; unset ignore_list[0]
  35. while getopts "AdNPp:x:" OPT; do
  36. case $OPT in
  37. A)
  38. $existing_port || usage
  39. if ! $rootrun; then
  40. ignore_list[${#ignore_list[@]}]=.cvsignore
  41. ignore_list[${#ignore_list[@]}]=.fslckout
  42. ignore_list[${#ignore_list[@]}]=.git
  43. ignore_list[${#ignore_list[@]}]=.gitignore
  44. ignore_list[${#ignore_list[@]}]=.hg
  45. ignore_list[${#ignore_list[@]}]=.hgignore
  46. ignore_list[${#ignore_list[@]}]=.svn
  47. ignore_list[${#ignore_list[@]}]=FINISHED
  48. ignore_list[${#ignore_list[@]}]=INDEX
  49. ignore_list[${#ignore_list[@]}]=README
  50. ignore_list[${#ignore_list[@]}]=README.md
  51. ignore_list[${#ignore_list[@]}]=bulk
  52. ignore_list[${#ignore_list[@]}]=distfiles
  53. ignore_list[${#ignore_list[@]}]=infrastructure
  54. ignore_list[${#ignore_list[@]}]=lost+found
  55. ignore_list[${#ignore_list[@]}]=mystuff
  56. ignore_list[${#ignore_list[@]}]=openbsd-wip
  57. ignore_list[${#ignore_list[@]}]=packages
  58. ignore_list[${#ignore_list[@]}]=plist
  59. ignore_list[${#ignore_list[@]}]=pobj
  60. ignore_list[${#ignore_list[@]}]=tests
  61. ignore_list[${#ignore_list[@]}]=update
  62. fi
  63. rootrun=true
  64. ;;
  65. d)
  66. debugging=true
  67. ;;
  68. N)
  69. $rootrun && usage
  70. existing_port=false
  71. ignore_cvs=false
  72. ;;
  73. P)
  74. plist_checks=false
  75. ;;
  76. p)
  77. portsdir=$OPTARG
  78. ;;
  79. x)
  80. set -A ignore_list -- "${ignore_list[@]}" "$OPTARG"
  81. ;;
  82. *)
  83. usage
  84. ;;
  85. esac
  86. done
  87. if ! $rootrun && [[ -n $portsdir && ${PWD##"$portsdir"} == "$PWD" ]]; then
  88. cat >&2 <<EOE
  89. ${0##*/}: current directory does not seem to be under the
  90. specified root directory: $portsdir.
  91. EOE
  92. exit 3
  93. fi
  94. shift $(($OPTIND - 1))
  95. (($# > 0)) && ! $rootrun && usage
  96. (($# == 0)) && set -- .
  97. ############################################################
  98. # Detect path to root of directory tree of current port(s) and put it
  99. # in $portsdir, unless it was set by user above. As a last resort, we
  100. # use some heuristics based on the commonly used names.
  101. #
  102. # We also have a $pkgpath variable, that represents subdirectory under
  103. # root ports directory where the port(s) will be imported. In case we
  104. # use heuristics for determining $portsdir, we'll set up $pkgpath, too,
  105. # since we would get this info anyway.
  106. #
  107. # In make_args we write PORTSDIR_PATH override, that allows us to run
  108. # even in ports directory that is not on the PORTSDIR_PATH. This is
  109. # useful, for example, when you check your port on cvs.openbsd.org,
  110. # where you cannot just override mk.conf.
  111. #
  112. pkgpath=
  113. if [[ -z $portsdir ]]; then
  114. # idea from DPB/Vars.pm
  115. test_mf=$(cat <<EOF
  116. COMMENT = test
  117. CATEGORIES = test
  118. PKGPATH = test/a
  119. DISTNAME = test
  120. PERMIT_PACKAGE_CDROM=Yes
  121. IGNORE=Yes
  122. _MAKEFILE_INC_DONE=Yes
  123. ECHO_MSG=:
  124. .include <bsd.port.mk>
  125. SIGNING_PARAMETERS ?=
  126. EOF
  127. )
  128. IFS=:
  129. set -A portsdir_path -- \
  130. $( (echo "$test_mf" | make -C / -f - show=PORTSDIR_PATH 2>/dev/null) || true)
  131. unset IFS
  132. if ((${#portsdir_path[@]} > 0)); then
  133. for p in "${portsdir_path[@]}"; do
  134. if [[ -z $portsdir && ${PWD#"$p"} != "$PWD" ]]; then
  135. portsdir=$p
  136. elif [[ -n $portsdir && ${PWD#"$p"} != "$PWD" &&
  137. $p > $portsdir ]]; then
  138. portsdir=$p
  139. fi
  140. done
  141. fi
  142. fi
  143. if [[ -z $portsdir ]]; then
  144. # heuristics mode ON
  145. pkgpath=${PWD##*/ports/*(mystuff/|openbsd-wip/)}
  146. portsdir=${PWD%"/$pkgpath"}
  147. fi
  148. if [[ -z $portsdir ]]; then
  149. cat >&2 <<EOE
  150. ${0##*/}: could not detect root ports directory. Please provide
  151. one with -p option.
  152. EOE
  153. exit 2
  154. fi
  155. # This way we can run all checks even on cvs.openbsd.org and/or
  156. # when SKIPDIR framework is used
  157. set -A make_args -- \
  158. SKIPDIR= STARTAFTER= STARTDIR= \
  159. MASTER_SITE_OPENBSD= \
  160. PORTSDIR_PATH="$portsdir:$(cd /usr/ports && make -V PORTSDIR_PATH || true)"
  161. if $rootrun; then
  162. cd -- "$portsdir"
  163. echo "scanning ports under the $portsdir" >&2
  164. fi
  165. ############################################################
  166. # Support for SKIPDIR, STARTDIR and STARTAFTER, see ports(7)
  167. #
  168. SKIPDIR=${SKIPDIR:-}
  169. STARTDIR=${STARTDIR:-}
  170. STARTAFTER=${STARTAFTER:-}
  171. if [[ -n $STARTAFTER ]]; then
  172. STARTDIR=$STARTAFTER
  173. SKIPDIR="$SKIPDIR $STARTAFTER"
  174. fi
  175. path_parts_count() {
  176. (IFS=/; set -- $1; echo $#)
  177. }
  178. # true if directory given should be skipped based on STARTDIR
  179. # and/or SKIPDIR variable
  180. skip_dir() {
  181. $rootrun || return 1
  182. local dir=$(readlink -f "$1")
  183. dir=${dir##$portsdir*(/)}
  184. local startpartscount=$(path_parts_count "$STARTDIR")
  185. local dirpartscount=$(path_parts_count "$dir")
  186. if ((dirpartscount >= startpartscount)); then
  187. [[ -n $STARTDIR && $dir < $STARTDIR ]] && return 0
  188. fi
  189. local d
  190. for d in $SKIPDIR; do
  191. [[ $d == "$dir" ]] && return 0
  192. done
  193. return 1
  194. }
  195. ############################################################
  196. # List of well-known top-level port categories
  197. # in a form usable in pattern matching: "foo|bar|baz"
  198. #
  199. top_level_categories=$(xargs <<EOF | sed -e 's/ /|/g'
  200. archivers
  201. astro
  202. audio
  203. base
  204. benchmarks
  205. biology
  206. books
  207. cad
  208. chinese
  209. comms
  210. converters
  211. databases
  212. devel
  213. editors
  214. education
  215. emulators
  216. fonts
  217. games
  218. geo
  219. graphics
  220. inputmethods
  221. japanese
  222. java
  223. korean
  224. lang
  225. mail
  226. math
  227. meta
  228. misc
  229. multimedia
  230. net
  231. news
  232. perl5
  233. plan9
  234. print
  235. productivity
  236. security
  237. shells
  238. sysutils
  239. telephony
  240. tests
  241. textproc
  242. www
  243. x11
  244. EOF
  245. )
  246. ############################################################
  247. # List of variables that should not go into port Makefiles
  248. #
  249. user_settings=$(xargs <<EOF | sed -e 's/ /|/g'
  250. BASELOCALSTATEDIR
  251. BASESYSCONFDIR
  252. BATCH
  253. BUILD_ONCE
  254. BULK
  255. BULK_COOKIES_DIR
  256. CHECKSUM_PACKAGES
  257. CHECK_LIB_DEPENDS
  258. COPTS
  259. CXXOPTS
  260. DISTDIR
  261. ECHO_MSG
  262. ECHO_REORDER
  263. FAKEOBJDIR
  264. FETCH_CMD
  265. FETCH_PACKAGES
  266. FETCH_SYMLINK_DISTFILES
  267. FORCE_UPDATE
  268. FTP_PACKAGES
  269. IGNORE_IS_FATAL
  270. IGNORE_SILENT
  271. INTERACTIVE
  272. LIST_DB
  273. LOCKDIR
  274. LOCK_VERBOSE
  275. MASTER_SITE_BACKUP
  276. MASTER_SITE_OVERRIDE
  277. NO_CHECKSUM
  278. NO_DEPENDS
  279. NO_IGNORE
  280. PACKAGE_REPOSITORY
  281. PKG_ADD
  282. PKG_CREATE
  283. PKG_DBDIR
  284. PKG_DELETE
  285. PKG_INFO
  286. REFETCH
  287. SIGNING_PARAMETERS
  288. SUDO
  289. TEMPLATES
  290. TRY_BROKEN
  291. UNLOCK_CMD
  292. UPDATE_COOKIES_DIR
  293. USE_CCACHE
  294. VARBASE
  295. WARNINGS
  296. EOF
  297. )
  298. ############################################################
  299. # Check and fail routines
  300. #
  301. error=false
  302. err() {
  303. local prefix=
  304. while (($# > 0)); do
  305. printf "$prefix%s" "$1" >&2
  306. prefix=" "
  307. shift
  308. done
  309. echo >&2
  310. error=true
  311. }
  312. err_duplicated() {
  313. err "both $2 and some of its parents has $1"
  314. }
  315. err_coredump_found() {
  316. err "core dump file found: $1"
  317. }
  318. has_subdirs_only() {
  319. $debugging && echo "CALLED: has_subdirs_only($*)" >&2
  320. local dir=$1; shift
  321. ls -A "$dir" | {
  322. local has_files=false has_dirs=false
  323. while read F; do
  324. $ignore_cvs && [[ $F == CVS ]] && continue
  325. ignoring "$dir/$F" && continue
  326. if [[ -d $dir/$F ]]; then
  327. has_dirs=true
  328. else
  329. has_files=true
  330. fi
  331. done
  332. $has_dirs && ! $has_files
  333. }
  334. }
  335. ignoring() {
  336. ((${#ignore_list[*]} > 0)) || return 1
  337. local iglob
  338. for iglob in "${ignore_list[@]}"; do
  339. [[ ${1#./} == $iglob ]] && return 0
  340. done
  341. return 1
  342. }
  343. is_vcs_item() {
  344. [[ -d "$1" && ${1##*/} == @(CVS|.fslckout|.git|.hg|.svn) ]]
  345. }
  346. handle_extra_file() {
  347. ignoring "$1" && return 0
  348. # avoid warning, e.g., about ".*"
  349. test -e "$1" || return 0
  350. if is_vcs_item "$1"; then
  351. if ! $ignore_cvs || [[ ${1##*/} != CVS ]]; then
  352. err "VCS item detected: $1"
  353. fi
  354. elif [[ -f $1 && $1 == *.core ]]; then
  355. err_coredump_found "$1"
  356. elif [[ -d $1 ]]; then
  357. err "extra directory: $1"
  358. else
  359. err "extra file: $1"
  360. fi
  361. }
  362. # Make a path to .py[co] file looks like as if it's in the same dir
  363. # as the corresponding .py file, and has same basename. E.g.:
  364. # lib/python3.3/__pycache__/Foo/cpython-33.Bar.pyc
  365. # became:
  366. # lib/python2.7/Foo/Bar.pyc
  367. # which corresponds to:
  368. # lib/python2.7/Foo/Bar.py
  369. normalize_pyco() {
  370. local pyco=$1
  371. [[ $pyco == *.cpython-+([0-9]).py[co] ]] &&
  372. pyco=${pyco%.cpython-+([0-9]).py[co]}.${pyco##*.}
  373. [[ $pyco == */__pycache__/* ]] &&
  374. pyco=${pyco%/__pycache__/*}/${pyco##*/__pycache__/}
  375. printf "%s" "$pyco"
  376. }
  377. # Print out a ref to the particular subport/subpackage, if needed.
  378. # Port FLAVORs could also be handled, if provided.
  379. # Usage: portref directory [subpackage [flavor all_flavors]]
  380. portref() {
  381. local dir=$1; shift
  382. local subpkg= flavor all_flavors=
  383. if (($# > 0)); then
  384. subpkg=$1
  385. shift
  386. fi
  387. if (($# > 0)); then
  388. flavor=$1
  389. all_flavors=$2
  390. shift 2
  391. fi
  392. local ref=
  393. if [[ $dir != . ]]; then
  394. ref="${dir#./}"
  395. [[ -n $subpkg && $subpkg != "-" ]] && ref="$ref,$subpkg"
  396. else
  397. [[ $subpkg != "-" ]] && ref="$subpkg"
  398. fi
  399. if [[ -n $all_flavors ]]; then
  400. [[ -n $ref ]] && ref="$ref, "
  401. if [[ -z $flavor ]]; then
  402. ref="${ref}default FLAVOR"
  403. else
  404. ref="${ref}FLAVOR \"$flavor\""
  405. fi
  406. fi
  407. [[ -n $ref ]] && echo "in $ref: "
  408. }
  409. # Contains last SUBST_CMD. Filled by check_port_dir(), used
  410. # by check_port_hier() to lazily call the check_pkg_dir().
  411. last_subst_cmd=
  412. # Checks made:
  413. # * Whitelist filter of what could be in this directory.
  414. check_port_hier() {
  415. $debugging && echo "CALLED: check_port_hier($*)" >&2
  416. local distinfo_lives_upper pkg_lives_upper plist_lives_upper
  417. local dir=$1; shift
  418. for opt; do
  419. # looks unsafe but we do not pass anything except
  420. # "foo=true" and "foo=false" here
  421. eval "$opt"
  422. done
  423. distinfo_lives_upper=${distinfo_lives_upper:-false}
  424. pkg_lives_upper=${pkg_lives_upper:-false}
  425. plist_lives_upper=${plist_lives_upper:-false}
  426. local distinfo_exists=false
  427. [[ -f $dir/distinfo ]] && distinfo_exists=true
  428. $distinfo_exists && $distinfo_lives_upper &&
  429. err_duplicated distinfo "$dir"
  430. local pkg_exists=false tell_pkg_exists=$pkg_lives_upper
  431. if [[ -d $dir/pkg ]]; then
  432. pkg_exists=true
  433. tell_pkg_exists=true
  434. fi
  435. local plist_exists=false
  436. ls $dir/pkg/PLIST* >/dev/null 2>&1 && plist_exists=true
  437. $plist_lives_upper && $plist_exists &&
  438. err_duplicated "packing list(s)" "$dir"
  439. $distinfo_lives_upper && distinfo_exists=true
  440. $plist_lives_upper && plist_exists=true
  441. local recursive_args
  442. set -A recursive_args -- \
  443. distinfo_lives_upper=$distinfo_exists \
  444. pkg_lives_upper=$tell_pkg_exists \
  445. plist_lives_upper=$plist_exists
  446. local F
  447. for F in "$dir"/* "$dir"/.*; do
  448. F=${F#./}
  449. ignoring "$F" && continue
  450. if is_vcs_item "$F"; then
  451. if ! $ignore_cvs || [[ ${F##*/} != CVS ]]; then
  452. err "VCS item detected: $F"
  453. fi
  454. elif [[ -d $F ]]; then
  455. case "${F##*/}" in
  456. files|patches)
  457. check_${F##*/}_dir "$F"
  458. ;;
  459. pkg)
  460. # Do nothing, pkg_exists is already set,
  461. # and we need to read SUBST_CMD first.
  462. ;;
  463. patches?(-*))
  464. check_patches_dir "$F"
  465. ;;
  466. *)
  467. if ! ([[ -f $F/Makefile ]] ||
  468. ls $F/*.port.mk >/dev/null 2>&1) &&
  469. ! has_subdirs_only "$F"; then
  470. # Avoid extra spam
  471. err "not a port directory: $F"
  472. else
  473. local pkgpath_set=false
  474. [[ -n $pkgpath ]] && pkgpath_set=true
  475. check_port_dir "$F" "${recursive_args[@]}"
  476. $pkgpath_set || pkgpath=${pkgpath%/*}
  477. fi
  478. ;;
  479. esac
  480. else
  481. case "${F##*/}" in
  482. Makefile?(.inc)|*.port.mk)
  483. check_makefile "$F"
  484. ;;
  485. distinfo)
  486. ;;
  487. *)
  488. handle_extra_file "$F"
  489. ;;
  490. esac
  491. fi
  492. done
  493. $pkg_exists && check_pkg_dir "$dir"/pkg "$last_subst_cmd"
  494. $existing_port ||
  495. egrep -q '^ *SUBDIR[[:space:]]*\+?=' "$dir"/Makefile ||
  496. err missing subdir Makefile
  497. }
  498. # Checks made:
  499. # * Whitelist filter of what could be in this directory.
  500. check_port_dir() {
  501. $debugging && echo "CALLED: check_port_dir($*)" >&2
  502. local dir=$1; shift
  503. skip_dir "$dir" && return
  504. local distinfo_lives_upper pkg_lives_upper plist_lives_upper
  505. for opt; do
  506. # looks unsafe but we do not pass anything except
  507. # "foo=true" and "foo=false" here
  508. eval "$opt"
  509. done
  510. distinfo_lives_upper=${distinfo_lives_upper:-false}
  511. pkg_lives_upper=${pkg_lives_upper:-false}
  512. plist_lives_upper=${plist_lives_upper:-false}
  513. check_perms_in_dir "$dir"
  514. if [[ -f $dir/Makefile.inc ]] ||
  515. egrep -sq '^ *SUBDIR[[:space:]]*\+?=' "$dir"/Makefile ||
  516. has_subdirs_only "$dir"; then
  517. check_port_hier "${dir#./}" "${@:-}"
  518. return
  519. fi
  520. local F
  521. local distinfo_exists=false
  522. local mk_exists=false
  523. local pkg_exists=false
  524. local plist_exists=false
  525. local portmk_exists=true
  526. local non_portmk=0
  527. for F in "$dir"/* "$dir"/.*; do
  528. F=${F#./}
  529. ignoring "$F" && continue
  530. case ${F##*/} in
  531. Makefile)
  532. test -f "$F" || err "$F is not a file"
  533. check_makefile "$F"
  534. mk_exists=true
  535. ((++non_portmk))
  536. ;;
  537. distinfo)
  538. $distinfo_lives_upper && err_duplicated distinfo "$dir"
  539. distinfo_exists=true
  540. test -f "$F" || err "$F is not a file"
  541. ((++non_portmk))
  542. ;;
  543. *.port.mk)
  544. test -f "$F" || err "$F is not a file"
  545. check_makefile "$F"
  546. portmk_exists=true
  547. ;;
  548. files|patches)
  549. if [[ -d $F ]]; then
  550. check_${F##*/}_dir "$F"
  551. else
  552. err "$F" is not a directory
  553. fi
  554. ((++non_portmk))
  555. ;;
  556. pkg)
  557. if [[ -d $F ]]; then
  558. pkg_exists=true
  559. # Actual check to be done later, we need to gather
  560. # additional info through "make show=" call.
  561. ls "$F"/PLIST* >/dev/null 2>&1 &&
  562. plist_exists=true
  563. $plist_lives_upper && $plist_exists &&
  564. err_duplicated "packing list(s)" "$dir"
  565. else
  566. err "$F" is not a directory
  567. fi
  568. ((++non_portmk))
  569. ;;
  570. *)
  571. handle_extra_file "$F"
  572. ;;
  573. esac
  574. done
  575. # examples: lang/clang, www/mozilla
  576. $portmk_exists && ((non_portmk == 0)) && return
  577. $mk_exists || err no Makefile in "$dir"
  578. $pkg_exists || $pkg_lives_upper || err "no pkg/ in $dir"
  579. $distinfo_lives_upper && distinfo_exists=true
  580. $distinfo_exists || $existing_port || err "no distinfo in $dir"
  581. # Now gather and check some info via "make show=...".
  582. # We request all info at once for speed.
  583. local categories dist_subdir distfiles flavor flavors
  584. local gh_commit master_sites
  585. local multi_packages pkgpath_this pseudo_flavor pseudo_flavors
  586. local shared_libs subst_cmd
  587. local perm_pkg_cdrom perm_pkg_ftp perm_dist_ftp
  588. local show_items="CATEGORIES DIST_SUBDIR DISTFILES FLAVOR FLAVORS GH_COMMIT"
  589. local show_items="$show_items MASTER_SITES MULTI_PACKAGES PKGPATH"
  590. local show_items="$show_items PSEUDO_FLAVOR PSEUDO_FLAVORS"
  591. local show_items="$show_items SHARED_LIBS SUBST_CMD"
  592. local show_items="$show_items PERMIT_PACKAGE_CDROM PERMIT_PACKAGE_FTP"
  593. local show_items="$show_items PERMIT_DISTFILES_FTP"
  594. local read_ok=false
  595. local read_failed=false
  596. (cd -- "$dir"; make "${make_args[@]}" show="$show_items" || true) </dev/null |&
  597. read -pr categories &&
  598. read -pr dist_subdir &&
  599. read -pr distfiles &&
  600. read -pr flavor &&
  601. read -pr flavors &&
  602. read -pr gh_commit &&
  603. read -pr master_sites &&
  604. read -pr multi_packages &&
  605. read -pr pkgpath_this &&
  606. read -pr pseudo_flavor &&
  607. read -pr pseudo_flavors &&
  608. read -pr shared_libs &&
  609. read -pr subst_cmd &&
  610. read -pr perm_pkg_cdrom &&
  611. read -pr perm_pkg_ftp &&
  612. read -pr perm_dist_ftp &&
  613. read_ok=true
  614. if $read_ok; then
  615. exec 3<&p
  616. exec 3<&-
  617. wait
  618. else
  619. error=true
  620. return
  621. fi
  622. pseudo_flavor=$(echo "$pseudo_flavor" | sed -e 's/,/ /g')
  623. pseudo_flavor=${pseudo_flavor##" "}
  624. local f pf found
  625. local check_flavors=
  626. [[ $flavor != "$pseudo_flavor" ]] && unset check_flavors[0]
  627. for f in $flavors; do
  628. for pf in $pseudo_flavors; do
  629. [[ $f == "$pf" ]] && continue 2
  630. done
  631. [[ $f == debug ]] && continue # XXX
  632. check_flavors[${#check_flavors[@]}]=$f
  633. done
  634. check_categories "$dir" $categories
  635. check_distfiles "$dir" "$dist_subdir" $distfiles
  636. check_master_sites "$dir" $master_sites
  637. check_permit_dist "$dir" "$perm_pkg_cdrom" "$perm_pkg_ftp" \
  638. "$perm_dist_ftp"
  639. $pkg_exists && check_pkg_dir "$dir"/pkg "$subst_cmd"
  640. $existing_port || check_shlibs_versions "$dir" $shared_libs
  641. if [[ -n $gh_commit ]]; then
  642. local ghclen=$(echo -n "$gh_commit" | wc -c)
  643. if ((ghclen != 40)); then
  644. err "GH_COMMIT should be in full form (40 characters)"
  645. fi
  646. fi
  647. for _s in $multi_packages; do
  648. sub_checks "$dir" "$_s" "${check_flavors[@]}"
  649. done
  650. pkgpath=${pkgpath:-"$pkgpath_this"}
  651. last_subst_cmd="$subst_cmd"
  652. }
  653. # Checks made: obvious
  654. check_trailing_whitespace() {
  655. egrep -q '[[:space:]]+$' "$1" &&
  656. err "trailing whitespace in $1"
  657. }
  658. # Checks made: obvious
  659. check_newline_at_eof() {
  660. (( $(tail -1 -- "$1" | wc -l) == 0)) &&
  661. err "no newline at EOF in $1"
  662. }
  663. # Checks made:
  664. # * Every library in SHARED_LIBS has 0.0 version.
  665. check_shlibs_versions() {
  666. $debugging && echo "CALLED: check_shlibs_versions($*)" >&2
  667. local dir=$1; shift
  668. local lib
  669. local libver
  670. local portref=$(portref "$dir")
  671. while (($# > 1)); do
  672. lib=$1
  673. libver=$2
  674. if [[ $libver != 0.0 ]]; then
  675. err "${portref}the $lib shared library has" \
  676. "version $libver instead of 0.0"
  677. fi
  678. shift 2
  679. done
  680. }
  681. # Checks made:
  682. # * All top-level category names are well-known.
  683. check_categories() {
  684. $debugging && echo "CALLED: check_categories($*)" >&2
  685. local dir=$1; shift
  686. local portref=$(portref "$dir")
  687. for c in "$@"; do
  688. c=${c%%/*}
  689. if ! echo "$c" | egrep -q "^($top_level_categories)\$"; then
  690. err "${portref}non-standard top-level category: $c"
  691. fi
  692. done
  693. }
  694. # Checks made:
  695. # * Distfiles with useless names go into DIST_SUBDIR or have {url} suffix.
  696. check_distfiles() {
  697. $debugging && echo "CALLED: check_distfiles($*)" >&2
  698. local dir=$1; shift
  699. local dist_subdir=$1; shift
  700. local portref=$(portref "$dir")
  701. # do not care about absent distfiles, this is fine for meta ports
  702. while (($# > 1)); do
  703. # try to catch "version-only" names, but not anything more
  704. if [[ $1 == ?(v)?(.)+([0-9])?(.+([0-9]))*(.+([a-z])) &&
  705. -z $dist_subdir && $1 != *\{*\} ]]; then
  706. err "${portref}badly named distfile $1 without" \
  707. "DIST_SUBDIR or {url} postfix"
  708. fi
  709. shift
  710. done
  711. }
  712. # Checks made:
  713. # * No unreliable (without fixed distfiles) hosting listed in MASTER_SITES.
  714. check_master_sites() {
  715. $debugging && echo "CALLED: check_master_sites($*)" >&2
  716. local dir=$1; shift
  717. local portref=$(portref "$dir")
  718. local name
  719. while (($# > 1)); do
  720. case "$1" in
  721. http?(s)://bitbucket.com/*) name=BitBucket;;
  722. http?(s)://gitorious.com/*) name=Gitorious;;
  723. *) name=;;
  724. esac
  725. [[ -n $name ]] && err "$portref$name does not hold real" \
  726. "releases, please host the distfiles somewhere" \
  727. "else or ask someone to do this for you"
  728. shift
  729. done
  730. }
  731. # Run checks that are FLAVOR/SUBPACKAGE-dependent.
  732. sub_checks() {
  733. $debugging && echo "CALLED: sub_checks($*)" >&2
  734. local dir=$1; shift
  735. local subpkg=$1; shift
  736. local flavor
  737. for flavor in "$@"; do
  738. # avoid extra noise
  739. [[ ${flavor#no_} != ${flavor} &&
  740. ${subpkg#-} == ${flavor#no_} ]] &&
  741. continue
  742. (
  743. cd -- "$dir"
  744. portref=$(portref "$dir" "$subpkg" "$flavor" "$*")
  745. export SUBPACKAGE="$subpkg" FLAVOR="$flavor"
  746. local wantlib_var=WANTLIB${subpkg%-}
  747. local vars="COMMENT$subpkg FULLPKGNAME$subpkg"
  748. vars="$vars MODULES"
  749. vars="$vars PKG_ARCH$subpkg $wantlib_var WANTLIB-"
  750. vars="$vars PERMIT_PACKAGE_CDROM${subpkg%-}"
  751. vars="$vars PERMIT_PACKAGE_FTP${subpkg%-}"
  752. make "${make_args[@]}" show="$vars" | {
  753. local comment fullpkgname modules pkg_arch
  754. local wantlib perm_pkg_cdrom perm_pkg_ftp
  755. read -r comment
  756. read -r fullpkgname
  757. read -r modules
  758. read -r pkg_arch
  759. read -r wantlib
  760. read -r wantlib_ss
  761. read -r perm_pkg_cdrom
  762. read -r perm_pkg_ftp
  763. if [[ $comment == @(a|an|the)" "* ]]; then
  764. err "${portref}no leading articles in" \
  765. "COMMENT${subpkg%-}, please"
  766. fi
  767. if [[ $pkg_arch == "*" && -n $wantlib ]]; then
  768. if [[ $subpkg != - || -n $wantlib_ss ]]; then
  769. err "${portref}non-empty $wantlib_var for" \
  770. "arch-independent package"
  771. fi
  772. fi
  773. check_wantlib "$portref" "$modules" $wantlib
  774. check_permit_subpkg "$portref" "$subpkg" \
  775. "$perm_pkg_cdrom" "$perm_pkg_ftp"
  776. if $plist_checks; then
  777. (make "${make_args[@]}" \
  778. print-plist-with-depends || true) \
  779. </dev/null |&
  780. check_plist "$portref" "$fullpkgname" \
  781. "$flavor" "${subpkg%-}" "$modules"
  782. check_lib_depends "$portref" "$subpkg" \
  783. "$modules" "$wantlib"
  784. wait
  785. fi
  786. ! $error
  787. } || error=true
  788. ! $error
  789. ) || error=true
  790. done
  791. wait
  792. }
  793. # Checks made:
  794. # * If package installs system-wide icons, it should have the
  795. # x11/gtk+3,-guic dependency and @exec/@unexec-delete with
  796. # %D/bin/gtk-update-icon-cache -q -t %D/share/icons/$theme
  797. # for each icon theme used in package. If there is an
  798. # index.theme provided, then, instead of gtk-update-icon-cache,
  799. # @unexec-delete should contain the following command:
  800. # rm -f %D/share/icons/$theme/icon-theme.cache
  801. #
  802. # * If package adds a MIME type handler, it should have the
  803. # devel/desktop-file-utils dependency and @exec/@unexec-delete with
  804. # %D/bin/update-desktop-database . Unfortunately, it's hard to tell
  805. # if there is a MIME type handler in .desktop file, so we just
  806. # trigger if any .desktop files are added to
  807. # ${PREFIX}/share/applications/ .
  808. #
  809. # * If package adds a MIME types package, it should have the
  810. # misc/shared-mime-info dependency and @exec/@unexec-delete with
  811. # %D/bin/update-mime-database %D/share/mime
  812. #
  813. # * If package adds a GLib schema, it should have @exec/@unexec-delete
  814. # with %D/bin/glib-compile-schemas %D/share/glib-2.0/schemas >/dev/null
  815. # and "devel/dconf" in MODULES (or at least RDEP on devel/dconf).
  816. #
  817. # * If package installs .mo files under ${PREFIX}/share/locale/, then
  818. # run-time dependency on devel/gettext should exists.
  819. #
  820. # * If package installs files under ${PREFIX}/share/dbus-1/system-services/,
  821. # it must have a run-time dependency on x11/dbus,-suid.
  822. #
  823. # * Each .py should have corresponding .pyc files, to avoid
  824. # generation of the latter at run-time.
  825. #
  826. # * Manual (man and info) pages should go under ${PREFIX}/{man,info},
  827. # not under ${PREFIx}/share/{man,info}.
  828. #
  829. # * Manual pages shouldn't be compressed.
  830. check_plist() {
  831. $debugging && echo "CALLED: check_plist($*)" >&2
  832. local portref=$1; shift
  833. local fullpkgname=$1; shift
  834. local flavor_list=$1; shift
  835. local subpkg=$1; shift
  836. local modules_list=$1; shift
  837. local flavor is_static=false
  838. for flavor in $flavor_list; do
  839. [[ $flavor == static ]] && is_static=true
  840. done
  841. local guic_dep=false
  842. local guic_dep_needed=false
  843. local guic_exec_cnt=0
  844. local guic_unexec_cnt=0
  845. local mime_dep=false
  846. local mime_dep_needed=false
  847. local mime_exec_cnt=0
  848. local mime_unexec_cnt=0
  849. local mimepkg_dep=false
  850. local mimepkg_dep_needed=false
  851. local mimepkg_exec_cnt=0
  852. local mimepkg_unexec_cnt=0
  853. local dconf_module
  854. if [[ $modules_list == ?(* )devel/dconf?( *) ]]; then
  855. dconf_module=true
  856. else
  857. dconf_module=false
  858. fi
  859. local dconf_dep=false
  860. local dconf_dep_needed=false
  861. local dconf_exec_cnt=0
  862. local dconf_unexec_cnt=0
  863. # Lists of icon themes discovered through reading
  864. # @file, @exec and @unexec lines, accordingly.
  865. local icon_themes= exec_icon_themes= unexec_icon_themes=
  866. # List of icon themes that remove cache file
  867. local rm_cache_themes=
  868. local gettext_dep=false
  869. local translation_found=false
  870. local dbus_suid_dep=false
  871. local dbus_suid_dep_needed=false
  872. # Lists of .py, .pyc and .pyo items found, accordingly
  873. local py_files= pyc_files= pyo_files=
  874. unset py_files[0] pyc_files[0] pyo_files[0]
  875. local wrong_man=false wrong_info=false
  876. local regsh=false unregsh=false
  877. local regsh_exec=false unregsh_exec=false
  878. # Temporary ones
  879. local app l theme varname py
  880. while read -pr l; do
  881. case "$l" in
  882. "@comment "*)
  883. # ignore
  884. ;;
  885. share/icons/*/*/*|share/icons/*/@(index.theme|iconrc?(-png)))
  886. # Themes have at least two levels in depth.
  887. #
  888. # We match directories by purpose, this helps to catch
  889. # update-plist fuckups, when directories go into one
  890. # package and actual icons go in another.
  891. guic_dep_needed=true
  892. theme=${l#share/icons/}
  893. theme=${theme%%/*}
  894. # wrap with the '/' characters to avoid erroneous matching
  895. echo "$icon_themes" | fgrep -q "/$theme/" ||
  896. icon_themes="$icon_themes /$theme/"
  897. if [[ "$l" = "share/icons/$theme/index.theme" ]]; then
  898. echo "$rm_cache_themes" | fgrep -q "/$theme/" ||
  899. err "${portref}missing @unexec-delete rm -f" \
  900. "%D/share/icons/$theme/icon-theme.cache"
  901. fi
  902. ;;
  903. share/icons/*(*/))
  904. # Do not match intermediate directories to avoid false
  905. # positives.
  906. ;;
  907. share/icons/*.xpm)
  908. app=${l#share/icons/}
  909. app=${app%%/*}
  910. app=${app%%.*}
  911. err "${portref}installs icon ${l##*/} in ${l%/*}, it" \
  912. "should likely go in share/pixmaps/ instead"
  913. ;;
  914. share/icons/default.*)
  915. ;;
  916. share/icons/*)
  917. app=${l#share/icons/}
  918. app=${app%%/*}
  919. app=${app%%.*}
  920. err "${portref}installs icon ${l##*/} in ${l%/*}, it" \
  921. "should go in share/$app/icons/ or like instead"
  922. ;;
  923. "@depend x11/gtk+3,-guic"*)
  924. guic_dep=true
  925. ;;
  926. "@exec %D/bin/gtk-update-icon-cache -q -t %D/share/icons/"*)
  927. theme=${l##*/}
  928. varname=$(echo "$theme" | sed -e 's/[^a-zA-Z_]/_/g')
  929. ((++guic_exec_cnt))
  930. eval "((++guic_exec_cnt_$varname))"
  931. exec_icon_themes="$exec_icon_themes /$theme/"
  932. ;;
  933. "@unexec-delete %D/bin/gtk-update-icon-cache -q -t %D/share/icons/"*)
  934. theme=${l##*/}
  935. varname=$(echo "$theme" | sed -e 's/[^a-zA-Z_]/_/g')
  936. ((++guic_unexec_cnt))
  937. eval "((++guic_unexec_cnt_$varname))"
  938. unexec_icon_themes="$unexec_icon_themes /$theme/"
  939. ;;
  940. "@unexec-delete rm -f "%D/share/icons/*/icon-theme.cache)
  941. # as an alternative, port could zap the theme entirely
  942. theme=${l#*/icons/}
  943. theme=${theme%/icon-theme.cache}
  944. varname=$(echo "$theme" | sed -e 's/[^a-zA-Z_]/_/g')
  945. ((++guic_unexec_cnt))
  946. eval "((++guic_unexec_cnt_$varname))"
  947. unexec_icon_themes="$unexec_icon_themes /$theme/"
  948. rm_cache_themes="$rm_cache_themes /$theme/"
  949. if echo "$icon_themes" | fgrep -q "/$theme/"; then
  950. err "${portref}the @unexec-delete line removing" \
  951. "%D/share/icons/$theme/icon-theme.cache" \
  952. "does not preceed all of the icon theme" \
  953. "$theme files"
  954. fi
  955. ;;
  956. @?(un)exec?(-delete|-update)" %D/bin/gtk-update-icon-cache"*)
  957. err "${portref}incorrect gtk-update-icon-cache" \
  958. "invocation: ${l#@* }"
  959. ;;
  960. share/applications/*(*/)*.desktop)
  961. mime_dep_needed=true
  962. ;;
  963. "@depend devel/desktop-file-utils"*)
  964. mime_dep=true
  965. ;;
  966. "@exec %D/bin/update-desktop-database")
  967. ((++mime_exec_cnt))
  968. ;;
  969. "@unexec-delete %D/bin/update-desktop-database")
  970. ((++mime_unexec_cnt))
  971. ;;
  972. @?(un)exec?(-delete|-update)" %D/bin/update-desktop-database"*)
  973. err "${portref}incorrect update-desktop-database" \
  974. "invocation: ${l#@* }"
  975. ;;
  976. share/mime/packages/*.xml)
  977. mimepkg_dep_needed=true
  978. ;;
  979. "@depend misc/shared-mime-info"*)
  980. mimepkg_dep=true
  981. ;;
  982. "@exec %D/bin/update-mime-database %D/share/mime")
  983. ((++mimepkg_exec_cnt))
  984. ;;
  985. "@unexec-delete %D/bin/update-mime-database %D/share/mime")
  986. ((++mimepkg_unexec_cnt))
  987. ;;
  988. @?(un)exec?(-delete|-update)" %D/bin/update-mime-database"*)
  989. err "${portref}incorrect update-mime-database" \
  990. "invocation: ${l#@* }"
  991. ;;
  992. share/glib-2.0/schemas/*.xml)
  993. dconf_dep_needed=true
  994. ;;
  995. "@depend devel/dconf"*)
  996. dconf_dep=true
  997. ;;
  998. "@exec %D/bin/glib-compile-schemas %D/share/glib-2.0/schemas >/dev/null")
  999. ((++dconf_exec_cnt))
  1000. ;;
  1001. "@unexec-delete %D/bin/glib-compile-schemas %D/share/glib-2.0/schemas >/dev/null")
  1002. ((++dconf_unexec_cnt))
  1003. ;;
  1004. @?(un)exec?(-delete|-update)" %D/bin/glib-compile-schemas"*)
  1005. err "${portref}incorrect glib-compile-schemas" \
  1006. "invocation: ${l#@* }"
  1007. ;;
  1008. "@depend devel/gettext"*)
  1009. gettext_dep=true
  1010. ;;
  1011. share/locale/*/*/*.mo)
  1012. translation_found=true
  1013. ;;
  1014. share/dbus-1/system-services/*)
  1015. dbus_suid_dep_needed=true
  1016. ;;
  1017. "@depend x11/dbus,-suid"*)
  1018. dbus_suid_dep=true
  1019. ;;
  1020. lib/ghc/*/register.sh)
  1021. regsh=true
  1022. ;;
  1023. lib/ghc/*/unregister.sh)
  1024. unregsh=true
  1025. ;;
  1026. "@exec /usr/bin/env HOME=/nonexistent "%D/lib/ghc/*/register.sh" -v0")
  1027. regsh_exec=true
  1028. ;;
  1029. "@unexec /usr/bin/env HOME=/nonexistent "%D/lib/ghc/*/unregister.sh" -v0 --force")
  1030. unregsh_exec=true
  1031. if $unregsh; then
  1032. err "${portref}unregister.sh call placed before" \
  1033. "script itself in PLIST${subpkg}"
  1034. fi
  1035. ;;
  1036. # XXX KSH arrays are limited to 10239 items
  1037. share/@(doc|*(*/)examples)+(/*).py|?(s)bin/*.py)
  1038. # ignore
  1039. ;;
  1040. *.py)
  1041. py_files[${#py_files[@]}]=$l
  1042. ;;
  1043. *.pyc)
  1044. pyc_files[${#pyc_files[@]}]=$(normalize_pyco "$l")
  1045. ;;
  1046. *.pyo)
  1047. pyo_files[${#pyo_files[@]}]=$(normalize_pyco "$l")
  1048. ;;
  1049. share/man/*)
  1050. wrong_man=true
  1051. ;;
  1052. share/info/*)
  1053. wrong_info=true
  1054. ;;
  1055. "@man "*.gz)
  1056. err "${portref}compressed $l"
  1057. ;;
  1058. esac
  1059. done
  1060. # gtk-update-icon-cache
  1061. $guic_dep_needed && ! $guic_dep &&
  1062. [[ $fullpkgname != gtk-update-icon-cache-* ]] &&
  1063. err "${portref}missing RDEP on x11/gtk+3,-guic"
  1064. local cnt
  1065. for theme in $icon_themes; do
  1066. theme=${theme#/}
  1067. theme=${theme%/}
  1068. varname=$(echo "$theme" | sed -e 's/[^a-zA-Z_]/_/g')
  1069. ((guic_exec_cnt--)) || true
  1070. ((guic_unexec_cnt--)) || true
  1071. eval "((guic_exec_cnt_$varname--)) || true"
  1072. eval "((guic_unexec_cnt_$varname--)) || true"
  1073. eval "cnt=\$guic_exec_cnt_$varname"
  1074. if (($cnt > 0)); then
  1075. err "${portref}extra @exec of gtk-update-icon-cache" \
  1076. "for icon theme $theme"
  1077. ((guic_exec_cnt--)) || true
  1078. elif (($cnt < 0)); then
  1079. err "${portref}missing @exec of gtk-update-icon-cache" \
  1080. "for icon theme $theme"
  1081. fi
  1082. eval "cnt=\$guic_unexec_cnt_$varname"
  1083. if (($cnt > 0)); then
  1084. err "${portref}extra @unexec-delete of gtk-update-icon-cache" \
  1085. "for icon theme $theme"
  1086. ((guic_unexec_cnt--)) || true
  1087. elif (($cnt < 0)); then
  1088. err "${portref}missing @unexec-delete of gtk-update-icon-cache" \
  1089. "for icon theme $theme"
  1090. fi
  1091. done
  1092. for theme in $exec_icon_themes; do
  1093. theme=${theme#/}
  1094. theme=${theme%/}
  1095. echo "$icon_themes" | fgrep -q "/$theme/" ||
  1096. err "${portref}doing @exec of gtk-update-icon-cache" \
  1097. "for absent icon theme $theme"
  1098. done
  1099. for theme in $unexec_icon_themes; do
  1100. theme=${theme#/}
  1101. theme=${theme%/}
  1102. echo "$icon_themes" | fgrep -q "/$theme/" ||
  1103. err "${portref}doing @unexec-delete of gtk-update-icon-cache" \
  1104. "for absent icon theme $theme"
  1105. done
  1106. ((guic_exec_cnt > 0)) &&
  1107. err "${portref}extra @exec of gtk-update-icon-cache"
  1108. ((guic_unexec_cnt > 0)) &&
  1109. err "${portref}extra @unexec-delete of gtk-update-icon-cache"
  1110. # desktop-file-utils (simplier than previous, isn't it?)
  1111. $mime_dep_needed && ! $mime_dep &&
  1112. [[ $fullpkgname != desktop-file-utils-* ]] &&
  1113. err "${portref}missing RDEP on devel/desktop-file-utils"
  1114. if $mime_dep_needed; then
  1115. ((mime_exec_cnt--)) || true
  1116. ((mime_unexec_cnt--)) || true
  1117. fi
  1118. if ((mime_exec_cnt > 0)) &&
  1119. [[ $fullpkgname != desktop-file-utils-* ]]; then
  1120. err "${portref}extra @exec of update-desktop-database"
  1121. elif ((mime_exec_cnt < 0)); then
  1122. err "${portref}missing @exec of update-desktop-database"
  1123. fi
  1124. if ((mime_unexec_cnt > 0)); then
  1125. err "${portref}extra @unexec-delete of update-desktop-database"
  1126. elif ((mime_unexec_cnt < 0)); then
  1127. err "${portref}missing @unexec-delete of update-desktop-database"
  1128. fi
  1129. # update-mime-database (same as previous)
  1130. $mimepkg_dep_needed && ! $mimepkg_dep &&
  1131. [[ $fullpkgname != shared-mime-info-* ]] &&
  1132. err "${portref}missing RDEP on misc/shared-mime-info"
  1133. if $mimepkg_dep_needed; then
  1134. ((mimepkg_exec_cnt--)) || true
  1135. ((mimepkg_unexec_cnt--)) || true
  1136. fi
  1137. if ((mimepkg_exec_cnt > 0)) &&
  1138. [[ $fullpkgname != shared-mime-info-* ]]; then
  1139. err "${portref}extra @exec of update-mime-database"
  1140. elif ((mimepkg_exec_cnt < 0)); then
  1141. err "${portref}missing @exec of update-mime-database"
  1142. fi
  1143. if ((mimepkg_unexec_cnt > 0)); then
  1144. err "${portref}extra @unexec-delete of update-mime-database"
  1145. elif ((mimepkg_unexec_cnt < 0)); then
  1146. err "${portref}missing @unexec-delete of update-mime-database"
  1147. fi
  1148. # glib-compile-schemas (almost same as previous)
  1149. #
  1150. # TODO: detect situation of extra devel/dconf in MODULES
  1151. # (requires investigation of all subpackages).
  1152. if $dconf_dep_needed; then
  1153. if ! $dconf_module; then
  1154. err "${portref}GLib2 XML schemas found without" \
  1155. "devel/dconf in MODULES"
  1156. elif ! $dconf_dep; then
  1157. err "${portref}missing" \
  1158. "RUN_DEPENDS${subpkg}+=\${MODDCONF_RUN_DEPENDS}"
  1159. fi
  1160. fi
  1161. if $dconf_dep_needed; then
  1162. ((dconf_exec_cnt--)) || true
  1163. ((dconf_unexec_cnt--)) || true
  1164. fi
  1165. if ((dconf_exec_cnt > 0)) &&
  1166. [[ $fullpkgname != glib2-* ]]; then
  1167. err "${portref}extra @exec of glib-compile-schemas"
  1168. elif ((dconf_exec_cnt < 0)); then
  1169. err "${portref}missing @exec of glib-compile-schemas"
  1170. fi
  1171. if ((dconf_unexec_cnt > 0)); then
  1172. err "${portref}extra @unexec-delete of glib-compile-schemas"
  1173. elif ((dconf_unexec_cnt < 0)); then
  1174. err "${portref}missing @unexec-delete of glib-compile-schemas"
  1175. fi
  1176. # gettext
  1177. $translation_found && ! $gettext_dep && ! $is_static &&
  1178. [[ $fullpkgname != gettext-* ]] &&
  1179. err "${portref}translation file(s) found without" \
  1180. "devel/gettext dependency in RUN_DEPENDS"
  1181. # dbus,-suid
  1182. if $dbus_suid_dep_needed && ! $dbus_suid_dep; then
  1183. err "${portref}missing" \
  1184. "RUN_DEPENDS${subpkg}+=x11/dbus,-suid"
  1185. fi
  1186. # Haskell register/unregister
  1187. if $regsh && ! $regsh_exec; then
  1188. err "${portref}missing @exec of register.sh"
  1189. fi
  1190. if $unregsh && ! $unregsh_exec; then
  1191. err "${portref}missing @unexec of unregister.sh"
  1192. fi
  1193. # Python modules
  1194. ((${#py_files[@]} > 0)) && set -sA py_files -- "${py_files[@]}"
  1195. ((${#pyc_files[@]} > 0)) && set -sA pyc_files -- "${pyc_files[@]}"
  1196. ((${#pyo_files[@]} > 0)) && set -sA pyo_files -- "${pyo_files[@]}"
  1197. local ic=0 io=0
  1198. if ((${#py_files[@]} > 0)); then for py in "${py_files[@]}"; do
  1199. while [[ $ic -lt ${#pyc_files[@]} ]]; do
  1200. [[ ${pyc_files[$ic]} < "$py"c ]] || break
  1201. # allowed behaviour
  1202. #err "${portref}compiled Python module without" \
  1203. # "source, expected: ${pyc_files[$ic]%c}"
  1204. ((++ic))
  1205. done
  1206. if [[ $ic -lt ${#pyc_files[@]} &&
  1207. ${pyc_files[$ic]} == "$py"c ]]; then
  1208. ((++ic))
  1209. else
  1210. err "${portref}Python module without" \
  1211. "compiled version, consider using" \
  1212. "\${MODPY_BIN} \${MODPY_LIBDIR}/compileall.py: $py"
  1213. fi
  1214. while [[ $io -lt ${#pyo_files[@]} ]]; do
  1215. [[ ${pyo_files[$io]} < "$py"o ]] || break
  1216. # allowed behaviour
  1217. #err "${portref}optimized Python module without" \
  1218. # "source, expected: ${pyo_files[$io]%o}"
  1219. ((++io))
  1220. done
  1221. if [[ $io -lt ${#pyo_files[@]} &&
  1222. ${pyo_files[$io]} == "$py"o ]]; then
  1223. ((++io))
  1224. # too much noise, maybe enable in the future
  1225. #else
  1226. # err "${portref}Python module without" \
  1227. # "optimized version: $py"
  1228. fi
  1229. done; fi
  1230. # allowed behaviour
  1231. #while (($ic < ${#pyc_files[@]})); do
  1232. # err "${portref}compiled Python module without source," \
  1233. # "expected: ${pyc_files[$ic]%c}"
  1234. # ((++ic))
  1235. #done
  1236. # allowed behaviour
  1237. #while (($io < ${#pyo_files[@]})); do
  1238. # err "${portref}optimized Python module without source," \
  1239. # "expected: ${pyo_files[$io]%o}"
  1240. # ((++io))
  1241. #done
  1242. $wrong_man && err "${portref}manual pages should go under" \
  1243. "\${PREFIX}/man/ rather than under \${PREFIX}/share/man/"
  1244. $wrong_info && err "${portref}info pages should go under" \
  1245. "\${PREFIX}/info/ rather than under \${PREFIX}/share/info/"
  1246. }
  1247. # Checks made:
  1248. # * devel/gettext dependency is not forgotten.
  1249. # * lib/kde/ and lib/kde4/ prefixes not missing where applicable.
  1250. # * stdc++ doesn't get into WANTLIB when gcc4.port.mk is used.
  1251. check_wantlib() {
  1252. local portref="$1"; shift
  1253. local modules="$1"; shift
  1254. local phonon_s_wantlib=false
  1255. local kde3_module=false
  1256. local kde4_module=false
  1257. local phonon_module=false
  1258. local gcc4_module=false
  1259. local v
  1260. for v in $modules; do case $v in
  1261. gcc4) gcc4_module=true;;
  1262. multimedia/phonon) phonon_module=true;;
  1263. x11/kde) kde3_module=true;;
  1264. x11/kde4) kde4_module=true;;
  1265. esac; done
  1266. for v; do case $v in
  1267. phonon_s?(?(">")=+([0-9])))
  1268. phonon_s_wantlib=true
  1269. ;;
  1270. @(smbclient|wbclient)?(?('>')=+([0-9])))
  1271. err "$portref$v instead of lib/samba/$v" \
  1272. "in WANTLIB"
  1273. ;;
  1274. @(DCOP|soundserver_idl|vcard)?(?('>')=+([0-9])))
  1275. err "$portref$v instead of \${KDE}/$v" \
  1276. "in WANTLIB (check other libs, too!)"
  1277. ;;
  1278. @(kdecore|kdeui|kio)?(?('>')=+([0-9])))
  1279. if $kde4_module; then
  1280. err "$portref$v instead of \${KDE4LIB}/$v" \
  1281. "in WANTLIB (check other libs, too!)"
  1282. elif $kde3_module; then
  1283. err "$portref$v instead of \${KDE}/$v" \
  1284. "in WANTLIB (check other libs, too!)"
  1285. else
  1286. err "$portref$v WANTLIB without x11/kde*" \
  1287. "in MODULES (check other libs, too!)"
  1288. fi
  1289. ;;
  1290. stdc++?(?('>')=+([0-9])))
  1291. if $gcc4_module; then
  1292. err "$portref$v in WANTLIB when gcc4 is" \
  1293. "in MODULES; run port-lib-depends-check" \
  1294. "and if stdc++ is still there, check" \
  1295. "actual build thoroughly, it's broken"
  1296. fi
  1297. esac; done
  1298. if $phonon_s_wantlib && ! $phonon_module; then
  1299. err "${portref}missing multimedia/phonon in MODULES"
  1300. fi
  1301. true
  1302. }
  1303. # Checks made:
  1304. # * Each library mentioned in WANTLIB is accessible either:
  1305. # a) as a part of base system, in /usr/lib or /usr/X11R6/lib;
  1306. # b) via LIB_DEPENDS directly, or via deeper dependency of LIB_DEPENDS.
  1307. check_lib_depends() {
  1308. $debugging && echo "CALLED: check_lib_depends($*)" >&2
  1309. local portref="$1"; shift
  1310. local subpkg="$1"; shift
  1311. local modules="$1"; shift
  1312. local wantlib="$1"; shift
  1313. # The idea as follows: build full list of run-time dependencies, but
  1314. # without RUN_DEPENDS begin involved.
  1315. #
  1316. # Then we look at libs in each pkgpath we got, and strip those
  1317. # from WANTLIB. We also strip system libraries from /usr/lib
  1318. # and /usr/X11R6/lib. And all WANTLIBs coming from MODULES are stripped
  1319. # too, supposing that authors of those MODULES know what they're doing
  1320. # (without stripping 'em, we'll get many false positives).
  1321. #
  1322. # If there are any non-stripped items in WANTLIB, we found a problem.
  1323. #
  1324. # XXX those checks do not take actual versions into account!
  1325. # get list of all WANTLIBs coming from MODULES
  1326. local m modvars=
  1327. for m in $modules; do
  1328. m=${m##*/}
  1329. case $m in
  1330. python)
  1331. m=py
  1332. ;;
  1333. esac
  1334. m=$(echo "MOD${m}_WANTLIB" | tr a-z A-Z)
  1335. modvars="$modvars $m"
  1336. done
  1337. local l modlibs=
  1338. make "${make_args[@]}" show="$modvars" </dev/null |&
  1339. while read -pr l; do
  1340. modlibs="$modlibs $l"
  1341. done
  1342. wait # make sure process exited before possible return below
  1343. # strip WANTLIBs coming from MODULES
  1344. local libsleft wl
  1345. for l in $modlibs; do
  1346. libsleft=
  1347. for wl in $wantlib; do
  1348. if [[ $l != "$wl" ]]; then
  1349. libsleft="$libsleft $wl"
  1350. elif $debugging; then
  1351. echo "WANTLIB ITEM $wl COMES FROM MODULES"
  1352. fi
  1353. done
  1354. [[ -n $libsleft ]] || return 0 # all libs found
  1355. wantlib=$libsleft
  1356. done
  1357. # prepare easy-to-use WANTLIB list in $checklibs
  1358. local wlprefix checklibs=
  1359. for wl in $wantlib; do
  1360. wl=${wl%%[><=]*}
  1361. wlprefix=${wl%/*}
  1362. [[ $wlprefix == "$wl" ]] && wlprefix=lib
  1363. wl=${wl##*/}
  1364. checklibs="$checklibs ${wlprefix}/lib$wl"
  1365. done
  1366. # strip system libraries
  1367. local d
  1368. for d in /usr /usr/X11R6; do
  1369. for l in $d/lib/lib*.@(so*(.+([0-9]))|a); do
  1370. libsleft=
  1371. for wl in $checklibs; do
  1372. if [[ $l != +(/*)/${wl}.@(so*(.+([0-9]))|a) ]]; then
  1373. libsleft="$libsleft $wl"
  1374. elif $debugging; then
  1375. echo "FOUND WANTLIB ITEM $wl: $l"
  1376. fi
  1377. done
  1378. [[ -n $libsleft ]] || return 0 # all libs found
  1379. checklibs=$libsleft
  1380. done
  1381. done
  1382. # get deep list of LDEPs
  1383. local lmake_args="${make_args[@]}"
  1384. lmake_args[${#lmake_args[@]}]="RUN_DEPENDS="
  1385. lmake_args[${#lmake_args[@]}]="RUN_DEPENDS$subpkg="
  1386. # Rely on the fact we're already in the port directory, see sub_checks().
  1387. # XXX ignoring make errors for now
  1388. local pure_lib_deps=$(make "${lmake_args[@]}" show-run-depends | sort)
  1389. [[ -n $pure_lib_deps ]] || return 0
  1390. # SUBDIR doesn't accept newline-separated values
  1391. set -A pure_lib_deps -- $pure_lib_deps
  1392. (
  1393. # strip libraries from ports
  1394. # TODO cache print-plist-libs output?
  1395. cd -- /usr/ports # XXX "$portsdir" fails for openbsd-wip and like
  1396. unset FLAVOR SUBPACKAGE
  1397. make "${make_args[@]}" SUBDIR="${pure_lib_deps[*]}" \
  1398. print-plist-libs </dev/null 2>/dev/null |&
  1399. while read -pr l; do
  1400. case $l in
  1401. "===> "*)
  1402. ;;
  1403. *)
  1404. libsleft=
  1405. for wl in $checklibs; do
  1406. if [[ $l != +(/*)/${wl}.@(so*(.+([0-9]))|a) ]]; then
  1407. libsleft="$libsleft $wl"
  1408. elif $debugging; then
  1409. echo "FOUND WANTLIB ITEM $wl: $l"
  1410. fi
  1411. done
  1412. [[ -n $libsleft ]] || exit 0 # all libs found
  1413. checklibs=$libsleft
  1414. ;;
  1415. esac
  1416. done
  1417. # prettify list of WANTLIBs left and print it
  1418. libsleft=
  1419. for wl in $checklibs; do
  1420. libsleft="$libsleft ${wl##*/lib}"
  1421. done
  1422. err "${portref}the following libraries in WANTLIB${subpkg%-}" \
  1423. "look like masked by RUN_DEPENDS${subpkg%-}:$libsleft"
  1424. wait
  1425. ! $error
  1426. ) || error=true
  1427. }
  1428. # Checks made:
  1429. # * No extra PERMIT_DISTFILES_FTP variables in Makefile.
  1430. # * PERMIT_DISTFILES_FTP should not contain just "No" but a reason.
  1431. #
  1432. # Runs in the port directory.
  1433. # XXX does not handle Makefile.inc and other .include cases correctly.
  1434. check_permit_dist() {
  1435. $debugging && echo "CALLED: check_permit_dist($*)" >&2
  1436. local portref=$(portref $1); shift
  1437. local perm_pkg_cdrom=$(echo "$1" | tr '[:upper:]' '[:lower:]')
  1438. local perm_pkg_ftp=$(echo "$2" | tr '[:upper:]' '[:lower:]')
  1439. local perm_dist_ftp=$(echo "$3" | tr '[:upper:]' '[:lower:]')
  1440. if [[ ($perm_pkg_cdrom == yes || $perm_pkg_ftp == yes) && \
  1441. $perm_dist_ftp == yes ]]; then
  1442. egrep -sq "^ *PERMIT_DISTFILES_FTP[[:space:]]*=" Makefile &&
  1443. err "${portref}extra PERMIT_DISTFILES_FTP line(-s)"
  1444. fi
  1445. if [[ $perm_dist_ftp == no ]]; then
  1446. err "${portref}PERMIT_DISTFILES_FTP should be either" \
  1447. "\"Yes\" or a reason for being non-redistributable"
  1448. fi
  1449. true
  1450. }
  1451. # Checks made:
  1452. # * No extra PERMIT_PACKAGE_FTP variables in Makefile.
  1453. # * PERMIT_PACKAGE_* should not contain just "No" but a reason.
  1454. #
  1455. # Runs in the port directory.
  1456. # XXX does not handle Makefile.inc and other .include cases correctly.
  1457. check_permit_subpkg() {
  1458. $debugging && echo "CALLED: check_permit_subpkg($*)" >&2
  1459. local portref=$1; shift
  1460. local subpkg=${1%-}; shift
  1461. local perm_pkg_cdrom=$(echo "$1" | tr '[:upper:]' '[:lower:]')
  1462. local perm_pkg_ftp=$(echo "$2" | tr '[:upper:]' '[:lower:]')
  1463. if [[ $perm_pkg_cdrom == yes && $perm_pkg_ftp == yes ]]; then
  1464. egrep -q "^ *PERMIT_PACKAGE_FTP${subpkg}[[:space:]]*=" Makefile &&
  1465. err "${portref}extra PERMIT_PACKAGE_FTP lines"
  1466. fi
  1467. if [[ $perm_pkg_cdrom == no ]]; then
  1468. err "${portref} PERMIT_PACKAGE_CDROM should be either" \
  1469. "\"Yes\" or a reason for being non-redistributable"
  1470. fi
  1471. if [[ $perm_pkg_ftp == no ]]; then
  1472. err "${portref} PERMIT_PACKAGE_FTP should be either" \
  1473. "\"Yes\" or a reason for being non-redistributable"
  1474. fi
  1475. true
  1476. }
  1477. # Checks made:
  1478. # * Directory is not empty
  1479. # * No '*.core' files present
  1480. check_files_dir() {
  1481. $debugging && echo "CALLED: check_files_dir($*)" >&2
  1482. find -f "$1" -- -type f | {
  1483. local empty=true
  1484. local mode
  1485. while read F; do
  1486. ignoring "$F" && continue
  1487. mode=$(stat -f %p "$F" || true)
  1488. (( (0$mode & 0111) != 0 )) &&
  1489. err "executable file: $F"
  1490. empty=false
  1491. [[ $F == *.core ]] &&
  1492. err_coredump_found "$F"
  1493. done
  1494. $empty && err "there are no files, please remove the $1 directory"
  1495. ! $error
  1496. } || error=true
  1497. }
  1498. # Checks made:
  1499. # * The patch is not empty.
  1500. # * The patch contains an OpenBSD RCS tag.
  1501. check_patch() {
  1502. local F=$1
  1503. test -f "$F" || {
  1504. err "$F is not a file"
  1505. return
  1506. }
  1507. if [ -s "$F" ]; then
  1508. head -n 1 -- "$F" | egrep -q '^\$OpenBSD.*\$$' ||
  1509. err "$F does not have \$OpenBSD\$ RCS tag at the top"
  1510. else
  1511. err "$F is empty and should be removed"
  1512. fi
  1513. }
  1514. # Checks made:
  1515. # * Each patch contains OpenBSD RCS tag.
  1516. # * Directory is not empty and consists only of plain files starting
  1517. # with 'patch-' and not ending with '.orig'.
  1518. check_patches_dir() {
  1519. $debugging && echo "CALLED: check_patches_dir($*)" >&2
  1520. local empty=true
  1521. local F
  1522. check_perms_in_dir "$1"
  1523. for F in "$1"/* "$1"/.*; do case "${F##*/}" in
  1524. patch-*.orig)
  1525. handle_extra_file "$F"
  1526. ;;
  1527. patch-*)
  1528. empty=false
  1529. $rootrun || check_patch "$F"
  1530. ;;
  1531. *)
  1532. handle_extra_file "$F"
  1533. ;;
  1534. esac; done
  1535. $empty && err "there are no patches, please remove the $1 directory instead"
  1536. }
  1537. # Checks made:
  1538. # * Directory is not empty and consist only of plain files with fixed names.
  1539. # * PFRAG, PLIST, README and .rc files contain appropriate OpenBSD RCS
  1540. # tags; other files should NOT contain OpenBSD RCS tag.
  1541. # * PFRAG.shared should be merged into PLIST.
  1542. # * No trailing whitespace for DESCR, MESSAGE, README, UNMESSAGE and
  1543. # .rc files (PLIST and PFRAG are better checked with "make package").
  1544. # * See also check_plist_file().
  1545. check_pkg_dir() {
  1546. $debugging && echo "CALLED: check_pkg_dir($*)" >&2
  1547. local dir=$1; shift
  1548. local subst_cmd
  1549. if (($# > 0)); then
  1550. # XXX should find the way to always obtain SUBST_CMD
  1551. subst_cmd=$1
  1552. shift
  1553. fi
  1554. local empty=true
  1555. local F
  1556. local plist
  1557. check_perms_in_dir "$dir"
  1558. dir="${dir#./}"
  1559. for F in "$dir"/* "$dir"/.*; do case "${F##*/}" in
  1560. DESCR?(-*))
  1561. empty=false
  1562. [[ -f $F ]] ||
  1563. err "$F is not a file"
  1564. check_trailing_whitespace "$F"
  1565. check_newline_at_eof "$F"
  1566. check_long_lines "$F"
  1567. check_hardcoded "$F"
  1568. [[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
  1569. egrep -q '\$OpenBSD.*\$' "$F" &&
  1570. err "$F should not contain \$OpenBSD\$ tag"
  1571. ;;
  1572. PFRAG.shared?(-*))
  1573. empty=false
  1574. [[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
  1575. check_plist_file "$F"
  1576. plist=PLIST${F##*/PFRAG.+([!-])}
  1577. err "$F should be merged into $plist"
  1578. ;;
  1579. PFRAG.*|PLIST?(-*))
  1580. empty=false
  1581. [[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
  1582. check_plist_file "$F"
  1583. ;;
  1584. README?(-*))
  1585. [[ -f $F ]] ||
  1586. err "$F is not a file"
  1587. [[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
  1588. check_trailing_whitespace "$F"
  1589. check_newline_at_eof "$F"
  1590. check_long_lines "$F"
  1591. check_hardcoded "$F"
  1592. head -n 1 -- "$F" |
  1593. egrep -q '^(#[[:space:]]*)?\$OpenBSD(:.*)?\$$' ||
  1594. err "$F does not have \$OpenBSD\$ RCS tag at the top"
  1595. ;;
  1596. *.rc)
  1597. [[ -f $F ]] ||
  1598. err "$F is not a file"
  1599. [[ ${F##*/} == [A-Za-z_]*([A-Za-z0-9_]).rc ]] ||
  1600. err "$F name will not work in rc.subr(8)"
  1601. check_trailing_whitespace "$F"
  1602. check_long_lines "$F"
  1603. check_hardcoded "$F"
  1604. head -n 5 -- "$F" |
  1605. egrep -q '^#[[:space:]]*\$OpenBSD(:.*)?\$$' ||
  1606. err "$F does not have \$OpenBSD\$ RCS tag at the top"
  1607. ;;
  1608. MESSAGE?(-*)|UNMESSAGE?(-*))
  1609. [[ -f $F ]] ||
  1610. err "$F is not a file"
  1611. [[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
  1612. check_trailing_whitespace "$F"
  1613. check_newline_at_eof "$F"
  1614. check_long_lines "$F"
  1615. check_hardcoded "$F"
  1616. egrep -q '\$OpenBSD.*\$' "$F" &&
  1617. err "$F should not contain \$OpenBSD\$ tag"
  1618. ;;
  1619. *)
  1620. handle_extra_file "$F"
  1621. ;;
  1622. esac; done
  1623. $empty && err "$dir directory does not contain either DESCR, PFRAG or PLIST files"
  1624. }
  1625. # Checks made:
  1626. # * There are no hardcoded /usr/local or /var paths in file.
  1627. # /var/log, /var/run and /var/tmp are perfectly fine, though.
  1628. check_hardcoded() {
  1629. $debugging && echo "CALLED: check_hardcoded($*)" >&2
  1630. perl -n -e 'BEGIN { $ec=0; }
  1631. if (m,/usr/local\b,o) { $ec=1; close ARGV; }
  1632. if (m,/var((?:/+[^/\s]+)*)(?:\s.*)?$,o) {
  1633. unless ($1 =~ m,^/+(?:log|run|tmp),o) {
  1634. $ec=1; close ARGV;
  1635. }
  1636. }
  1637. END { $? = $ec; }' \
  1638. "$1" || err "hardcoded paths detected in $1, consider using" \
  1639. "SUBST_VARS and TRUEPREFIX/LOCALBASE/LOCALSTATEDIR/VARBASE"
  1640. }
  1641. # Checks made:
  1642. # * There are no lines longer than 80 characters that have at least
  1643. # one space (avoids warnings on long URLs etc.).
  1644. check_long_lines() {
  1645. $debugging && echo "CALLED: check_long_lines($*)" >&2
  1646. local file=$1; shift
  1647. local n=$(awk <"$file" \
  1648. '/[[:space:]]/ && length > 80 { n++ } END { print n+0 }')
  1649. (($n > 0 )) &&
  1650. err "$n line(s) longer than 80 chars in $file"
  1651. }
  1652. # Checks made:
  1653. # * There is an OpenBSD RCS tag at the top.
  1654. # * No items with ${FULLPKGNAME} are allowed, except readme.
  1655. # * No empty lines.
  1656. check_plist_file() {
  1657. $debugging && echo "CALLED: check_plist_file($*)" >&2
  1658. [[ -f $1 ]] ||
  1659. err "$1 is not a file"
  1660. head -n 1 -- "$1" |
  1661. egrep -q '^@comment \$OpenBSD.*\$$' ||
  1662. err "$1 does not have \$OpenBSD\$ RCS tag at the top"
  1663. # Do not match just '${FULLPKGNAME}' because many ports use the
  1664. # following trick:
  1665. # @cwd ${LOCALBASE}/share/doc/pkg-readmes
  1666. # ${FULLPKGNAME}
  1667. egrep -v '^(share/doc/pkg-readmes/\$\{FULLPKGNAME\}|@comment .*)$' "$1" |
  1668. egrep '.\$\{FULLPKGNAME\}|\$\{FULLPKGNAME\}.' >&2 &&
  1669. err "$1 contains item(s) with \${FULLPKGNAME} in it, see above"
  1670. egrep -q '^[[:space:]]*$' "$1" && err "$1 contains empty lines"
  1671. }
  1672. # Checks made:
  1673. # * Every variable referenced by ${[A-Z]+} should be in ${SUBST_VARS}.
  1674. check_subst_vars() {
  1675. $debugging && echo "CALLED: check_subst_vars($*)" >&2
  1676. local F=$1; shift
  1677. local subst_cmd=$1; shift
  1678. # Add variables sometimes referenced in port docs.
  1679. eval "$subst_cmd" -DPATH=test -DWRKSRC=test <"$F" |
  1680. egrep '\$\{[A-Z]+\}' >&2 &&
  1681. err "looks like misspelled variables in $F, see above"
  1682. }
  1683. # Checks made:
  1684. # * Contains OpenBSD RCS tag at the top line.
  1685. # * No REVISION marks present in given file (unless in update mode).
  1686. # * Each REVISION mark presents only once.
  1687. # * BUILD_DEPENDS, MODULES and PERMIT_DISTFILES_FTP are not defined in
  1688. # VAR-subpkg manner.
  1689. # * No trailing whitespace.
  1690. # * SHARED_LIBS are not defined inside ".if" statements.
  1691. # * Variables are not assigned via "=" twice outside of .if statemets.
  1692. # * No user settings present.
  1693. # * SHARED_ONLY not defined
  1694. check_makefile() {
  1695. $debugging && echo "CALLED: check_makefile($*)" >&2
  1696. local F="$1"
  1697. check_trailing_whitespace "$F"
  1698. check_long_lines "$F"
  1699. check_hardcoded "$F"
  1700. head -n 1 -- "$F" |
  1701. egrep -q '^#[[:space:]]*\$OpenBSD.*\$' ||
  1702. err "$F does not have \$OpenBSD\$ RCS tag at the top"
  1703. local iflevel=0 l lnum=0 revs= t r mkvars= var duprevfound
  1704. # do not unset mkvars, having empty element(-s) is fine
  1705. unset revs[0]
  1706. local tab="$(print '\t')"
  1707. while IFS= read -r l; do ((++lnum))
  1708. set -A t -- $l
  1709. duprevfound=false
  1710. if echo "$l" | egrep -q "^ *($user_settings)[[:>:]].*\$"; then
  1711. err "user settings in port: $l"
  1712. fi
  1713. case $l in
  1714. *(" ")REVISION*)
  1715. $existing_port ||
  1716. err "REVISION mark found at $F:$lnum"
  1717. var=${t[0]%=}
  1718. if ((${#revs[@]} > 0)); then
  1719. for r in "${revs[@]}"; do
  1720. if [[ $var == "$r" ]]; then
  1721. err "duplicated $r in $F"
  1722. # avoid dup error messages
  1723. duprevfound=true
  1724. break
  1725. fi
  1726. done
  1727. fi
  1728. revs[${#revs[@]}]=${t[0]}
  1729. ;;
  1730. *(" ")@(BUILD_DEPENDS|MODULES|PERMIT_DISTFILES_FTP)-*)
  1731. err "${l%%-*} is not a subpackageble variable, see $F:$lnum"
  1732. ;;
  1733. *(" ").*(" "|"$tab")if*)
  1734. ((++iflevel))
  1735. ;;
  1736. *(" ").*(" "|"$tab")endif*)
  1737. ((iflevel--))
  1738. ;;
  1739. *(" ")SHARED_LIBS*(" "|"$tab")*(+|:|!)=*)
  1740. if ((iflevel > 0)); then
  1741. err "should not be inside .if block ($F:$lnum): $l"
  1742. fi
  1743. ;;
  1744. *(" ")SHARED_ONLY*(" "|"$tab")*(+|:|!|\?)=*)
  1745. err "SHARED_ONLY is deprecated ($F:$lnum)"
  1746. ;;
  1747. esac
  1748. if [[ $l == *(" ")+([A-Za-z0-9_-])*(" "|"$tab")?(\?)=* ]] &&
  1749. ((iflevel == 0)) && ! $duprevfound; then
  1750. var=${t[0]%?(\?)=*}
  1751. for v in "${mkvars[@]}"; do
  1752. if [[ $v == "$var" ]]; then
  1753. err "duplicated assignment of $v" \
  1754. "at $F:$lnum"
  1755. break
  1756. fi
  1757. done
  1758. mkvars[${#mkvars[@]}]=$var
  1759. fi
  1760. done <"$F"
  1761. }
  1762. # Checks made:
  1763. # * None of executable bits (111) are set on plain files.
  1764. check_perms_in_dir() {
  1765. $debugging && echo "CALLED: check_perms_in_dir($*)" >&2
  1766. (find -f "$1" -- -maxdepth 1 -type f \
  1767. \( -perm -100 -or -perm -010 -or -perm 001 \) \
  1768. </dev/null || true) |&
  1769. local F
  1770. while read -pr F; do
  1771. F=${F#./}
  1772. ignoring "$F" && continue
  1773. err "executable file: ${F#./}"
  1774. done
  1775. }
  1776. ############################################################
  1777. # Run checks. Also calculate and show pkgpath variable,
  1778. # unless we're checking the ports tree root dir.
  1779. #
  1780. for D; do
  1781. if [[ $D == /* ]]; then
  1782. err "absolute path $D ignored"
  1783. continue
  1784. fi
  1785. if [[ $D == *(*/)..*(/*) ]]; then
  1786. err "too many .. in $D, skipping"
  1787. continue
  1788. fi
  1789. check_port_dir "$D"
  1790. done
  1791. if ! $rootrun; then
  1792. [[ -z $pkgpath ]] && pkgpath=${PWD##"$portsdir/"}
  1793. if [[ $pkgpath == "$PWD" ]]; then
  1794. cat >&2 <<EOE
  1795. ${0##*/}: could not determine PKGPATH. Please help me with the -p option.
  1796. EOE
  1797. exit 2
  1798. fi
  1799. echo "$pkgpath"
  1800. fi
  1801. ! $error