project 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519
  1. #!/usr/bin/env bash
  2. # Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
  3. # Copyright (C) 2018 Andrew Robbins <contact@andrewrobbins.info>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. PROJECT_ACTIONS_GENERIC=(usage dependencies download extract update build install release clean)
  18. PROJECT_ACTIONS_GENERIC_IGNORE_CHECK=(usage clean)
  19. PROJECT_ACTIONS_HELPERS=(arguments dependencies)
  20. INSTALL_REGEX='\([^:]*\):\(.*\)'
  21. project_include() {
  22. local project=$1
  23. local project_path=$(project_path "$project")
  24. unset -f "${PROJECT_ACTIONS[@]}"
  25. source "$project_path/$project"
  26. project_helper_include "$project"
  27. }
  28. project_helper_include() {
  29. local project=$1
  30. local project_path=$(project_path "$project")
  31. local include="$project_path/$project-helper"
  32. if [[ -f "$include" ]]
  33. then
  34. source "$include"
  35. fi
  36. }
  37. project_check() {
  38. local project="${1##*/}"
  39. local project_path="$(project_path "$project")"
  40. if ! [[ -f "$project_path/$project" ]]; then
  41. return 1
  42. fi
  43. }
  44. project_dependencies() {
  45. local project=$1
  46. shift
  47. local -a dependencies
  48. mapfile -t dependencies < <(project_file_contents_herit "$project" "$CONFIGS" "$DEPENDENCIES" "$@")
  49. if [[ -n ${dependencies[*]} ]]; then
  50. printf '%s\n' "${dependencies[@]}"
  51. fi
  52. }
  53. project_dependencies_check() {
  54. local project=$1
  55. shift
  56. local -a dependencies
  57. mapfile -t dependencies < <(project_dependencies "$project" "$@")
  58. local -i count=${#dependencies[@]}
  59. local -i missing=0
  60. for ((i = 0; i < count; i++)); do
  61. local -a dependency=(${dependencies[i]})
  62. project_check "${dependency[0]}" || let missing++
  63. done
  64. return $missing
  65. }
  66. project_dependencies_sources_check() {
  67. local project=$1
  68. shift
  69. local -a dependencies
  70. mapfile -t dependencies < <(project_dependencies "$project" "$@")
  71. local -i count=${#dependencies[@]}
  72. local -i missing=0
  73. for ((i = 0; i < count; i++)); do
  74. local -a dependency=(${dependencies[i]})
  75. project_sources_directory_filled_check "${dependency[0]}" \
  76. || let missing++
  77. done
  78. return $missing
  79. }
  80. project_dependencies_action_arguments() {
  81. local action=$1
  82. local project=$2
  83. shift 2
  84. local -a dependencies
  85. mapfile -t dependencies < <(project_dependencies "$project" "$@")
  86. local -i count=${#dependencies[@]}
  87. for ((i = 0; i < count; i++)); do
  88. local -a dependency=(${dependencies[i]})
  89. if project_function_check "${dependency[0]}" "$action"; then
  90. project_action_arguments "$action" "${dependency[@]}"
  91. fi
  92. done
  93. }
  94. project_function_check() {
  95. local project=$1
  96. local function=$2
  97. project_include "$project"
  98. if ! function_check "$function"
  99. then
  100. return 1
  101. fi
  102. return 0
  103. }
  104. project_action() {
  105. local action="$1"
  106. shift
  107. local project="$1"
  108. shift
  109. local arguments="$*"
  110. (
  111. set +e
  112. project_action_check "$action" "$project" "$@"
  113. printf '%s\n\n' "Project $project $action (with ${arguments:-no argument})"
  114. if "$action" "$@"; then
  115. printf '\n%s\n' "Project $project $action (with ${arguments:-no argument}) completed"
  116. else
  117. printf 1>&2 '\n%s\n' "Project $project $action (with ${arguments:-no argument}) failed"
  118. return 1
  119. fi
  120. )
  121. }
  122. project_action_check() {
  123. local action="$1"
  124. shift
  125. local project="$1"
  126. shift
  127. (
  128. set +e
  129. if ! function_check "${action}_check"; then
  130. return 1
  131. fi
  132. for project_force in $PROJECTS_FORCE; do
  133. if [[ "$project_force" == "$project" ]]; then
  134. return 1
  135. fi
  136. done
  137. (
  138. set -e
  139. "${action}_check" "$@"
  140. )
  141. )
  142. }
  143. project_action_helper() {
  144. local helper="$1"
  145. shift
  146. local project="$1"
  147. shift
  148. if ! function_check "$helper"; then
  149. return 0
  150. fi
  151. "$helper" "$@"
  152. }
  153. project_action_arguments() {
  154. local action="$1"
  155. shift
  156. local project="$1"
  157. shift
  158. project_include "$project"
  159. project_action_arguments_verify_recursive "$action" "$project" "$@"
  160. project_action_arguments_recursive "$action" "$project" "$@"
  161. }
  162. project_action_arguments_verify_recursive() {
  163. local action="$1"
  164. shift
  165. local project="$1"
  166. shift
  167. local action_helper_arguments
  168. # Store final argument.
  169. local argument="${*:$#}"
  170. local test
  171. if [[ "$#" -gt 1 ]]; then
  172. # Set previous arguments.
  173. set "${@:1:$#-1}"
  174. elif [[ "$#" -eq 1 ]]; then
  175. shift
  176. else
  177. return 0
  178. fi
  179. action_helper_arguments="$(project_action_helper 'arguments' "$project" "$@")"
  180. if [[ -n "$action_helper_arguments" ]]; then
  181. test="$(printf '%s\n' "$action_helper_arguments" | grep -e "^$argument\$" || true)"
  182. if [[ -z "$test" ]]; then
  183. printf 1>&2 '%s\n' "Invalid argument $argument for project $project action $action"
  184. return 1
  185. fi
  186. fi
  187. project_action_arguments_verify_recursive "$action" "$project" "$@"
  188. }
  189. project_action_arguments_recursive() {
  190. local action="$1"
  191. shift
  192. local project="$1"
  193. shift
  194. local action_helper_arguments
  195. local argument
  196. action_helper_arguments="$(project_action_helper 'arguments' "$project" "$@" || true)"
  197. if [[ -z "$action_helper_arguments" ]]; then
  198. project_action "$action" "$project" "$@"
  199. else
  200. # This is to allow space characters in arguments.
  201. local ifs_save="$IFS"
  202. local IFS=$'\n'
  203. for argument in $(printf '%s\n' "$action_helper_arguments")
  204. do
  205. IFS="$ifs_save"
  206. # Only a single argument at a time is returned by the helper.
  207. project_action_arguments_recursive "$action" "$project" "$@" "$argument"
  208. done
  209. fi
  210. }
  211. project_action_projects() {
  212. local action="$1"
  213. shift
  214. local project="$1"
  215. shift
  216. local project_path="$(project_path "$project")"
  217. local project_projects_path="$project_path/$CONFIGS/$PROJECTS"
  218. local project_projects_action_path="$project_path/$CONFIGS/$PROJECTS-$action"
  219. local arguments
  220. local path
  221. if [[ -f "$project_projects_action_path" ]]; then
  222. path="$project_projects_action_path"
  223. else
  224. path="$project_projects_path"
  225. fi
  226. # Multiple arguments can be read from the file.
  227. while read -r arguments; do
  228. eval "project_action_arguments $action $arguments"
  229. done < "$path"
  230. }
  231. project_path() {
  232. local project=$1
  233. local project_path="$root/$PROJECTS/$project"
  234. printf '%s\n' "$project_path"
  235. }
  236. project_sources_path() {
  237. local project=$1
  238. shift
  239. local repository=$1
  240. shift
  241. local sources_path
  242. local argument
  243. local path
  244. # Check downloaded and extracted sources first, using "$project."
  245. path="$root/$SOURCES/$project"
  246. for argument in "" "$@"
  247. do
  248. if [[ -n "$argument" ]]
  249. then
  250. path="$path-$argument"
  251. fi
  252. if ! directory_filled_check "$path"
  253. then
  254. continue
  255. fi
  256. sources_path=$path
  257. done
  258. if [[ -n "$sources_path" ]]
  259. then
  260. printf '%s\n' "$sources_path"
  261. return
  262. fi
  263. # Check downloaded sources then, using "$repository."
  264. path="$root/$SOURCES/$repository"
  265. if directory_filled_check "$path"
  266. then
  267. printf '%s\n' "$path"
  268. return
  269. fi
  270. # Check project sources finally, using "$project."
  271. path="$root/$PROJECTS/$project/$SOURCES"
  272. for argument in "" "$@"
  273. do
  274. if [[ -n "$argument" ]]
  275. then
  276. path="$path/$argument"
  277. fi
  278. if ! directory_filled_check "$path"
  279. then
  280. continue
  281. fi
  282. sources_path=$path
  283. done
  284. if [[ -n "$sources_path" ]]
  285. then
  286. printf '%s\n' "$sources_path"
  287. return
  288. fi
  289. }
  290. project_sources_directory_filled_check() {
  291. local project=$1
  292. shift
  293. local sources_path=$(project_sources_path "$project" "$@")
  294. test ! -z "$sources_path"
  295. }
  296. project_sources_directory_filled_error() {
  297. local project=$1
  298. shift
  299. local arguments="$*"
  300. local sources_path=$(project_sources_path "$project" "$@")
  301. if [[ -n "$sources_path" ]]
  302. then
  303. printf 1>&2 '%s\n' "Sources directory for project $project (with ${arguments:-no argument}) already exists"
  304. return 1
  305. else
  306. return 0
  307. fi
  308. }
  309. project_sources_directory_missing_empty_error() {
  310. local project=$1
  311. shift
  312. local arguments="$*"
  313. local sources_path=$(project_sources_path "$project" "$@")
  314. if [[ -z "$sources_path" ]]
  315. then
  316. printf 1>&2 '%s\n' "Sources directory for project $project (with ${arguments:-no argument}) missing or empty"
  317. return 1
  318. else
  319. return 0
  320. fi
  321. }
  322. project_sources_archive() {
  323. local project=$1
  324. shift
  325. local sources_archive
  326. local argument
  327. local path="$root/$SOURCES/$project"
  328. for argument in "" "$@"
  329. do
  330. if [[ -n "$argument" ]]
  331. then
  332. path="$path-$argument"
  333. fi
  334. local archive="$path.$ARCHIVE"
  335. if ! [[ -f "$archive" ]]
  336. then
  337. continue
  338. fi
  339. sources_archive=$archive
  340. done
  341. if [[ -n "$sources_archive" ]]
  342. then
  343. printf '%s\n' "$sources_archive"
  344. fi
  345. }
  346. project_sources_archive_extract() {
  347. local project=$1
  348. shift
  349. local arguments="$*"
  350. local archive=$(project_sources_archive "$project" "$@")
  351. local destination=$(dirname "$archive")
  352. printf '%s\n' "Extracting source archive for $project (with ${arguments:-no argument})"
  353. file_verification_check "$archive"
  354. archive_extract "$archive" "$destination"
  355. }
  356. project_sources_archive_update() {
  357. local project=$1
  358. shift
  359. local arguments="$*"
  360. local repository=$project
  361. local sources_path=$(project_sources_path "$project" "$repository" "$@")
  362. local archive=$(project_sources_archive "$project" "$@")
  363. local destination=$(dirname "$archive")
  364. if [[ -d "$sources_path" ]]
  365. then
  366. rm -rf "$sources_path"
  367. fi
  368. printf '%s\n' "Extracting source archive for $project (with ${arguments:-no argument})"
  369. file_verification_check "$archive"
  370. archive_extract "$archive" "$destination"
  371. }
  372. project_sources_archive_missing_error() {
  373. local project=$1
  374. shift
  375. local arguments="$*"
  376. local archive=$(project_sources_archive "$project" "$@")
  377. if [[ -z "$archive" ]] || ! [[ -f "$archive" ]]
  378. then
  379. printf 1>&2 '%s\n' "Missing sources archive for $project (with ${arguments:-no argument})"
  380. return 1
  381. else
  382. return 0
  383. fi
  384. }
  385. project_sources_archive_missing_check() {
  386. local project=$1
  387. shift
  388. local archive=$(project_sources_archive "$project" "$@")
  389. if [[ -z "$archive" ]] || ! [[ -f "$archive" ]]
  390. then
  391. return 0
  392. else
  393. return 1
  394. fi
  395. }
  396. project_sources_prepare() {
  397. local project="$1"
  398. local sources_path="$2"
  399. # Not implemented yet / May end up not being needed
  400. #project_sources_prepare_blobs
  401. project_sources_prepare_patch "$project" "$sources_path" "$@"
  402. }
  403. project_sources_prepare_patch() {
  404. local project="$1"
  405. local sources_path="$2"
  406. local project_path="$(project_path "$project")"
  407. local patches_path="$project_path/$PATCHES"
  408. for patch in "$patches_path"/[!.]*.@(patch|diff); do
  409. diff_patch "$sources_path" "$patch"
  410. done
  411. }
  412. project_blobs_path() {
  413. local project=$1
  414. shift
  415. local project_path=$(project_path "$project")
  416. local configs_path="$project_path/$CONFIGS"
  417. local argument
  418. local path
  419. for argument in "" "$@"
  420. do
  421. if [[ -n "$argument" ]]
  422. then
  423. if [[ -z "$path" ]]
  424. then
  425. path="$argument"
  426. else
  427. path="$path/$argument"
  428. fi
  429. fi
  430. local blobs_path="$configs_path/$path/$BLOBS"
  431. if [[ -f "$blobs_path" ]]
  432. then
  433. printf '%s\n' "$blobs_path"
  434. return
  435. fi
  436. done
  437. printf '%s\n' "$blobs_path"
  438. }
  439. project_blobs_ignore_path() {
  440. local project=$1
  441. shift
  442. local project_path=$(project_path "$project")
  443. local configs_path="$project_path/$CONFIGS"
  444. local argument
  445. local path
  446. for argument in "" "$@"
  447. do
  448. if [[ -n "$argument" ]]
  449. then
  450. if [[ -z "$path" ]]
  451. then
  452. path="$argument"
  453. else
  454. path="$path/$argument"
  455. fi
  456. fi
  457. blobs_ignore_path="$configs_path/$path/$BLOBS_IGNORE"
  458. if [[ -f "$blobs_ignore_path" ]]
  459. then
  460. printf '%s\n' "$blobs_ignore_path"
  461. return
  462. fi
  463. done
  464. }
  465. project_arguments_targets() {
  466. local project=$1
  467. shift
  468. local project_path=$(project_path "$project")
  469. local targets_path="$project_path/$CONFIGS"
  470. local argument
  471. for argument in "$@"
  472. do
  473. targets_path="$targets_path/$argument"
  474. done
  475. targets_path="$targets_path/$TARGETS"
  476. if [[ -f "$targets_path" ]]
  477. then
  478. cat "$targets_path"
  479. fi
  480. }
  481. project_usage_actions() {
  482. local project="$1"
  483. shift
  484. printf '\n%s\n' 'Generic actions:'
  485. (
  486. for action in "${PROJECT_ACTIONS_GENERIC[@]}"; do
  487. if function_check "$action"; then
  488. printf '%s\n' " $action"
  489. fi
  490. done
  491. )
  492. if [[ "$#" -gt 0 ]]; then
  493. printf '\n%s\n' 'Specific actions:'
  494. (
  495. for action in "$@"; do
  496. printf '%s\n' " $action"
  497. done
  498. )
  499. fi
  500. }
  501. project_usage_arguments() {
  502. local project="$1"
  503. shift
  504. printf '\n%s\n' 'Arguments:'
  505. project_usage_arguments_recursive "$project" ' ' "$@"
  506. }
  507. project_usage_arguments_recursive() {
  508. local project="$1"
  509. shift
  510. local spacing="$1"
  511. shift
  512. local action_helper_arguments
  513. local argument
  514. action_helper_arguments="$(project_action_helper 'arguments' "$project" "$@")"
  515. if [[ -n "$action_helper_arguments" ]]; then
  516. for argument in $action_helper_arguments; do
  517. printf '%s\n' "$spacing$argument"
  518. project_usage_arguments_recursive "$project" " $spacing" "$@" "$argument"
  519. done
  520. fi
  521. }
  522. project_download_git() {
  523. local project=$1
  524. shift
  525. local repository=$1
  526. shift
  527. local urls=$1
  528. shift
  529. requirements "git"
  530. if ! git_project_check "$repository"
  531. then
  532. project_sources_directory_filled_error "$project" "$repository" "$@"
  533. git_project_clone "$repository" "$urls"
  534. fi
  535. git_project_prepare "$project" "$repository" "$@"
  536. }
  537. project_download_check_git() {
  538. local project=$1
  539. shift
  540. local repository=$1
  541. shift
  542. requirements "git"
  543. git_project_check "$repository"
  544. git_project_prepare_check "$project" "$repository" "$@"
  545. }
  546. project_download_archive() {
  547. local project="$1"
  548. shift
  549. local archive_uri="$1"
  550. shift
  551. local archive_dsig_uri="$1"
  552. local archive="${archive_uri##*/}"
  553. local compress_fmt="${archive##*.tar}"
  554. local directory_prefix="$root/$SOURCES"
  555. local archive_path="$root/$SOURCES/$archive"
  556. local sources_path="$root/$SOURCES/$project"
  557. if [[ "${compress_fmt#*.}" != "${ARCHIVE#*.}" ]]; then
  558. ARCHIVE="tar$compress_fmt"
  559. fi
  560. # TODO: Split this code block into separate functions
  561. # Archive verification will be included at that point in time
  562. if ! project_sources_directory_filled_check "$project"; then
  563. download_wrapper "$directory_prefix" "$archive_uri" "$archive_dsig_uri"
  564. archive_extract "$archive_path" "$directory_prefix"
  565. mv "${archive_path%.tar*}" "$sources_path"
  566. fi
  567. # Patch the source, if necessary
  568. project_sources_prepare "$project" "$sources_path"
  569. }
  570. project_download_check_archive() {
  571. local project="$1"
  572. local sources_path="$2"
  573. # TODO: Write the following function
  574. #project_sources_archive_extract_check "$project" "$sources_path"
  575. }
  576. project_extract() {
  577. local project=$1
  578. shift
  579. local repository=$project
  580. if ! project_sources_directory_filled_check "$project" "$repository" "$@"
  581. then
  582. project_sources_archive_missing_error "$project" "$@" || return 1
  583. project_sources_archive_extract "$project" "$@"
  584. fi
  585. }
  586. project_extract_check() {
  587. local project=$1
  588. shift
  589. local repository=$project
  590. project_sources_directory_filled_check "$project" "$repository" "$@"
  591. }
  592. project_update_git() {
  593. local project=$1
  594. shift
  595. local repository=$1
  596. shift
  597. requirements "git"
  598. project_sources_directory_missing_empty_error "$project" "$repository" "$@"
  599. if git_project_check "$repository"
  600. then
  601. git_project_update "$project" "$repository" "$@"
  602. else
  603. if ! project_sources_archive_missing_check "$project" "$@"
  604. then
  605. project_sources_archive_update "$project" "$@"
  606. fi
  607. fi
  608. }
  609. project_update_check_git() {
  610. local project=$1
  611. shift
  612. local repository=$1
  613. shift
  614. requirements "git"
  615. if ! git_project_check "$repository"
  616. then
  617. # Git repository should always be updated (even if upstream didn't progress).
  618. # For instance, this is useful for testing new versions of patches without changing revision.
  619. return 1
  620. else
  621. project_sources_archive_missing_check "$project" "$@"
  622. fi
  623. }
  624. project_build_check() {
  625. local project=$1
  626. shift
  627. local project_path=$(project_path "$project")
  628. local build_path=$(project_build_path "$project" "$@")
  629. local source_file_path
  630. local argument
  631. local rule
  632. local path
  633. for argument in "" "$@"
  634. do
  635. if [[ -n "$argument" ]]
  636. then
  637. if [[ -z "$path" ]]
  638. then
  639. path="$argument"
  640. else
  641. path="$path/$argument"
  642. fi
  643. fi
  644. configs_install_path="$project_path/$CONFIGS/$path/$INSTALL"
  645. if ! [[ -f "$configs_install_path" ]]
  646. then
  647. continue
  648. fi
  649. while read -r rule
  650. do
  651. source=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\1/g")
  652. source_path="$build_path/$source"
  653. # Source may contain a wildcard.
  654. path_wildcard_expand "$source_path" | while read -r source_file_path
  655. do
  656. if ! [[ -f "$source_file_path" ]] && ! [[ -d "$source_file_path" ]]
  657. then
  658. false
  659. fi
  660. done
  661. done < "$configs_install_path"
  662. done
  663. }
  664. project_build_path() {
  665. local project=$1
  666. shift
  667. local build_path="$root/$BUILD/$project"
  668. local argument
  669. for argument in "$@"
  670. do
  671. build_path="$build_path-$argument"
  672. done
  673. printf '%s\n' "$build_path"
  674. }
  675. project_build_directory_missing_empty_error() {
  676. local project=$1
  677. shift
  678. local arguments="$*"
  679. local build_path=$(project_build_path "$project" "$@")
  680. if ! directory_filled_check "$build_path"
  681. then
  682. printf 1>&2 '%s\n' "Build directory for project $project (with ${arguments:-no argument}) missing or empty"
  683. return 1
  684. else
  685. return 0
  686. fi
  687. }
  688. project_install() {
  689. local project=$1
  690. shift
  691. local project_path=$(project_path "$project")
  692. local build_path=$(project_build_path "$project" "$@")
  693. local install_path=$(project_install_path "$project" "$@")
  694. local source_file_path
  695. local argument
  696. local rule
  697. local path
  698. # Install built files first.
  699. for argument in "" "$@"
  700. do
  701. if [[ -n "$argument" ]]
  702. then
  703. if [[ -z "$path" ]]
  704. then
  705. path="$argument"
  706. else
  707. path="$path/$argument"
  708. fi
  709. fi
  710. configs_install_path="$project_path/$CONFIGS/$path/$INSTALL"
  711. if ! [[ -f "$configs_install_path" ]]
  712. then
  713. continue
  714. fi
  715. project_build_directory_missing_empty_error "$project" "$@"
  716. while read -r rule
  717. do
  718. source=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\1/g")
  719. source_path="$build_path/$source"
  720. destination=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\2/g")
  721. destination_path="$install_path/$destination"
  722. destination_directory_path=$(dirname "$destination_path")
  723. mkdir -p "$destination_directory_path"
  724. # Source may contain a wildcard.
  725. path_wildcard_expand "$source_path" | while read -r source_file_path
  726. do
  727. cp -rT "$source_file_path" "$destination_path"
  728. done
  729. done < "$configs_install_path"
  730. done
  731. path=""
  732. # Install install files then.
  733. for argument in "" "$@"
  734. do
  735. if [[ -n "$argument" ]]
  736. then
  737. if [[ -z "$path" ]]
  738. then
  739. path="$argument"
  740. else
  741. path="$path/$argument"
  742. fi
  743. fi
  744. install_install_path="$project_path/$INSTALL/$path/$INSTALL"
  745. if ! [[ -f "$install_install_path" ]]
  746. then
  747. continue
  748. fi
  749. while read -r rule
  750. do
  751. source=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\1/g")
  752. source_path="$project_path/$INSTALL/$path/$source"
  753. destination=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\2/g")
  754. destination_path="$install_path/$destination"
  755. destination_directory_path=$(dirname "$destination_path")
  756. mkdir -p "$destination_directory_path"
  757. # Source may contain a wildcard.
  758. path_wildcard_expand "$source_path" | while read -r source_file_path
  759. do
  760. cp -rT "$source_file_path" "$destination_path"
  761. done
  762. done < "$install_install_path"
  763. done
  764. }
  765. project_install_check() {
  766. local project=$1
  767. shift
  768. local project_path=$(project_path "$project")
  769. local build_path=$(project_build_path "$project" "$@")
  770. local install_path=$(project_install_path "$project" "$@")
  771. local argument
  772. local rule
  773. local path
  774. # Install built files first.
  775. for argument in "" "$@"
  776. do
  777. if [[ -n "$argument" ]]
  778. then
  779. if [[ -z "$path" ]]
  780. then
  781. path="$argument"
  782. else
  783. path="$path/$argument"
  784. fi
  785. fi
  786. configs_install_path="$project_path/$CONFIGS/$path/$INSTALL"
  787. if ! [[ -f "$configs_install_path" ]]
  788. then
  789. continue
  790. fi
  791. project_build_directory_missing_empty_error "$project" "$@"
  792. while read -r rule
  793. do
  794. destination=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\2/g")
  795. destination_path="$install_path/$destination"
  796. if ! [[ -f "$destination_path" ]] && ! [[ -d "$destination_path" ]]
  797. then
  798. false
  799. fi
  800. done < "$configs_install_path"
  801. done
  802. path=""
  803. # Install install files then.
  804. for argument in "" "$@"
  805. do
  806. if [[ -n "$argument" ]]
  807. then
  808. if [[ -z "$path" ]]
  809. then
  810. path="$argument"
  811. else
  812. path="$path/$argument"
  813. fi
  814. fi
  815. install_install_path="$project_path/$INSTALL/$path/$INSTALL"
  816. if ! [[ -f "$install_install_path" ]]
  817. then
  818. continue
  819. fi
  820. while read -r rule
  821. do
  822. destination=$(printf '%s\n' "$rule" | sed "s/$INSTALL_REGEX/\\2/g")
  823. destination_path="$install_path/$destination"
  824. if ! [[ -f "$destination_path" ]] && ! [[ -d "$destination_path" ]]
  825. then
  826. false
  827. fi
  828. done < "$install_install_path"
  829. done
  830. }
  831. project_install_path() {
  832. local project=$1
  833. shift
  834. local install_path="$root/$INSTALL/$project"
  835. local argument
  836. for argument in "$@"
  837. do
  838. install_path="$install_path-$argument"
  839. done
  840. printf '%s\n' "$install_path"
  841. }
  842. project_install_directory_missing_empty_error() {
  843. local project=$1
  844. shift
  845. local arguments="$*"
  846. local install_path=$(project_install_path "$project" "$@")
  847. if ! directory_filled_check "$install_path"
  848. then
  849. printf 1>&2 '%s\n' "Install directory for project $project (with ${arguments:-no argument}) missing or empty"
  850. return 1
  851. else
  852. return 0
  853. fi
  854. }
  855. project_release_path() {
  856. local project=$1
  857. shift
  858. local prefix=$1
  859. local release_path="$root/$RELEASE/$prefix"
  860. # Special care for tools and systems, that depend on the host arch.
  861. if [[ "$prefix" = "$SYSTEMS" ]] || [[ "$prefix" = "$TOOLS" ]]
  862. then
  863. local machine=$(uname -m)
  864. release_path="$release_path/$machine/$project"
  865. else
  866. release_path="$release_path/$project"
  867. fi
  868. printf '%s\n' "$release_path"
  869. }
  870. project_release_archive_path() {
  871. local project=$1
  872. shift
  873. local prefix=$1
  874. shift
  875. local release_path=$(project_release_path "$project" "$prefix")
  876. local argument
  877. local path="$project"
  878. for argument in "$@"
  879. do
  880. path="$path-$argument"
  881. done
  882. local archive_path="$release_path/$path.$ARCHIVE"
  883. printf '%s\n' "$archive_path"
  884. }
  885. project_release_rootfs_path() {
  886. local project=$1
  887. shift
  888. local prefix=$1
  889. shift
  890. local release_path=$(project_release_path "$project" "$prefix")
  891. local argument
  892. local path="$project"
  893. for argument in "$@"
  894. do
  895. path="$path-$argument"
  896. done
  897. local rootfs_path="$release_path/$path.$ARCHIVE"
  898. printf '%s\n' "$rootfs_path"
  899. }
  900. project_release_sources_archive_path() {
  901. local project=$1
  902. shift
  903. local repository="$project"
  904. local sources_path="$(project_sources_path "$project" "$repository" "$@")"
  905. local archive_path="$root/$RELEASE/$SOURCES/$project/${sources_path##*/}.$ARCHIVE"
  906. printf '%s\n' "$archive_path"
  907. }
  908. project_release_sources_archive_create() {
  909. local project=$1
  910. shift
  911. local arguments="$*"
  912. local repository=$project
  913. local archive_path=$(project_release_sources_archive_path "$project" "$@")
  914. local sources_path=$(project_sources_path "$project" "$repository" "$@")
  915. printf '%s\n' "Releasing sources archive for $project (with ${arguments:-no argument})"
  916. archive_create "$archive_path" "$sources_path"
  917. file_verification_create "$archive_path"
  918. }
  919. project_release_sources_archive_exists_check() {
  920. local project=$1
  921. shift
  922. local archive_path=$(project_release_sources_archive_path "$project" "$@")
  923. if [[ -z "$archive_path" ]] || ! [[ -f "$archive_path" ]]
  924. then
  925. return 1
  926. else
  927. return 0
  928. fi
  929. }
  930. project_release_sources_git() {
  931. local project=$1
  932. shift
  933. local repository=$1
  934. shift
  935. requirements "git"
  936. project_sources_directory_missing_empty_error "$project" "$repository" "$@"
  937. if git_project_check "$repository"
  938. then
  939. if ! git_project_release_check "$project" "$repository" "$@"
  940. then
  941. git_project_release "$project" "$repository" "$@"
  942. fi
  943. else
  944. if ! project_release_sources_archive_exists_check "$project" "$@"
  945. then
  946. project_release_sources_archive_create "$project" "$@"
  947. fi
  948. fi
  949. }
  950. project_release_check_sources_git() {
  951. local project=$1
  952. shift
  953. local repository=$1
  954. shift
  955. requirements "git"
  956. if git_project_check "$repository"
  957. then
  958. git_project_release_check "$project" "$repository" "$@"
  959. else
  960. project_release_sources_archive_exists_check "$project" "$@"
  961. fi
  962. }
  963. project_release_install() {
  964. local project=$1
  965. shift
  966. local prefix=$1
  967. shift
  968. local install_path=$(project_install_path "$project" "$@")
  969. local release_path=$(project_release_path "$project" "$prefix")
  970. local directory_path
  971. local path
  972. project_install_directory_missing_empty_error "$project" "$@"
  973. local files=$(find "$install_path" -type f || true)
  974. local file
  975. printf '%s\n' "$files" | while read -r file
  976. do
  977. path="$release_path/$file"
  978. directory_path=$(dirname "$path")
  979. mkdir -p "$directory_path"
  980. cp "$install_path/$file" "$path"
  981. file_verification_create "$path"
  982. done
  983. }
  984. project_release_install_check() {
  985. local project=$1
  986. shift
  987. local prefix=$1
  988. shift
  989. local install_path=$(project_install_path "$project" "$@")
  990. local release_path=$(project_release_path "$project" "$prefix")
  991. local path
  992. project_install_directory_missing_empty_error "$project" "$@"
  993. local files=$(find "$install_path" -type f || true)
  994. local file
  995. printf '%s\n' "$files" | while read -r file
  996. do
  997. path="$release_path/$file"
  998. file_exists_check "$path"
  999. done
  1000. }
  1001. project_release_install_archive() {
  1002. local project=$1
  1003. shift
  1004. local prefix=$1
  1005. shift
  1006. project_install_directory_missing_empty_error "$project" "$@"
  1007. project_release_install_archive_create "$project" "$prefix" "$@"
  1008. }
  1009. project_release_install_archive_check() {
  1010. local project=$1
  1011. shift
  1012. project_release_install_archive_exists_check "$project" "$@"
  1013. }
  1014. project_release_install_archive_create() {
  1015. local project=$1
  1016. shift
  1017. local prefix=$1
  1018. shift
  1019. local arguments="$*"
  1020. local install_path=$(project_install_path "$project" "$@")
  1021. local archive_path=$(project_release_archive_path "$project" "$prefix" "$@")
  1022. printf '%s\n' "Releasing $prefix archive for $project (with ${arguments:-no argument})"
  1023. archive_create "$archive_path" "$install_path"
  1024. file_verification_create "$archive_path"
  1025. }
  1026. project_release_install_archive_exists_check() {
  1027. local project=$1
  1028. shift
  1029. local prefix=$1
  1030. shift
  1031. local archive_path=$(project_release_archive_path "$project" "$prefix" "$@")
  1032. file_exists_check "$archive_path"
  1033. }
  1034. project_release_install_rootfs() {
  1035. local project=$1
  1036. shift
  1037. local prefix=$1
  1038. shift
  1039. project_install_directory_missing_empty_error "$project" "$@"
  1040. if ! project_release_install_rootfs_exists_check "$project" "$prefix" "$@"
  1041. then
  1042. project_release_install_rootfs_create "$project" "$prefix" "$@"
  1043. fi
  1044. }
  1045. project_release_install_rootfs_check() {
  1046. local project=$1
  1047. shift
  1048. project_release_install_rootfs_exists_check "$project" "$@"
  1049. }
  1050. project_release_install_rootfs_create() {
  1051. local project=$1
  1052. shift
  1053. local prefix=$1
  1054. shift
  1055. local arguments="$*"
  1056. local install_path=$(project_install_path "$project" "$@")
  1057. local rootfs_path=$(project_release_rootfs_path "$project" "$prefix" "$@")
  1058. printf '%s\n' "Releasing $prefix rootfs for $project (with ${arguments:-no argument})"
  1059. rootfs_create "$rootfs_path" "$install_path"
  1060. file_verification_create "$rootfs_path"
  1061. }
  1062. project_release_install_rootfs_exists_check() {
  1063. local project=$1
  1064. shift
  1065. local prefix=$1
  1066. shift
  1067. local rootfs_path=$(project_release_rootfs_path "$project" "$prefix" "$@")
  1068. file_exists_check "$rootfs_path"
  1069. }
  1070. project_clean() {
  1071. local project=$1
  1072. shift
  1073. project_clean_build "$project" "$@"
  1074. project_clean_install "$project" "$@"
  1075. project_clean_release "$project" "$@"
  1076. }
  1077. project_clean_build() {
  1078. local project=$1
  1079. shift
  1080. local build_path=$(project_build_path "$project" "$@")
  1081. rm -rf "$build_path"
  1082. }
  1083. project_clean_install() {
  1084. local project=$1
  1085. shift
  1086. local install_path=$(project_install_path "$project" "$@")
  1087. rm -rf "$install_path"
  1088. }
  1089. project_clean_release() {
  1090. local project=$1
  1091. shift
  1092. local prefix
  1093. for prefix in "$SOURCES" "$SYSTEMS" "$IMAGES" "$TOOLS" "$DOCS"
  1094. do
  1095. local release_path=$(project_release_path "$project" "$prefix")
  1096. rm -rf "$release_path"
  1097. done
  1098. }
  1099. project_clean_rootfs() {
  1100. local project=$1
  1101. shift
  1102. project_clean_build "$project" "$@"
  1103. project_clean_rootfs_install "$project" "$@"
  1104. project_clean_release "$project" "$@"
  1105. }
  1106. project_clean_rootfs_install() {
  1107. local project=$1
  1108. shift
  1109. local install_path=$(project_install_path "$project" "$@")
  1110. execute_root rm -rf "$install_path"
  1111. }
  1112. project_file_path() {
  1113. local project=$1
  1114. shift
  1115. local directory=$1
  1116. shift
  1117. local file=$1
  1118. shift
  1119. local project_path=$(project_path "$project")
  1120. local path="$project_path/$directory"
  1121. local argument
  1122. local file_path
  1123. for argument in "" "$@"
  1124. do
  1125. if [[ -n "$argument" ]]
  1126. then
  1127. path="$path/$argument"
  1128. fi
  1129. if ! [[ -f "$path/$file" ]]
  1130. then
  1131. continue
  1132. fi
  1133. file_path="$path/$file"
  1134. break
  1135. done
  1136. if [[ -z "$file_path" ]]
  1137. then
  1138. return 1
  1139. fi
  1140. printf '%s\n' "$file_path"
  1141. }
  1142. project_file_test() {
  1143. local file_path=$(project_file_path "$@")
  1144. test -f "$file_path"
  1145. }
  1146. project_file_contents() {
  1147. local file_path=$(project_file_path "$@")
  1148. if [[ -f "$file_path" ]]
  1149. then
  1150. cat "$file_path"
  1151. fi
  1152. }
  1153. project_file_contents_herit() {
  1154. local project=$1
  1155. shift
  1156. local directory=$1
  1157. shift
  1158. local file=$1
  1159. shift
  1160. local project_path=$(project_path "$project")
  1161. local path="$project_path/$directory"
  1162. local argument
  1163. local file_path
  1164. for argument in "" "$@"
  1165. do
  1166. if [[ -n "$argument" ]]
  1167. then
  1168. path="$path/$argument"
  1169. fi
  1170. file_path="$path/$file"
  1171. if ! [[ -f "$file_path" ]]
  1172. then
  1173. continue
  1174. fi
  1175. cat "$file_path"
  1176. done
  1177. }