project 28 KB

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