musare.sh 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. #!/bin/bash
  2. set -e
  3. export PATH=/usr/local/bin:/usr/bin:/bin
  4. # Color variables
  5. CYAN='\033[33;36m';
  6. RED='\033[0;31m'
  7. YELLOW='\033[0;93m'
  8. GREEN='\033[0;32m'
  9. NC='\033[0m'
  10. # Print provided formatted error and exit with code (default 1)
  11. throw()
  12. {
  13. echo -e "${RED}${1}${NC}"
  14. exit "${2:-1}"
  15. }
  16. # Navigate to repository
  17. scriptLocation=$(dirname -- "$(readlink -fn -- "$0"; echo x)")
  18. cd "${scriptLocation%x}"
  19. # Import environment variables
  20. if [[ ! -f .env ]]; then
  21. throw "Error: .env does not exist" 2
  22. fi
  23. # shellcheck disable=SC1091
  24. source .env
  25. # Define docker command
  26. docker="${DOCKER_COMMAND:-docker}"
  27. if [[ ${docker} != "docker" && ${docker} != "podman" ]]; then
  28. throw "Error: Invalid DOCKER_COMMAND"
  29. fi
  30. set +e
  31. # Check if docker is installed
  32. ${docker} --version > /dev/null 2>&1
  33. dockerInstalled=$?
  34. # Define docker compose command
  35. dockerCompose="${docker} compose"
  36. # Check if docker compose is installed
  37. ${dockerCompose} version > /dev/null 2>&1
  38. composeInstalled=$?
  39. if [[ ${composeInstalled} -gt 0 ]]; then
  40. dockerCompose="${docker}-compose"
  41. ${dockerCompose} --version > /dev/null 2>&1
  42. composeInstalled=$?
  43. fi
  44. set -e
  45. # Exit if docker and/or docker compose is not installed
  46. if [[ ${dockerInstalled} -gt 0 || ${composeInstalled} -gt 0 ]]; then
  47. if [[ ${dockerInstalled} -eq 0 && ${composeInstalled} -gt 0 ]]; then
  48. throw "Error: ${dockerCompose} not installed."
  49. fi
  50. if [[ ${dockerInstalled} -gt 0 && ${composeInstalled} -eq 0 ]]; then
  51. throw "Error: ${docker} not installed."
  52. fi
  53. throw "Error: ${docker} and ${dockerCompose} not installed."
  54. fi
  55. # Add docker compose file arguments to command
  56. composeFiles="-f docker-compose.yml"
  57. if [[ ${APP_ENV} == "development" ]]; then
  58. composeFiles="${composeFiles} -f docker-compose.dev.yml"
  59. fi
  60. if [[ ${CONTAINER_MODE} == "local" ]]; then
  61. composeFiles="${composeFiles} -f docker-compose.local.yml"
  62. fi
  63. if [[ -f docker-compose.override.yml ]]; then
  64. composeFiles="${composeFiles} -f docker-compose.override.yml"
  65. fi
  66. dockerCompose="${dockerCompose} ${composeFiles}"
  67. # Parse services from arguments string
  68. handleServices()
  69. {
  70. # shellcheck disable=SC2206
  71. validServices=($1)
  72. servicesArray=()
  73. invalidServices=false
  74. for x in "${@:2}"; do
  75. if [[ ${validServices[*]} =~ (^|[[:space:]])"$x"($|[[:space:]]) ]]; then
  76. if ! [[ ${servicesArray[*]} =~ (^|[[:space:]])"$x"($|[[:space:]]) ]]; then
  77. servicesArray+=("${x}")
  78. fi
  79. else
  80. if [[ $invalidServices == false ]]; then
  81. invalidServices="${x}"
  82. else
  83. invalidServices="${invalidServices} ${x}"
  84. fi
  85. fi
  86. done
  87. if [[ $invalidServices == false && ${#servicesArray[@]} -gt 0 ]]; then
  88. echo "1|${servicesArray[*]}"
  89. elif [[ $invalidServices == false ]]; then
  90. echo "1|all"
  91. else
  92. echo "0|Invalid Service(s): ${invalidServices}"
  93. fi
  94. }
  95. # Execute a docker command
  96. runDockerCommand()
  97. {
  98. validCommands=(start stop restart pull build ps logs)
  99. if ! [[ ${validCommands[*]} =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; then
  100. throw "Error: Invalid runDockerCommand input"
  101. fi
  102. servicesString=$(handleServices "backend frontend mongo redis" "${@:3}")
  103. if [[ ${servicesString:0:1} != 1 ]]; then
  104. throw "${servicesString:2}\n${YELLOW}Usage: ${1} [backend, frontend, mongo, redis]"
  105. fi
  106. if [[ ${servicesString:2:4} == "all" ]]; then
  107. servicesString=""
  108. pullServices="mongo redis"
  109. buildServices="backend frontend"
  110. else
  111. servicesString=${servicesString:2}
  112. pullArray=()
  113. buildArray=()
  114. if [[ "${servicesString}" == *mongo* ]]; then
  115. pullArray+=("mongo")
  116. fi
  117. if [[ "${servicesString}" == *redis* ]]; then
  118. pullArray+=("redis")
  119. fi
  120. if [[ "${servicesString}" == *backend* ]]; then
  121. buildArray+=("backend")
  122. fi
  123. if [[ "${servicesString}" == *frontend* ]]; then
  124. buildArray+=("frontend")
  125. fi
  126. pullServices="${pullArray[*]}"
  127. buildServices="${buildArray[*]}"
  128. fi
  129. if [[ ${2} == "stop" || ${2} == "restart" ]]; then
  130. # shellcheck disable=SC2086
  131. ${dockerCompose} stop ${servicesString}
  132. fi
  133. if [[ ${2} == "start" || ${2} == "restart" ]]; then
  134. # shellcheck disable=SC2086
  135. ${dockerCompose} up -d ${servicesString}
  136. fi
  137. if [[ ${2} == "pull" && ${pullServices} != "" ]]; then
  138. # shellcheck disable=SC2086
  139. ${dockerCompose} pull ${pullServices}
  140. fi
  141. if [[ ${2} == "build" && ${buildServices} != "" ]]; then
  142. # shellcheck disable=SC2086
  143. ${dockerCompose} build ${buildServices}
  144. fi
  145. if [[ ${2} == "ps" || ${2} == "logs" ]]; then
  146. # shellcheck disable=SC2086
  147. ${dockerCompose} "${2}" ${servicesString}
  148. fi
  149. }
  150. # Get docker container id
  151. getContainerId()
  152. {
  153. if [[ $docker == "docker" ]]; then
  154. containerId=$(${dockerCompose} ps -q "${1}")
  155. else
  156. containerId=$(${dockerCompose} ps \
  157. | sed '0,/CONTAINER/d' \
  158. | awk "/${1}/ {print \$1;exit}")
  159. fi
  160. echo "${containerId}"
  161. }
  162. # Reset services
  163. handleReset()
  164. {
  165. servicesString=$(handleServices "backend frontend mongo redis" "${@:2}")
  166. if [[ ${servicesString:0:1} != 1 ]]; then
  167. throw "${servicesString:2}\n${YELLOW}Usage: ${1} [backend, frontend, mongo, redis]"
  168. fi
  169. confirmMessage="${GREEN}Are you sure you want to reset all data"
  170. if [[ ${servicesString:2:4} != "all" ]]; then
  171. confirmMessage="${confirmMessage} for $(echo "${servicesString:2}" | tr ' ' ',')"
  172. fi
  173. echo -e "${confirmMessage}? ${YELLOW}[y,n]: ${NC}"
  174. read -r confirm
  175. if [[ "${confirm}" != y* ]]; then
  176. throw "Cancelled reset"
  177. fi
  178. if [[ ${servicesString:2:4} == "all" ]]; then
  179. runDockerCommand "$(basename "$0") $1" stop
  180. ${dockerCompose} rm -v --force
  181. else
  182. # shellcheck disable=SC2086
  183. runDockerCommand "$(basename "$0") $1" stop ${servicesString:2}
  184. # shellcheck disable=SC2086
  185. ${dockerCompose} rm -v --force ${servicesString:2}
  186. fi
  187. }
  188. # Attach to service in docker container
  189. attachContainer()
  190. {
  191. containerId=$(getContainerId "${2}")
  192. if [[ -z $containerId ]]; then
  193. throw "Error: ${2} offline, please start to attach."
  194. fi
  195. case $2 in
  196. backend)
  197. echo -e "${YELLOW}Detach with CTRL+P+Q${NC}"
  198. ${docker} attach "$containerId"
  199. ;;
  200. mongo)
  201. MONGO_VERSION_INT=${MONGO_VERSION:0:1}
  202. echo -e "${YELLOW}Detach with CTRL+D${NC}"
  203. if [[ $MONGO_VERSION_INT -ge 5 ]]; then
  204. ${dockerCompose} exec mongo mongosh musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "disableTelemetry()" --shell
  205. else
  206. ${dockerCompose} exec mongo mongo musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}"
  207. fi
  208. ;;
  209. redis)
  210. echo -e "${YELLOW}Detach with CTRL+C${NC}"
  211. ${dockerCompose} exec redis redis-cli -a "${REDIS_PASSWORD}"
  212. ;;
  213. *)
  214. throw "Invalid service ${2}\n${YELLOW}Usage: ${1} [backend, mongo, redis]"
  215. ;;
  216. esac
  217. }
  218. # Lint codebase, docs, scripts, etc
  219. handleLinting()
  220. {
  221. set +e
  222. # shellcheck disable=SC2001
  223. services=$(sed "s/\(\ \)\{0,1\}\(-\)\{0,2\}fix//g;t;q1" <<< "${@:2}")
  224. fixFound=$?
  225. if [[ $fixFound -eq 0 ]]; then
  226. fix="--fix"
  227. echo -e "${GREEN}Auto-fix enabled${NC}"
  228. fi
  229. # shellcheck disable=SC2001
  230. services=$(sed "s/\(\ \)\{0,1\}\(-\)\{0,2\}no-cache//g;t;q1" <<< "${services}")
  231. noCacheFound=$?
  232. cache="--cache"
  233. if [[ $noCacheFound -eq 0 ]]; then
  234. cache=""
  235. echo -e "${YELLOW}ESlint cache disabled${NC}"
  236. fi
  237. set -e
  238. # shellcheck disable=SC2068
  239. servicesString=$(handleServices "backend frontend docs shell" ${services[@]})
  240. if [[ ${servicesString:0:1} != 1 ]]; then
  241. throw "${servicesString:2}\n${YELLOW}Usage: ${1} [backend, frontend, docs, shell] [fix]"
  242. fi
  243. set +e
  244. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  245. echo -e "${CYAN}Running frontend lint...${NC}"
  246. # shellcheck disable=SC2086
  247. ${dockerCompose} exec -T frontend npm run lint -- ${cache} ${fix}
  248. frontendExitValue=$?
  249. fi
  250. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *backend* ]]; then
  251. echo -e "${CYAN}Running backend lint...${NC}"
  252. # shellcheck disable=SC2086
  253. ${dockerCompose} exec -T backend npm run lint -- ${cache} ${fix}
  254. backendExitValue=$?
  255. fi
  256. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *docs* ]]; then
  257. echo -e "${CYAN}Running docs lint...${NC}"
  258. # shellcheck disable=SC2086
  259. ${docker} run --rm -v "${scriptLocation}":/workdir ghcr.io/igorshubovych/markdownlint-cli:latest ".wiki" "*.md" ${fix}
  260. docsExitValue=$?
  261. fi
  262. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *shell* ]]; then
  263. echo -e "${CYAN}Running shell lint...${NC}"
  264. ${docker} run --rm -v "${scriptLocation}":/mnt koalaman/shellcheck:stable ./*.sh ./**/*.sh
  265. shellExitValue=$?
  266. fi
  267. set -e
  268. if [[ ${frontendExitValue} -gt 0 || ${backendExitValue} -gt 0 || ${docsExitValue} -gt 0 || ${shellExitValue} -gt 0 ]]; then
  269. exit 1
  270. fi
  271. }
  272. # Validate typescript in services
  273. handleTypescript()
  274. {
  275. set +e
  276. # shellcheck disable=SC2001
  277. services=$(sed "s/\(\ \)\{0,1\}\(-\)\{0,2\}strict//g;t;q1" <<< "${@:2}")
  278. strictFound=$?
  279. if [[ $strictFound -eq 0 ]]; then
  280. strict="--strict"
  281. echo -e "${GREEN}Strict mode enabled${NC}"
  282. fi
  283. set -e
  284. # shellcheck disable=SC2068
  285. servicesString=$(handleServices "backend frontend" ${services[@]})
  286. if [[ ${servicesString:0:1} != 1 ]]; then
  287. throw "${servicesString:2}\n${YELLOW}Usage: ${1} [backend, frontend] [strict]"
  288. fi
  289. set +e
  290. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  291. echo -e "${CYAN}Running frontend typescript check...${NC}"
  292. # shellcheck disable=SC2086
  293. ${dockerCompose} exec -T frontend npm run typescript -- ${strict}
  294. frontendExitValue=$?
  295. fi
  296. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *backend* ]]; then
  297. echo -e "${CYAN}Running backend typescript check...${NC}"
  298. # shellcheck disable=SC2086
  299. ${dockerCompose} exec -T backend npm run typescript -- ${strict}
  300. backendExitValue=$?
  301. fi
  302. set -e
  303. if [[ ${frontendExitValue} -gt 0 || ${backendExitValue} -gt 0 ]]; then
  304. exit 1
  305. fi
  306. }
  307. # Execute automated tests in services
  308. handleTests()
  309. {
  310. servicesString=$(handleServices "backend frontend" "${@:2}")
  311. if [[ ${servicesString:0:1} != 1 ]]; then
  312. throw "${servicesString:2}\n${YELLOW}Usage: ${1} [backend, frontend]"
  313. fi
  314. set +e
  315. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *backend* ]]; then
  316. echo -e "${CYAN}Running backend tests...${NC}"
  317. ${dockerCompose} exec -T backend npm run test
  318. backendExitValue=$?
  319. fi
  320. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  321. echo -e "${CYAN}Running frontend tests...${NC}"
  322. ${dockerCompose} exec -T frontend npm run test -- --run
  323. frontendExitValue=$?
  324. fi
  325. set -e
  326. if [[ ${backendExitValue} -gt 0 || ${frontendExitValue} -gt 0 ]]; then
  327. exit 1
  328. fi
  329. }
  330. # Execute test coverage in services
  331. handleTestCoverage()
  332. {
  333. servicesString=$(handleServices "frontend" "${@:2}")
  334. if [[ ${servicesString:0:1} != 1 ]]; then
  335. throw "${servicesString:2}\n${YELLOW}Usage: ${1} [frontend]"
  336. fi
  337. set +e
  338. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  339. echo -e "${CYAN}Running frontend test coverage report...${NC}"
  340. ${dockerCompose} exec -T frontend npm run coverage
  341. frontendExitValue=$?
  342. fi
  343. set -e
  344. if [[ ${frontendExitValue} -gt 0 ]]; then
  345. exit 1
  346. fi
  347. }
  348. # Update Musare
  349. handleUpdate()
  350. {
  351. musareshModified=$(git diff HEAD -- musare.sh)
  352. git fetch
  353. updated=$(git log --name-only --oneline HEAD..@\{u\})
  354. if [[ ${updated} == "" ]]; then
  355. echo -e "${GREEN}Already up to date${NC}"
  356. exit 0
  357. fi
  358. breakingConfigChange=$(git rev-list "$(git rev-parse HEAD)" | grep d8b73be1de231821db34c677110b7b97e413451f)
  359. if [[ -f backend/config/default.json && -z $breakingConfigChange ]]; then
  360. throw "Configuration has breaking changes. Please rename or remove 'backend/config/default.json' and run the update command again to continue."
  361. fi
  362. musareshChange=$(echo "${updated}" | grep "musare.sh")
  363. dbChange=$(echo "${updated}" | grep "backend/logic/db/schemas")
  364. bcChange=$(echo "${updated}" | grep "backend/config/default.json")
  365. if [[ ( $2 == "auto" && -z $dbChange && -z $bcChange && -z $musareshChange ) || -z $2 ]]; then
  366. if [[ -n $musareshChange && $(git diff @\{u\} -- musare.sh) != "" ]]; then
  367. if [[ $musareshModified != "" ]]; then
  368. throw "musare.sh has been modified, please reset these changes and run the update command again to continue."
  369. else
  370. git checkout @\{u\} -- musare.sh
  371. throw "${YELLOW}musare.sh has been updated, please run the update command again to continue."
  372. fi
  373. else
  374. git pull
  375. echo -e "${CYAN}Updating...${NC}"
  376. runDockerCommand "$(basename "$0") $1" pull
  377. runDockerCommand "$(basename "$0") $1" build
  378. runDockerCommand "$(basename "$0") $1" restart
  379. echo -e "${GREEN}Updated!${NC}"
  380. if [[ -n $dbChange ]]; then
  381. echo -e "${RED}Database schema has changed, please run migration!${NC}"
  382. fi
  383. if [[ -n $bcChange ]]; then
  384. echo -e "${RED}Backend config has changed, please update!${NC}"
  385. fi
  386. fi
  387. elif [[ $2 == "auto" ]]; then
  388. throw "Auto Update Failed! musare.sh, database and/or config has changed!"
  389. fi
  390. }
  391. # Backup the database
  392. handleBackup()
  393. {
  394. if [[ -z "${BACKUP_LOCATION}" ]]; then
  395. backupLocation="${scriptLocation%x}/backups"
  396. else
  397. backupLocation="${BACKUP_LOCATION%/}"
  398. fi
  399. if [[ ! -d "${backupLocation}" ]]; then
  400. echo -e "${YELLOW}Creating backup directory at ${backupLocation}${NC}"
  401. mkdir "${backupLocation}"
  402. fi
  403. if [[ -z "${BACKUP_NAME}" ]]; then
  404. backupLocation="${backupLocation}/musare-$(date +"%Y-%m-%d-%s").dump"
  405. else
  406. backupLocation="${backupLocation}/${BACKUP_NAME}"
  407. fi
  408. echo -e "${YELLOW}Creating backup at ${backupLocation}${NC}"
  409. ${dockerCompose} exec -T mongo sh -c "mongodump --authenticationDatabase musare -u ${MONGO_USER_USERNAME} -p ${MONGO_USER_PASSWORD} -d musare --archive" > "${backupLocation}"
  410. }
  411. # Restore database from dump
  412. handleRestore()
  413. {
  414. if [[ -z $2 ]]; then
  415. echo -e "${GREEN}Please enter the full path of the dump you wish to restore: ${NC}"
  416. read -r restoreFile
  417. else
  418. restoreFile=$2
  419. fi
  420. if [[ -z ${restoreFile} ]]; then
  421. throw "Error: no restore path given, cancelled restoration."
  422. elif [[ -d ${restoreFile} ]]; then
  423. throw "Error: restore path given is a directory, cancelled restoration."
  424. elif [[ ! -f ${restoreFile} ]]; then
  425. throw "Error: no file at restore path given, cancelled restoration."
  426. else
  427. ${dockerCompose} exec -T mongo sh -c "mongorestore --authenticationDatabase musare -u ${MONGO_USER_USERNAME} -p ${MONGO_USER_PASSWORD} --archive" < "${restoreFile}"
  428. fi
  429. }
  430. # Toggle user admin role
  431. handleAdmin()
  432. {
  433. MONGO_VERSION_INT=${MONGO_VERSION:0:1}
  434. case $2 in
  435. add)
  436. if [[ -z $3 ]]; then
  437. echo -e "${GREEN}Please enter the username of the user you wish to make an admin: ${NC}"
  438. read -r adminUser
  439. else
  440. adminUser=$3
  441. fi
  442. if [[ -z $adminUser ]]; then
  443. throw "Error: Username for new admin not provided."
  444. fi
  445. if [[ $MONGO_VERSION_INT -ge 5 ]]; then
  446. ${dockerCompose} exec mongo mongosh musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "disableTelemetry(); db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'admin'}})"
  447. else
  448. ${dockerCompose} exec mongo mongo musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'admin'}})"
  449. fi
  450. ;;
  451. remove)
  452. if [[ -z $3 ]]; then
  453. echo -e "${GREEN}Please enter the username of the user you wish to remove as admin: ${NC}"
  454. read -r adminUser
  455. else
  456. adminUser=$3
  457. fi
  458. if [[ -z $adminUser ]]; then
  459. throw "Error: Username for new admin not provided."
  460. fi
  461. if [[ $MONGO_VERSION_INT -ge 5 ]]; then
  462. ${dockerCompose} exec mongo mongosh musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "disableTelemetry(); db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'default'}})"
  463. else
  464. ${dockerCompose} exec mongo mongo musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'default'}})"
  465. fi
  466. ;;
  467. *)
  468. throw "Invalid command $2\n${YELLOW}Usage: ${1} [add,remove] username"
  469. ;;
  470. esac
  471. }
  472. availableCommands=$(cat << COMMANDS
  473. start - Start services
  474. stop - Stop services
  475. restart - Restart services
  476. status - Service status
  477. logs - View logs for services
  478. update - Update Musare
  479. attach [backend,mongo,redis] - Attach to backend service, mongo or redis shell
  480. build - Build services
  481. lint - Run lint on frontend, backend, docs and/or shell
  482. backup - Backup database data to file
  483. restore - Restore database data from backup file
  484. reset - Reset service data
  485. admin [add,remove] - Assign/unassign admin role to/from a user
  486. typescript - Run typescript checks on frontend and/or backend
  487. COMMANDS
  488. )
  489. # Handle command
  490. case $1 in
  491. start)
  492. echo -e "${CYAN}Musare | Start Services${NC}"
  493. # shellcheck disable=SC2068
  494. runDockerCommand "$(basename "$0") $1" start ${@:2}
  495. ;;
  496. stop)
  497. echo -e "${CYAN}Musare | Stop Services${NC}"
  498. # shellcheck disable=SC2068
  499. runDockerCommand "$(basename "$0") $1" stop ${@:2}
  500. ;;
  501. restart)
  502. echo -e "${CYAN}Musare | Restart Services${NC}"
  503. # shellcheck disable=SC2068
  504. runDockerCommand "$(basename "$0") $1" restart ${@:2}
  505. ;;
  506. build)
  507. echo -e "${CYAN}Musare | Build Services${NC}"
  508. # shellcheck disable=SC2068
  509. runDockerCommand "$(basename "$0") $1" pull ${@:2}
  510. # shellcheck disable=SC2068
  511. runDockerCommand "$(basename "$0") $1" build ${@:2}
  512. ;;
  513. status)
  514. echo -e "${CYAN}Musare | Service Status${NC}"
  515. # shellcheck disable=SC2068
  516. runDockerCommand "$(basename "$0") $1" ps ${@:2}
  517. ;;
  518. reset)
  519. echo -e "${CYAN}Musare | Reset Services${NC}"
  520. # shellcheck disable=SC2068
  521. handleReset "$(basename "$0") $1" ${@:2}
  522. ;;
  523. attach)
  524. echo -e "${CYAN}Musare | Attach${NC}"
  525. attachContainer "$(basename "$0") $1" "$2"
  526. ;;
  527. lint|eslint)
  528. echo -e "${CYAN}Musare | Lint${NC}"
  529. # shellcheck disable=SC2068
  530. handleLinting "$(basename "$0") $1" ${@:2}
  531. ;;
  532. typescript|ts)
  533. echo -e "${CYAN}Musare | TypeScript Check${NC}"
  534. # shellcheck disable=SC2068
  535. handleTypescript "$(basename "$0") $1" ${@:2}
  536. ;;
  537. test)
  538. echo -e "${CYAN}Musare | Test${NC}"
  539. # shellcheck disable=SC2068
  540. handleTests "$(basename "$0") $1" ${@:2}
  541. ;;
  542. test:coverage)
  543. echo -e "${CYAN}Musare | Test Coverage${NC}"
  544. # shellcheck disable=SC2068
  545. handleTestCoverage "$(basename "$0") $1" ${@:2}
  546. ;;
  547. update)
  548. echo -e "${CYAN}Musare | Update${NC}"
  549. # shellcheck disable=SC2068
  550. handleUpdate "$(basename "$0") $1" ${@:2}
  551. ;;
  552. logs)
  553. echo -e "${CYAN}Musare | Logs${NC}"
  554. # shellcheck disable=SC2068
  555. runDockerCommand "$(basename "$0") $1" logs ${@:2}
  556. ;;
  557. backup)
  558. echo -e "${CYAN}Musare | Backup${NC}"
  559. # shellcheck disable=SC2068
  560. handleBackup "$(basename "$0") $1" ${@:2}
  561. ;;
  562. restore)
  563. echo -e "${CYAN}Musare | Restore${NC}"
  564. # shellcheck disable=SC2068
  565. handleRestore "$(basename "$0") $1" ${@:2}
  566. ;;
  567. admin)
  568. echo -e "${CYAN}Musare | Add Admin${NC}"
  569. # shellcheck disable=SC2068
  570. handleAdmin "$(basename "$0") $1" ${@:2}
  571. ;;
  572. "")
  573. echo -e "${CYAN}Musare | Available Commands${NC}"
  574. echo -e "${YELLOW}${availableCommands}${NC}"
  575. ;;
  576. *)
  577. echo -e "${CYAN}Musare${NC}"
  578. echo -e "${RED}Error: Invalid Command $1${NC}"
  579. echo -e "${CYAN}Available Commands:${NC}"
  580. echo -e "${YELLOW}${availableCommands}${NC}"
  581. exit 1
  582. ;;
  583. esac