feat(macos): add proper macOS wrapper app (#1290)
Still missing build process + assembly of bundle
161
.github/workflows/build-and-release-binary.yml
vendored
@@ -43,10 +43,6 @@ jobs:
|
|||||||
target: linux-x64
|
target: linux-x64
|
||||||
- name: ubuntu-22.04-arm
|
- name: ubuntu-22.04-arm
|
||||||
target: linux-arm64
|
target: linux-arm64
|
||||||
- name: macos-13
|
|
||||||
target: macos-x64
|
|
||||||
- name: macos-14
|
|
||||||
target: macos-arm64
|
|
||||||
- name: windows-latest
|
- name: windows-latest
|
||||||
target: win-x64
|
target: win-x64
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -71,40 +67,21 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
- name: 'Create env file (release)'
|
- name: 'Create env file'
|
||||||
run: |
|
|
||||||
touch .env
|
|
||||||
echo TUNARR_EDGE_BUILD=false >> .env
|
|
||||||
echo NODE_ENV=production >> .env
|
|
||||||
echo TUNARR_BIND_ADDR=0.0.0.0 >> .env
|
|
||||||
cat .env
|
|
||||||
cp .env server/.env
|
|
||||||
cp .env web/.env
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
|
|
||||||
- name: 'Create env file (edge)'
|
|
||||||
run: |
|
run: |
|
||||||
touch .env
|
touch .env
|
||||||
echo TUNARR_BUILD="$(git rev-parse --short ${{ github.sha }})" >> .env
|
echo TUNARR_BUILD="$(git rev-parse --short ${{ github.sha }})" >> .env
|
||||||
echo TUNARR_EDGE_BUILD=true >> .env
|
echo TUNARR_EDGE_BUILD=${{github.ref == format('refs/heads/{0}', 'dev') && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')}} >> .env
|
||||||
echo NODE_ENV=production >> .env
|
echo NODE_ENV=production >> .env
|
||||||
echo TUNARR_BIND_ADDR=0.0.0.0 >> .env
|
echo TUNARR_BIND_ADDR=0.0.0.0 >> .env
|
||||||
|
grep -v '^#.*' .env >> $GITHUB_ENV
|
||||||
cat .env
|
cat .env
|
||||||
cp .env server/.env
|
cp .env server/.env
|
||||||
cp .env web/.env
|
cp .env web/.env
|
||||||
if: github.ref == format('refs/heads/{0}', 'dev') && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
|
|
||||||
|
|
||||||
- name: Bundle web
|
- name: Bundle web
|
||||||
run: pnpm turbo bundle --filter=@tunarr/web
|
run: pnpm turbo bundle --filter=@tunarr/web
|
||||||
|
|
||||||
# Install ldid for adhoc signing of macos ARM binaries. PKG should take
|
|
||||||
# care of this.
|
|
||||||
- name: Install ldid
|
|
||||||
uses: MOZGIII/install-ldid-action@v1
|
|
||||||
with:
|
|
||||||
tag: v2.1.5-procursus2
|
|
||||||
if: matrix.os.target == 'macos-arm64'
|
|
||||||
|
|
||||||
- name: Build Executable
|
- name: Build Executable
|
||||||
run: pnpm turbo make-bin -- --target ${{matrix.os.target}}
|
run: pnpm turbo make-bin -- --target ${{matrix.os.target}}
|
||||||
|
|
||||||
@@ -124,3 +101,135 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
./server/bin/tunarr-*
|
./server/bin/tunarr-*
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
build-mac:
|
||||||
|
needs: typecheck
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- name: macos-13
|
||||||
|
target: macos-x64
|
||||||
|
runner: macos-13
|
||||||
|
- name: macos-14
|
||||||
|
target: macos-arm64
|
||||||
|
runner: macos-latest
|
||||||
|
runs-on: ${{matrix.os.runner}}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4 # Checkout code from repository
|
||||||
|
|
||||||
|
- uses: ilammy/setup-nasm@v1
|
||||||
|
|
||||||
|
- name: Use Latest Corepack
|
||||||
|
run: |
|
||||||
|
npm install -g corepack@latest
|
||||||
|
corepack enable && corepack enable pnpm
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22.13.0
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
pnpm install
|
||||||
|
brew install jq
|
||||||
|
|
||||||
|
- name: Import Code-Signing Certificates
|
||||||
|
uses: Apple-Actions/import-codesign-certs@v2
|
||||||
|
with:
|
||||||
|
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}
|
||||||
|
p12-password: ${{ secrets.APPLE_CERTIFICATE_P12_PASSWORD }}
|
||||||
|
|
||||||
|
- name: 'Create env file'
|
||||||
|
run: |
|
||||||
|
touch .env
|
||||||
|
echo TUNARR_BUILD="$(git rev-parse --short ${{ github.sha }})" >> .env
|
||||||
|
echo TUNARR_EDGE_BUILD=${{github.ref == format('refs/heads/{0}', 'dev') && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')}} >> .env
|
||||||
|
echo NODE_ENV=production >> .env
|
||||||
|
echo TUNARR_BIND_ADDR=0.0.0.0 >> .env
|
||||||
|
|
||||||
|
tunarr_version="$(jq -r .version package.json)"
|
||||||
|
if [[ "$TUNARR_EDGE_BUILD" == "true" || "$TUNARR_EDGE_BUILD" == "1" ]]; then
|
||||||
|
is_edge_build=true
|
||||||
|
else
|
||||||
|
is_edge_build=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$TUNARR_BUILD" && "$TUNARR_EDGE_BUILD" == true ]]; then
|
||||||
|
tunarr_version+="-${build}"
|
||||||
|
fi
|
||||||
|
echo "TUNARR_VERSION=${tunarr_version}" >> $GITHUB_ENV
|
||||||
|
release_name="Tunarr-${tunarr_version}-${{ matrix.os.target }}"
|
||||||
|
echo "RELEASE_NAME=${release_name}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
grep -v '^#.*' .env >> $GITHUB_ENV
|
||||||
|
cat .env
|
||||||
|
cp .env server/.env
|
||||||
|
cp .env web/.env
|
||||||
|
|
||||||
|
- name: Bundle web
|
||||||
|
run: pnpm turbo bundle --filter=@tunarr/web
|
||||||
|
|
||||||
|
- name: Build Executable
|
||||||
|
run: pnpm turbo make-bin -- --target ${{matrix.os.target}}
|
||||||
|
|
||||||
|
- name: Bundle
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
brew install coreutils
|
||||||
|
plutil -replace CFBundleShortVersionString -string "$TUNARR_VERSION" macos/Tunarr/Tunarr/Info.plist
|
||||||
|
plutil -replace CFBundleVersion -string "$TUNARR_VERSION" macos/Tunarr/Tunarr/Info.plist
|
||||||
|
scripts/bundle-macos.sh
|
||||||
|
|
||||||
|
- name: Sign
|
||||||
|
shell: bash
|
||||||
|
run: scripts/sign-macos.sh
|
||||||
|
|
||||||
|
- name: Create DMG
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
brew install create-dmg
|
||||||
|
create-dmg \
|
||||||
|
--volname "Tunarr" \
|
||||||
|
--volicon "design/Tunarr.icns" \
|
||||||
|
--window-pos 200 120 \
|
||||||
|
--window-size 800 400 \
|
||||||
|
--icon-size 100 \
|
||||||
|
--icon "Tunarr.app" 200 190 \
|
||||||
|
--hide-extension "Tunarr.app" \
|
||||||
|
--app-drop-link 600 185 \
|
||||||
|
--skip-jenkins \
|
||||||
|
--no-internet-enable \
|
||||||
|
"Tunarr.dmg" \
|
||||||
|
"Tunarr.app/"
|
||||||
|
|
||||||
|
- name: Notarize
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
xcrun notarytool submit Tunarr.dmg --apple-id "${{ secrets.AC_USERNAME }}" --password "${{ secrets.AC_PASSWORD }}" --team-id XX35C4MZN8 --wait
|
||||||
|
xcrun stapler staple Tunarr.dmg
|
||||||
|
|
||||||
|
- name: Finalize
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mv Tunarr.dmg "${{env.RELEASE_NAME}}.dmg"
|
||||||
|
|
||||||
|
- name: Upload Edge Binary
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
name: Tunarr Edge
|
||||||
|
tag_name: edge
|
||||||
|
prerelease: true
|
||||||
|
files: |
|
||||||
|
${{ env.RELEASE_NAME }}.dmg
|
||||||
|
if: github.ref == format('refs/heads/{0}', 'dev') && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
|
||||||
|
|
||||||
|
- name: Upload Binaries
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
${{ env.RELEASE_NAME }}.dmg
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
2
.gitignore
vendored
@@ -20,4 +20,4 @@ log.txt
|
|||||||
coverage/
|
coverage/
|
||||||
|
|
||||||
*.dmg
|
*.dmg
|
||||||
*.app
|
*.app
|
||||||
|
|||||||
BIN
design/Tunarr.icns
Normal file
556
macos/Tunarr/Tunarr.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,556 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 77;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
14E9EAAB2E35689400486B60 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 14E9EA942E35689100486B60 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 14E9EA9B2E35689100486B60;
|
||||||
|
remoteInfo = Tunarr;
|
||||||
|
};
|
||||||
|
14E9EAB52E35689400486B60 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 14E9EA942E35689100486B60 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 14E9EA9B2E35689100486B60;
|
||||||
|
remoteInfo = Tunarr;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
14E9EA9C2E35689100486B60 /* Tunarr.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tunarr.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
14E9EAAA2E35689400486B60 /* TunarrTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TunarrTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
14E9EAB42E35689400486B60 /* TunarrUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TunarrUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
14E9EA9E2E35689100486B60 /* Tunarr */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
path = Tunarr;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
14E9EAAD2E35689400486B60 /* TunarrTests */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
path = TunarrTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
14E9EAB72E35689400486B60 /* TunarrUITests */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
path = TunarrUITests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
14E9EA992E35689100486B60 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
14E9EAA72E35689400486B60 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
14E9EAB12E35689400486B60 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
14E9EA932E35689100486B60 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
14E9EA9E2E35689100486B60 /* Tunarr */,
|
||||||
|
14E9EAAD2E35689400486B60 /* TunarrTests */,
|
||||||
|
14E9EAB72E35689400486B60 /* TunarrUITests */,
|
||||||
|
14E9EA9D2E35689100486B60 /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
14E9EA9D2E35689100486B60 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
14E9EA9C2E35689100486B60 /* Tunarr.app */,
|
||||||
|
14E9EAAA2E35689400486B60 /* TunarrTests.xctest */,
|
||||||
|
14E9EAB42E35689400486B60 /* TunarrUITests.xctest */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
14E9EA9B2E35689100486B60 /* Tunarr */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 14E9EABE2E35689400486B60 /* Build configuration list for PBXNativeTarget "Tunarr" */;
|
||||||
|
buildPhases = (
|
||||||
|
14E9EA982E35689100486B60 /* Sources */,
|
||||||
|
14E9EA992E35689100486B60 /* Frameworks */,
|
||||||
|
14E9EA9A2E35689100486B60 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
14E9EA9E2E35689100486B60 /* Tunarr */,
|
||||||
|
);
|
||||||
|
name = Tunarr;
|
||||||
|
packageProductDependencies = (
|
||||||
|
);
|
||||||
|
productName = Tunarr;
|
||||||
|
productReference = 14E9EA9C2E35689100486B60 /* Tunarr.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
14E9EAA92E35689400486B60 /* TunarrTests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 14E9EAC12E35689400486B60 /* Build configuration list for PBXNativeTarget "TunarrTests" */;
|
||||||
|
buildPhases = (
|
||||||
|
14E9EAA62E35689400486B60 /* Sources */,
|
||||||
|
14E9EAA72E35689400486B60 /* Frameworks */,
|
||||||
|
14E9EAA82E35689400486B60 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
14E9EAAC2E35689400486B60 /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
14E9EAAD2E35689400486B60 /* TunarrTests */,
|
||||||
|
);
|
||||||
|
name = TunarrTests;
|
||||||
|
packageProductDependencies = (
|
||||||
|
);
|
||||||
|
productName = TunarrTests;
|
||||||
|
productReference = 14E9EAAA2E35689400486B60 /* TunarrTests.xctest */;
|
||||||
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
|
};
|
||||||
|
14E9EAB32E35689400486B60 /* TunarrUITests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 14E9EAC42E35689400486B60 /* Build configuration list for PBXNativeTarget "TunarrUITests" */;
|
||||||
|
buildPhases = (
|
||||||
|
14E9EAB02E35689400486B60 /* Sources */,
|
||||||
|
14E9EAB12E35689400486B60 /* Frameworks */,
|
||||||
|
14E9EAB22E35689400486B60 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
14E9EAB62E35689400486B60 /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
14E9EAB72E35689400486B60 /* TunarrUITests */,
|
||||||
|
);
|
||||||
|
name = TunarrUITests;
|
||||||
|
packageProductDependencies = (
|
||||||
|
);
|
||||||
|
productName = TunarrUITests;
|
||||||
|
productReference = 14E9EAB42E35689400486B60 /* TunarrUITests.xctest */;
|
||||||
|
productType = "com.apple.product-type.bundle.ui-testing";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
14E9EA942E35689100486B60 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
BuildIndependentTargetsInParallel = 1;
|
||||||
|
LastSwiftUpdateCheck = 1640;
|
||||||
|
LastUpgradeCheck = 1640;
|
||||||
|
TargetAttributes = {
|
||||||
|
14E9EA9B2E35689100486B60 = {
|
||||||
|
CreatedOnToolsVersion = 16.4;
|
||||||
|
};
|
||||||
|
14E9EAA92E35689400486B60 = {
|
||||||
|
CreatedOnToolsVersion = 16.4;
|
||||||
|
TestTargetID = 14E9EA9B2E35689100486B60;
|
||||||
|
};
|
||||||
|
14E9EAB32E35689400486B60 = {
|
||||||
|
CreatedOnToolsVersion = 16.4;
|
||||||
|
TestTargetID = 14E9EA9B2E35689100486B60;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 14E9EA972E35689100486B60 /* Build configuration list for PBXProject "Tunarr" */;
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 14E9EA932E35689100486B60;
|
||||||
|
minimizedProjectReferenceProxies = 1;
|
||||||
|
preferredProjectObjectVersion = 77;
|
||||||
|
productRefGroup = 14E9EA9D2E35689100486B60 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
14E9EA9B2E35689100486B60 /* Tunarr */,
|
||||||
|
14E9EAA92E35689400486B60 /* TunarrTests */,
|
||||||
|
14E9EAB32E35689400486B60 /* TunarrUITests */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
14E9EA9A2E35689100486B60 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
14E9EAA82E35689400486B60 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
14E9EAB22E35689400486B60 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
14E9EA982E35689100486B60 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
14E9EAA62E35689400486B60 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
14E9EAB02E35689400486B60 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
14E9EAAC2E35689400486B60 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 14E9EA9B2E35689100486B60 /* Tunarr */;
|
||||||
|
targetProxy = 14E9EAAB2E35689400486B60 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
14E9EAB62E35689400486B60 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 14E9EA9B2E35689100486B60 /* Tunarr */;
|
||||||
|
targetProxy = 14E9EAB52E35689400486B60 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
14E9EABC2E35689400486B60 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 15.5;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
14E9EABD2E35689400486B60 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 15.5;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
14E9EABF2E35689400486B60 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Tunarr/Tunarr.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.cbenincasa.Tunarr;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
REGISTER_APP_GROUPS = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
14E9EAC02E35689400486B60 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Tunarr/Tunarr.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.cbenincasa.Tunarr;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
REGISTER_APP_GROUPS = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
14E9EAC22E35689400486B60 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 15.5;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.cbenincasa.TunarrTests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Tunarr.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Tunarr";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
14E9EAC32E35689400486B60 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 15.5;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.cbenincasa.TunarrTests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Tunarr.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Tunarr";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
14E9EAC52E35689400486B60 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.cbenincasa.TunarrUITests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TEST_TARGET_NAME = Tunarr;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
14E9EAC62E35689400486B60 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = XX35C4MZN8;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.cbenincasa.TunarrUITests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TEST_TARGET_NAME = Tunarr;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
14E9EA972E35689100486B60 /* Build configuration list for PBXProject "Tunarr" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
14E9EABC2E35689400486B60 /* Debug */,
|
||||||
|
14E9EABD2E35689400486B60 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
14E9EABE2E35689400486B60 /* Build configuration list for PBXNativeTarget "Tunarr" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
14E9EABF2E35689400486B60 /* Debug */,
|
||||||
|
14E9EAC02E35689400486B60 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
14E9EAC12E35689400486B60 /* Build configuration list for PBXNativeTarget "TunarrTests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
14E9EAC22E35689400486B60 /* Debug */,
|
||||||
|
14E9EAC32E35689400486B60 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
14E9EAC42E35689400486B60 /* Build configuration list for PBXNativeTarget "TunarrUITests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
14E9EAC52E35689400486B60 /* Debug */,
|
||||||
|
14E9EAC62E35689400486B60 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 14E9EA942E35689100486B60 /* Project object */;
|
||||||
|
}
|
||||||
7
macos/Tunarr/Tunarr.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>Tunarr.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
37
macos/Tunarr/Tunarr/AppDelegate.swift
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// AppDelegate.swift
|
||||||
|
// Tunarr
|
||||||
|
//
|
||||||
|
// Created by Christian Benincasa on 7/26/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import AppKit
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
let bundle = Bundle.main
|
||||||
|
var task = Process()
|
||||||
|
|
||||||
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||||
|
guard let executablePath = Bundle.main.url(forAuxiliaryExecutable: "tunarr-macos")
|
||||||
|
else {
|
||||||
|
/// TODO: Do a popup here.
|
||||||
|
NSLog("Error: Bundled executable 'tunarr-macos' not found.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
task.executableURL = executablePath
|
||||||
|
do {
|
||||||
|
try task.run()
|
||||||
|
NSLog("Successfully started Tunarr subprocess.")
|
||||||
|
} catch {
|
||||||
|
NSLog("Could not launch Tunarr. Reason: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillTerminate(_ aNotification: Notification) {
|
||||||
|
NSLog("Shutting down Tunarr.")
|
||||||
|
task.terminate()
|
||||||
|
task.waitUntilExit()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_16x16.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "16x16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_16x16@2x.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "16x16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_32x32.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "32x32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_32x32@2x.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "32x32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_128x128.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "128x128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_128x128@2x.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "128x128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_256x256.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "256x256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_256x256@2x.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "256x256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_512x512.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "512x512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "tunarr_512_512@2x.png",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 14 KiB |
6
macos/Tunarr/Tunarr/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "7x7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "7x7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "11x11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "11x11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "24x24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "24x24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "50x50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "50x50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "100x100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "mac",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "100x100"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
23
macos/Tunarr/Tunarr/Assets.xcassets/StatusBarButtonImage.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "favicon.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "favicon 1.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "favicon 2.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
25
macos/Tunarr/Tunarr/Assets.xcassets/StatusBarButtonImage.imageset/favicon 1.svg
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<style>
|
||||||
|
line { stroke: #231A12; }
|
||||||
|
path.darkMode, circle { fill: #231A12; }
|
||||||
|
circle.button {fill: white}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
line { stroke: #474143 }
|
||||||
|
path.darkMode, circle { fill: #474143 }
|
||||||
|
circle.button {fill: white}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<line class="darkMode" x1="13.0531" y1="3.85848" x2="15.1559" y2="7.61348" stroke="#231A12"/>
|
||||||
|
<line x1="18.3012" y1="3.78277" x2="15.8843" y2="7.34375" stroke="#231A12"/>
|
||||||
|
<path class="darkMode" d="M0 17C0 11.4772 4.47715 7 10 7H22C27.5228 7 32 11.4772 32 17V18C32 23.5228 27.5228 28 22 28H10C4.47715 28 0 23.5228 0 18V17Z" fill="#231A12"/>
|
||||||
|
<path class="darkMode" d="M0 8.48936C0 7.66681 0.69548 7 1.5534 7H30.4466C31.3045 7 32 7.66681 32 8.48936V26.5106C32 27.3332 31.3045 28 30.4466 28H1.5534C0.69548 28 0 27.3332 0 26.5106V8.48936Z" fill="#231A12"/>
|
||||||
|
<circle cx="13" cy="4" r="1" fill="#231A12"/>
|
||||||
|
<circle cx="18" cy="4" r="1" fill="#231A12"/>
|
||||||
|
<path d="M3.00397 11.5614C3.00397 11.0091 3.45168 10.5614 4.00397 10.5614H8.33894V24.53H4.00397C3.45168 24.53 3.00397 24.0823 3.00397 23.53V11.5614Z" fill="#DD3C2C"/>
|
||||||
|
<path d="M18.8472 10.5614H23.1822C23.7345 10.5614 24.1822 11.0091 24.1822 11.5614V23.53C24.1822 24.0823 23.7345 24.53 23.1822 24.53H18.8472V10.5614Z" fill="#E98E1D"/>
|
||||||
|
<rect x="13.6739" y="10.5614" width="5.33497" height="13.9686" fill="#68AAE5"/>
|
||||||
|
<rect x="8.33899" y="10.5614" width="5.33497" height="13.9686" fill="#8DCA23"/>
|
||||||
|
<circle class="button" cx="28" cy="14" r="1" fill="white"/>
|
||||||
|
<circle class="button" cx="28" cy="22" r="1" fill="white"/>
|
||||||
|
<circle class="button" cx="28" cy="18" r="1" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
25
macos/Tunarr/Tunarr/Assets.xcassets/StatusBarButtonImage.imageset/favicon 2.svg
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<style>
|
||||||
|
line { stroke: #231A12; }
|
||||||
|
path.darkMode, circle { fill: #231A12; }
|
||||||
|
circle.button {fill: white}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
line { stroke: #474143 }
|
||||||
|
path.darkMode, circle { fill: #474143 }
|
||||||
|
circle.button {fill: white}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<line class="darkMode" x1="13.0531" y1="3.85848" x2="15.1559" y2="7.61348" stroke="#231A12"/>
|
||||||
|
<line x1="18.3012" y1="3.78277" x2="15.8843" y2="7.34375" stroke="#231A12"/>
|
||||||
|
<path class="darkMode" d="M0 17C0 11.4772 4.47715 7 10 7H22C27.5228 7 32 11.4772 32 17V18C32 23.5228 27.5228 28 22 28H10C4.47715 28 0 23.5228 0 18V17Z" fill="#231A12"/>
|
||||||
|
<path class="darkMode" d="M0 8.48936C0 7.66681 0.69548 7 1.5534 7H30.4466C31.3045 7 32 7.66681 32 8.48936V26.5106C32 27.3332 31.3045 28 30.4466 28H1.5534C0.69548 28 0 27.3332 0 26.5106V8.48936Z" fill="#231A12"/>
|
||||||
|
<circle cx="13" cy="4" r="1" fill="#231A12"/>
|
||||||
|
<circle cx="18" cy="4" r="1" fill="#231A12"/>
|
||||||
|
<path d="M3.00397 11.5614C3.00397 11.0091 3.45168 10.5614 4.00397 10.5614H8.33894V24.53H4.00397C3.45168 24.53 3.00397 24.0823 3.00397 23.53V11.5614Z" fill="#DD3C2C"/>
|
||||||
|
<path d="M18.8472 10.5614H23.1822C23.7345 10.5614 24.1822 11.0091 24.1822 11.5614V23.53C24.1822 24.0823 23.7345 24.53 23.1822 24.53H18.8472V10.5614Z" fill="#E98E1D"/>
|
||||||
|
<rect x="13.6739" y="10.5614" width="5.33497" height="13.9686" fill="#68AAE5"/>
|
||||||
|
<rect x="8.33899" y="10.5614" width="5.33497" height="13.9686" fill="#8DCA23"/>
|
||||||
|
<circle class="button" cx="28" cy="14" r="1" fill="white"/>
|
||||||
|
<circle class="button" cx="28" cy="22" r="1" fill="white"/>
|
||||||
|
<circle class="button" cx="28" cy="18" r="1" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
25
macos/Tunarr/Tunarr/Assets.xcassets/StatusBarButtonImage.imageset/favicon.svg
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<style>
|
||||||
|
line { stroke: #231A12; }
|
||||||
|
path.darkMode, circle { fill: #231A12; }
|
||||||
|
circle.button {fill: white}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
line { stroke: #474143 }
|
||||||
|
path.darkMode, circle { fill: #474143 }
|
||||||
|
circle.button {fill: white}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<line class="darkMode" x1="13.0531" y1="3.85848" x2="15.1559" y2="7.61348" stroke="#231A12"/>
|
||||||
|
<line x1="18.3012" y1="3.78277" x2="15.8843" y2="7.34375" stroke="#231A12"/>
|
||||||
|
<path class="darkMode" d="M0 17C0 11.4772 4.47715 7 10 7H22C27.5228 7 32 11.4772 32 17V18C32 23.5228 27.5228 28 22 28H10C4.47715 28 0 23.5228 0 18V17Z" fill="#231A12"/>
|
||||||
|
<path class="darkMode" d="M0 8.48936C0 7.66681 0.69548 7 1.5534 7H30.4466C31.3045 7 32 7.66681 32 8.48936V26.5106C32 27.3332 31.3045 28 30.4466 28H1.5534C0.69548 28 0 27.3332 0 26.5106V8.48936Z" fill="#231A12"/>
|
||||||
|
<circle cx="13" cy="4" r="1" fill="#231A12"/>
|
||||||
|
<circle cx="18" cy="4" r="1" fill="#231A12"/>
|
||||||
|
<path d="M3.00397 11.5614C3.00397 11.0091 3.45168 10.5614 4.00397 10.5614H8.33894V24.53H4.00397C3.45168 24.53 3.00397 24.0823 3.00397 23.53V11.5614Z" fill="#DD3C2C"/>
|
||||||
|
<path d="M18.8472 10.5614H23.1822C23.7345 10.5614 24.1822 11.0091 24.1822 11.5614V23.53C24.1822 24.0823 23.7345 24.53 23.1822 24.53H18.8472V10.5614Z" fill="#E98E1D"/>
|
||||||
|
<rect x="13.6739" y="10.5614" width="5.33497" height="13.9686" fill="#68AAE5"/>
|
||||||
|
<rect x="8.33899" y="10.5614" width="5.33497" height="13.9686" fill="#8DCA23"/>
|
||||||
|
<circle class="button" cx="28" cy="14" r="1" fill="white"/>
|
||||||
|
<circle class="button" cx="28" cy="22" r="1" fill="white"/>
|
||||||
|
<circle class="button" cx="28" cy="18" r="1" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 52 KiB |
8
macos/Tunarr/Tunarr/Info.plist
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>LSUIElement</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
22
macos/Tunarr/Tunarr/Tunarr.entitlements
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.automation.apple-events</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<false/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
47
macos/Tunarr/Tunarr/TunarrApp.swift
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// TunarrApp.swift
|
||||||
|
// Tunarr
|
||||||
|
//
|
||||||
|
// Created by Christian Benincasa on 7/26/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct TunarrApp: App {
|
||||||
|
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||||
|
|
||||||
|
var body: some Scene {
|
||||||
|
MenuBarExtra("Tunarr", image: "StatusBarButtonImage") {
|
||||||
|
Button("Launch Web UI") {
|
||||||
|
let portString = ProcessInfo.processInfo.environment[
|
||||||
|
"TUNARR_SERVER_PORT"
|
||||||
|
]
|
||||||
|
NSLog("Port string is \(portString ?? "null")")
|
||||||
|
let port = Int(portString ?? "") ?? 8000
|
||||||
|
let url = "http://localhost:\(port)"
|
||||||
|
NSWorkspace.shared.open(NSURL(string: url)! as URL)
|
||||||
|
}
|
||||||
|
Button("Show Logs") {
|
||||||
|
NSWorkspace.shared.activateFileViewerSelecting(
|
||||||
|
[
|
||||||
|
URL(
|
||||||
|
fileURLWithPath:
|
||||||
|
FileManager.default
|
||||||
|
.homeDirectoryForCurrentUser
|
||||||
|
.appendingPathComponent(
|
||||||
|
"Library"
|
||||||
|
).appendingPathComponent("Preferences")
|
||||||
|
.appendingPathComponent("tunarr")
|
||||||
|
.appendingPathComponent("logs").path
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Divider()
|
||||||
|
Button("Quit Tunarr") {
|
||||||
|
NSApplication.shared.terminate(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
macos/Tunarr/TunarrTests/TunarrTests.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// TunarrTests.swift
|
||||||
|
// TunarrTests
|
||||||
|
//
|
||||||
|
// Created by Christian Benincasa on 7/26/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Testing
|
||||||
|
@testable import Tunarr
|
||||||
|
|
||||||
|
struct TunarrTests {
|
||||||
|
|
||||||
|
@Test func example() async throws {
|
||||||
|
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
macos/Tunarr/TunarrUITests/TunarrUITests.swift
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// TunarrUITests.swift
|
||||||
|
// TunarrUITests
|
||||||
|
//
|
||||||
|
// Created by Christian Benincasa on 7/26/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class TunarrUITests: XCTestCase {
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
|
||||||
|
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||||
|
continueAfterFailure = false
|
||||||
|
|
||||||
|
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDownWithError() throws {
|
||||||
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testExample() throws {
|
||||||
|
// UI tests must launch the application that they test.
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testLaunchPerformance() throws {
|
||||||
|
// This measures how long it takes to launch your application.
|
||||||
|
measure(metrics: [XCTApplicationLaunchMetric()]) {
|
||||||
|
XCUIApplication().launch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
macos/Tunarr/TunarrUITests/TunarrUITestsLaunchTests.swift
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// TunarrUITestsLaunchTests.swift
|
||||||
|
// TunarrUITests
|
||||||
|
//
|
||||||
|
// Created by Christian Benincasa on 7/26/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class TunarrUITestsLaunchTests: XCTestCase {
|
||||||
|
|
||||||
|
override class var runsForEachTargetApplicationUIConfiguration: Bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
continueAfterFailure = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testLaunch() throws {
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Insert steps here to perform after app launch but before taking a screenshot,
|
||||||
|
// such as logging into a test account or navigating somewhere in the app
|
||||||
|
|
||||||
|
let attachment = XCTAttachment(screenshot: app.screenshot())
|
||||||
|
attachment.name = "Launch Screen"
|
||||||
|
attachment.lifetime = .keepAlways
|
||||||
|
add(attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
22
scripts/bundle-macos.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
BINARY_NAME="$1"
|
||||||
|
SCRIPT_FOLDER=$(dirname "${BASH_SOURCE[0]}")
|
||||||
|
REPO_ROOT=$(realpath "$SCRIPT_FOLDER/..")
|
||||||
|
APP_NAME="$REPO_ROOT/Tunarr.app"
|
||||||
|
|
||||||
|
if [ -d "$APP_NAME" ]
|
||||||
|
then
|
||||||
|
rm -rf "$APP_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd "$REPO_ROOT/macos/Tunarr" || exit
|
||||||
|
|
||||||
|
xcodebuild build
|
||||||
|
cp -R "$REPO_ROOT/macos/Tunarr/build/Release/Tunarr.app" "$APP_NAME"
|
||||||
|
|
||||||
|
popd || exit
|
||||||
|
|
||||||
|
cp -a "$REPO_ROOT/server/bin/$BINARY_NAME" "$APP_NAME/Contents/MacOS/tunarr-macos"
|
||||||
|
|
||||||
|
chmod +x "$APP_NAME/Contents/MacOS/tunarr-macos"
|
||||||
3
scripts/gen-icns.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
iconutil -c icns -o ./design/Tunarr.icns macos/Tunarr/Tunarr/Assets.xcassets/TunarrIcon.iconset
|
||||||
11
scripts/sign-macos-dmg.sh
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_FOLDER=$(dirname "${BASH_SOURCE[0]}")
|
||||||
|
REPO_ROOT=$(realpath "$SCRIPT_FOLDER/..")
|
||||||
|
DMG_NAME="$REPO_ROOT/Tunarr.dmg"
|
||||||
|
ENTITLEMENTS="$REPO_ROOT/macos/Tunarr/Tunarr/Tunarr.entitlements"
|
||||||
|
SIGNING_IDENTITY="040A9C3F4C8D3D983822CCB65959A6FDB9DACDCD"
|
||||||
|
|
||||||
|
codesign --force --timestamp --options=runtime --entitlements "$ENTITLEMENTS" --sign "$SIGNING_IDENTITY" "$DMG_NAME"
|
||||||
9
scripts/sign-macos.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_FOLDER=$(dirname "${BASH_SOURCE[0]}")
|
||||||
|
REPO_ROOT=$(realpath "$SCRIPT_FOLDER/..")
|
||||||
|
APP_NAME="$REPO_ROOT/Tunarr.app"
|
||||||
|
ENTITLEMENTS="$REPO_ROOT/macos/Tunarr/Tunarr/Tunarr.entitlements"
|
||||||
|
SIGNING_IDENTITY="040A9C3F4C8D3D983822CCB65959A6FDB9DACDCD"
|
||||||
|
|
||||||
|
codesign --force --verbose --timestamp --options=runtime --entitlements "$ENTITLEMENTS" --sign "$SIGNING_IDENTITY" --deep "$APP_NAME"
|
||||||