project 28 KB

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