From ae9931f4ed57586c8a526bd334055ef7fa8a394c Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Wed, 10 Jan 2024 19:56:43 -0800 Subject: [PATCH] Update Setup --- README.md | 6 +- Scripts/create.sh | 178 +++++++++++++++++- TemplateApplication.xcodeproj/project.pbxproj | 16 +- .../TemplateApplication.docc/Create.md | 2 +- .../TemplateApplication.docc/Modify.md | 2 +- ...wift => TemplateApplicationDelegate.swift} | 0 ... => TemplateApplicationTestingSetup.swift} | 0 7 files changed, 185 insertions(+), 19 deletions(-) rename TemplateApplication/{TemplateAppDelegate.swift => TemplateApplicationDelegate.swift} (100%) rename TemplateApplication/{TemplateAppTestingSetup.swift => TemplateApplicationTestingSetup.swift} (100%) diff --git a/README.md b/README.md index b88bdffb..e7eb5c52 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ SPDX-License-Identifier: MIT [![DOI](https://zenodo.org/badge/589846478.svg)](https://zenodo.org/badge/latestdoi/589846478) This repository contains the Spezi Template Application. -It demonstrates using the [Spezi](https://github.com/StanfordSpezi/Spezi) framework template and builds on top of the [Stanford Biodesign Digital Health Template Application](https://github.com/StanfordBDHG/TemplateApplication). +It demonstrates using the [Spezi](https://github.com/StanfordSpezi/Spezi) ecosystem and builds on top of the [Stanford Biodesign Digital Health Template Application](https://github.com/StanfordBDHG/TemplateApplication). > [!NOTE] > Do you want to try out the Spezi Template Application? You can download it to your iOS device using [TestFlight](https://testflight.apple.com/join/ipEezBY1)! @@ -85,7 +85,7 @@ It uses the [**Spezi Onboarding** module](https://github.com/StanfordSpezi/Spezi

A screen displaying welcome information. - A screen showing an overview of the modules used in the Spezi Template application. + A screen showing an overview of the modules used in the Spezi Template Application. A screen displaying the consent view. A screen showing a view displaying the HealthKit access screen.

@@ -127,7 +127,7 @@ It uses the [**Spezi Mock Web Service** module](https://github.com/StanfordSpezi ## Continuous Delivery Workflows -The Spezi Template application includes continuous integration (CI) and continuous delivery (CD) setup. +The Spezi Template Application includes continuous integration (CI) and continuous delivery (CD) setup. - Automatically build and test the application on every pull request before deploying it. If your organization doesn't have a self-hosted macOS runner modeled after the setup in the [StanfordBDHG ContinuousIntegration](https://github.com/StanfordBDHG/ContinousIntegration) setup, you will need to remove the `runsonlabels` arguments in the `build-and-test.yml` file to ensure that the build runs on the default macOS runners provided by GitHub. - An automated setup to deploy the application to TestFlight every time there is a new commit on the repository's main branch. - Ensure a coherent code style by checking the conformance to the SwiftLint rules defined in `.swiftlint.yml` on every pull request and commit. diff --git a/Scripts/create.sh b/Scripts/create.sh index 75d75d28..5b6966f1 100644 --- a/Scripts/create.sh +++ b/Scripts/create.sh @@ -1,4 +1,4 @@ -#!/bin/s +#!/bin/bash # # This source file is part of the Stanford Spezi Template Application open-source project # @@ -7,9 +7,175 @@ # SPDX-License-Identifier: MIT # -# Script to create a new iOS application based on the Spezi Template Application -# -# Arguments: -# --test : ... +#!/bin/bash + +export LC_CTYPE=UTF-8 +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + + +# Function to display an error message, show the help, and exit +error_exit_help() { + echo "Error: $1" >&2 + show_help + exit 1 +} + +# Function to display help message +show_help() { + echo "Usage: $0 --name --bundleIdentifier [--provisioningProfile ]" + echo + echo "Options:" + echo " --name Name of the application. (required)" + echo " --bundleIdentifier The iOS bundle identifier of the application. (required)" + echo " --provisioningProfile The name of the iOS provisioning profile to build the application. (optional, defaults to the value of --name)" + echo " --help Display this help and exit." +} + +# Initialize variables +appName="" +bundleIdentifier="" +provisioningProfile="" + +# Parse named arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --name) + appName="$2" + shift # past argument + shift # past value + ;; + --bundleIdentifier) + bundleIdentifier="$2" + shift # past argument + shift # past value + ;; + --provisioningProfile) + provisioningProfile="$2" + shift # past argument + shift # past value + ;; + --help) + show_help + exit 0 + ;; + *) + error_exit_help "Unknown option: $1" + ;; + esac +done + +# Check for required arguments +if [ -z "$appName" ]; then + error_exit_help "The --name argument is required." +fi + +if [ -z "$bundleIdentifier" ]; then + error_exit_help "The --bundleIdentifier argument is required." +fi + +# Set default value for provisioningProfile if not provided +if [ -z "$provisioningProfile" ]; then + provisioningProfile="$appName" +fi + +# Remove spaces from appName +appNameNoSpaces="${appName// /}" + +# Convert appName to lowercase and remove spaces +appNameLowerNoSpaces=$(echo "$appName" | tr '[:upper:]' '[:lower:]' | tr -d ' ') + +# Testing the input: +echo "Application Name: $appName" +echo "Bundle Identifier: $bundleIdentifier" +echo "Provisioning Profile: $provisioningProfile" +echo "Application Name (No Spaces): $appNameNoSpaces" +echo "Application Name (Lowercase, No Spaces): $appNameLowerNoSpaces" + +# Rename the bundle identifier: +oldBundleIdentifierEscaped=$(sed 's:/:\\/:g' <<< "edu.stanford.spezi.templateapplication") +bundleIdentifierEscaped=$(sed 's:/:\\/:g' <<< "$bundleIdentifier") + +find . -type f -not \( -path '*/.git/*' \) -not \( -path '*/Scripts/create.sh' \) -exec grep -Iq . {} \; -print | while read -r file; do + sed -i '' "s/${oldBundleIdentifierEscaped}/${bundleIdentifierEscaped}/g" "$file" || echo "Failed to process $file" +done + + +# Rename the provisioning profile: +oldProvisioningProfileEscaped=$(sed 's:/:\\/:g' <<< "\"Spezi Template Application\"") +provisioningProfileEscaped=$(sed 's:/:\\/:g' <<< "\"$provisioningProfile\"") + +sed -i '' "s/${oldProvisioningProfileEscaped}/${provisioningProfileEscaped}/g" "./fastlane/Fastfile" +sed -i '' "s/${oldProvisioningProfileEscaped}/${provisioningProfileEscaped}/g" "./TemplateApplication.xcodeproj/project.pbxproj" + + +# Firebase project name: +firebaseProjectNameEscaped=$(sed 's:/:\\/:g' <<< "stanfordspezitemplateapp") +appNameLowerNoSpacesEscaped=$(sed 's:/:\\/:g' <<< "\"$appNameLowerNoSpaces\"") + +sed -i '' "s/${firebaseProjectNameEscaped}/${appNameLowerNoSpacesEscaped}/g" ".firebaserc" +sed -i '' "s/${firebaseProjectNameEscaped}/${appNameLowerNoSpacesEscaped}/g" "./TemplateApplication/Supporting Files/GoogleService-Info.plist" + + +# Rename project and code: +projectNameLowercaseEscaped=$(sed 's:/:\\/:g' <<< "templateapplication") +headerFileEscaped=$(sed 's:/:\\/:g' <<< "Stanford Spezi Template Application open-source") +projectNameNoSpacesEscaped=$(sed 's:/:\\/:g' <<< "TemplateApplication") +projectNameSpeziEscaped=$(sed 's:/:\\/:g' <<< "Spezi Template Application") +projectNameEscaped=$(sed 's:/:\\/:g' <<< "Template Application") +templateEscaped=$(sed 's:/:\\/:g' <<< "Template") + +# appNameEscaped=$(sed 's:/:\\/:g' <<< "$appName based on the Stanford Spezi Template Application") +appNameEscaped=$(sed 's:/:\\/:g' <<< "$appName") +appNameNoSpacesEscaped=$(sed 's:/:\\/:g' <<< "$appNameNoSpaces") + +find . -type f -not \( -path '*/.git/*' \) -not \( -path '*/Scripts/create.sh' \) -exec grep -Iq . {} \; -print | while read -r file; do + sed -i '' "s/${projectNameLowercaseEscaped}/${appNameLowerNoSpacesEscaped}/g" "$file" || echo "Failed to process $file" + sed -i '' "s/${headerFileEscaped}/${appNameEscaped}/g" "$file" || echo "Failed to process $file" + sed -i '' "s/${projectNameNoSpacesEscaped}/${appNameNoSpacesEscaped}/g" "$file" || echo "Failed to process $file" + sed -i '' "s/${projectNameSpeziEscaped}/${appNameEscaped}/g" "$file" || echo "Failed to process $file" + sed -i '' "s/${projectNameEscaped}/${appNameEscaped}/g" "$file" || echo "Failed to process $file" + sed -i '' "s/${templateEscaped}/${appNameNoSpacesEscaped}/g" "$file" || echo "Failed to process $file" +done + +# Remove the repo link and DOI from the citation file: +# Specify the file name +citationFile="CITATION.cff" +total_lines=$(wc -l < "$citationFile") +lines_to_keep=$((total_lines - 2)) + +# Check if the file has more than 3 lines +if [ "$lines_to_keep" -ge 1 ]; then + # Output the first N lines to a temporary file + head -n "$lines_to_keep" "$citationFile" > ".$citationFile" + # Replace the original file with the temporary file + mv ".$citationFile" "$citationFile" +else + echo "$citationFile has less than 3 lines, nothing will be removed." +fi + + +# Rename files and directories +# Function to recursively rename directories +rename_directories() { + base_dir=$1 + find "$base_dir" -depth -type d -name "*${projectNameNoSpacesEscaped}*" | while read -r dir; do + new_dir=$(echo "$dir" | sed "s/${projectNameNoSpacesEscaped}/${appNameNoSpacesEscaped}/g") + mv "$dir" "$new_dir" + # Prevent reprocessing of already renamed directories + rename_directories "$new_dir" + done +} + +# Rename directories +rename_directories "." -# 1. ... +# Rename files +find . -type f -name "*${projectNameNoSpacesEscaped}*" | while read -r file; do + new_file=$(echo "$file" | sed "s/${projectNameNoSpacesEscaped}/${appNameNoSpacesEscaped}/g") + # Check if the new file path's directory exists before moving + new_dir=$(dirname "$new_file") + if [ -d "$new_dir" ]; then + mv "$file" "$new_file" + fi +done diff --git a/TemplateApplication.xcodeproj/project.pbxproj b/TemplateApplication.xcodeproj/project.pbxproj index e0c0802e..16f634ac 100644 --- a/TemplateApplication.xcodeproj/project.pbxproj +++ b/TemplateApplication.xcodeproj/project.pbxproj @@ -13,10 +13,10 @@ 2F3D4ABC2A4E7C290068FB2F /* SpeziScheduler in Frameworks */ = {isa = PBXBuildFile; productRef = 2F3D4ABB2A4E7C290068FB2F /* SpeziScheduler */; }; 2F49B7762980407C00BCB272 /* Spezi in Frameworks */ = {isa = PBXBuildFile; productRef = 2F49B7752980407B00BCB272 /* Spezi */; }; 2F4E237E2989A2FE0013F3D9 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */; }; - 2F4E23832989D51F0013F3D9 /* TemplateAppTestingSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23822989D51F0013F3D9 /* TemplateAppTestingSetup.swift */; }; + 2F4E23832989D51F0013F3D9 /* TemplateApplicationTestingSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23822989D51F0013F3D9 /* TemplateApplicationTestingSetup.swift */; }; 2F4E23872989DB360013F3D9 /* ContactsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23862989DB360013F3D9 /* ContactsTests.swift */; }; 2F4FC8D729EE69D300BFFE26 /* MockUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */; }; - 2F5E32BD297E05EA003432F8 /* TemplateAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F5E32BC297E05EA003432F8 /* TemplateAppDelegate.swift */; }; + 2F5E32BD297E05EA003432F8 /* TemplateApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F5E32BC297E05EA003432F8 /* TemplateApplicationDelegate.swift */; }; 2F6025CB29BBE70F0045459E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2F6025CA29BBE70F0045459E /* GoogleService-Info.plist */; }; 2F65B44E2A3B8B0600A36932 /* NotificationPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F65B44D2A3B8B0600A36932 /* NotificationPermissions.swift */; }; 2FA0BFED2ACC977500E0EF83 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2FA0BFEC2ACC977500E0EF83 /* Localizable.xcstrings */; }; @@ -105,10 +105,10 @@ 2F1AC9DE2B4E840E00C24973 /* TemplateApplication.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = TemplateApplication.docc; sourceTree = ""; }; 2F1B52CD2A4F5CCE003AE151 /* MockUploadTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUploadTests.swift; sourceTree = ""; }; 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTests.swift; sourceTree = ""; }; - 2F4E23822989D51F0013F3D9 /* TemplateAppTestingSetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateAppTestingSetup.swift; sourceTree = ""; }; + 2F4E23822989D51F0013F3D9 /* TemplateApplicationTestingSetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateApplicationTestingSetup.swift; sourceTree = ""; }; 2F4E23862989DB360013F3D9 /* ContactsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsTests.swift; sourceTree = ""; }; 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUpload.swift; sourceTree = ""; }; - 2F5E32BC297E05EA003432F8 /* TemplateAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateAppDelegate.swift; sourceTree = ""; }; + 2F5E32BC297E05EA003432F8 /* TemplateApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateApplicationDelegate.swift; sourceTree = ""; }; 2F6025CA29BBE70F0045459E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 2F65B44D2A3B8B0600A36932 /* NotificationPermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPermissions.swift; sourceTree = ""; }; 2FA0BFEC2ACC977500E0EF83 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; @@ -333,9 +333,9 @@ isa = PBXGroup; children = ( 653A2550283387FE005D4D48 /* TemplateApplication.swift */, - 2F5E32BC297E05EA003432F8 /* TemplateAppDelegate.swift */, + 2F5E32BC297E05EA003432F8 /* TemplateApplicationDelegate.swift */, 2FF53D8C2A8729D600042B76 /* TemplateApplicationStandard.swift */, - 2F4E23822989D51F0013F3D9 /* TemplateAppTestingSetup.swift */, + 2F4E23822989D51F0013F3D9 /* TemplateApplicationTestingSetup.swift */, 2FC975A72978F11A00BA99FE /* Home.swift */, A9720E412ABB68B300872D23 /* Account */, 2FE5DC2829EDD398004B9AB4 /* Onboarding */, @@ -633,14 +633,14 @@ 2FE5DC4629EDD7F2004B9AB4 /* Bundle+Image.swift in Sources */, 2FE5DC4F29EDD7FA004B9AB4 /* EventContext.swift in Sources */, 2FE5DC5029EDD7FA004B9AB4 /* EventContextView.swift in Sources */, - 2F4E23832989D51F0013F3D9 /* TemplateAppTestingSetup.swift in Sources */, + 2F4E23832989D51F0013F3D9 /* TemplateApplicationTestingSetup.swift in Sources */, 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */, 2FE5DC5129EDD7FA004B9AB4 /* TemplateApplicationTaskContext.swift in Sources */, 97D8B2AB2A769A6E00715F50 /* OnboardingFlow+PreviewSimulator.swift in Sources */, 56F6F2A02AB441930022FE5A /* ContributionsList.swift in Sources */, 566155292AB8447C00209B80 /* Package+LicenseType.swift in Sources */, 5680DD392AB8983D004E6D4A /* PackageCell.swift in Sources */, - 2F5E32BD297E05EA003432F8 /* TemplateAppDelegate.swift in Sources */, + 2F5E32BD297E05EA003432F8 /* TemplateApplicationDelegate.swift in Sources */, 2FE5DC5229EDD7FA004B9AB4 /* TemplateApplicationScheduler.swift in Sources */, A9FE7AD02AA39BAB0077B045 /* AccountSheet.swift in Sources */, 653A2551283387FE005D4D48 /* TemplateApplication.swift in Sources */, diff --git a/TemplateApplication/Supporting Files/TemplateApplication.docc/Create.md b/TemplateApplication/Supporting Files/TemplateApplication.docc/Create.md index 67579958..f91d00b0 100644 --- a/TemplateApplication/Supporting Files/TemplateApplication.docc/Create.md +++ b/TemplateApplication/Supporting Files/TemplateApplication.docc/Create.md @@ -28,7 +28,7 @@ You can create your own Spezi-based application by creating a new GitHub repo an ## 3. Setup the Continous Integration and Delivery Setup Continuous integration (CI) and continuous delivery (CD) is essential to automatically test and deploy your application at any time. -Each Spezi Template Application-based Spezi app already has the nescessary infrastructure in place; the Spezi Template application includes continuous integration (CI) and continuous delivery (CD) setup: +Each Spezi Template Application-based Spezi app already has the nescessary infrastructure in place; the Spezi Template Application includes continuous integration (CI) and continuous delivery (CD) setup: - Automatically build and test the application on every pull request before deploying it. If your organization doesn't have a self-hosted macOS runner modeled after the setup in the [StanfordBDHG ContinuousIntegration](https://github.com/StanfordBDHG/ContinousIntegration) setup, you will need to remove the `runsonlabels` arguments in the `build-and-test.yml` file to ensure that the build runs on the default macOS runners provided by GitHub. - An automated setup to deploy the application to TestFlight every time there is a new commit on the repository's main branch. - Ensure a coherent code style by checking the conformance to the SwiftLint rules defined in `.swiftlint.yml` on every pull request and commit. diff --git a/TemplateApplication/Supporting Files/TemplateApplication.docc/Modify.md b/TemplateApplication/Supporting Files/TemplateApplication.docc/Modify.md index 8f628626..af1a5d6b 100644 --- a/TemplateApplication/Supporting Files/TemplateApplication.docc/Modify.md +++ b/TemplateApplication/Supporting Files/TemplateApplication.docc/Modify.md @@ -27,7 +27,7 @@ It uses the [**Spezi Onboarding** module](https://github.com/StanfordSpezi/Spezi } } @Column { - @Image(source: "InterestingModules", alt: "A screen showing an overview of the modules used in the Spezi Template application.") { + @Image(source: "InterestingModules", alt: "A screen showing an overview of the modules used in the Spezi Template Application.") { You can find and modify the sequencial onboarding information in the ``InterestingModules`` view. } } diff --git a/TemplateApplication/TemplateAppDelegate.swift b/TemplateApplication/TemplateApplicationDelegate.swift similarity index 100% rename from TemplateApplication/TemplateAppDelegate.swift rename to TemplateApplication/TemplateApplicationDelegate.swift diff --git a/TemplateApplication/TemplateAppTestingSetup.swift b/TemplateApplication/TemplateApplicationTestingSetup.swift similarity index 100% rename from TemplateApplication/TemplateAppTestingSetup.swift rename to TemplateApplication/TemplateApplicationTestingSetup.swift