project 28 KB

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