]> git.r.bdr.sh - rbdr/captura/commitdiff
Add sparkle
authorRuben Beltran del Rio <redacted>
Sat, 14 Sep 2024 16:07:50 +0000 (18:07 +0200)
committerRuben Beltran del Rio <redacted>
Sat, 14 Sep 2024 16:07:50 +0000 (18:07 +0200)
.gitignore [new file with mode: 0644]
Captura.xcodeproj/project.pbxproj
Captura.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved [new file with mode: 0644]
Captura.xcodeproj/xcuserdata/rbdr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
Captura/CapturaApp.swift
Captura/Info.plist
Makefile [new file with mode: 0644]
README.md
export_options.plist [new file with mode: 0644]
scripts/package.sh [new file with mode: 0755]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..d5905e3
--- /dev/null
@@ -0,0 +1 @@
+builds
index 163061ee8551e7f46d2bf9ad34df406f87a7008c..f87b633970f3fdfdf4bf4945b81ceae80d588b12 100644 (file)
@@ -28,6 +28,7 @@
                B55403EA2A79A434004BCBAB /* ScriptedPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55403E92A79A434004BCBAB /* ScriptedPreferences.swift */; };
                B55403EB2A7A2AD2004BCBAB /* Captura.sdef in Resources */ = {isa = PBXBuildFile; fileRef = B5278B482A781B78009F6462 /* Captura.sdef */; };
                B55403ED2A7A388B004BCBAB /* RecordCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55403EC2A7A388B004BCBAB /* RecordCommand.swift */; };
+               B55541E52C95801B0015F522 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = B55541E42C95801B0015F522 /* Sparkle */; };
                B55DDFCC2A6F0253001A5E76 /* Notification+AppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55DDFCB2A6F0253001A5E76 /* Notification+AppEvents.swift */; };
                B55DDFCE2A6F069D001A5E76 /* RecordingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55DDFCD2A6F069D001A5E76 /* RecordingWindow.swift */; };
                B56C70CD2A6EFDF4009B97EB /* CaptureState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56C70CC2A6EFDF4009B97EB /* CaptureState.swift */; };
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               B55541E52C95801B0015F522 /* Sparkle in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        path = Scripting;
                        sourceTree = "<group>";
                };
+               B55541E32C95801B0015F522 /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
                B5F915452A6EF80D007ECE8E = {
                        isa = PBXGroup;
                        children = (
                                B5F915642A6EF80E007ECE8E /* CapturaTests */,
                                B5F9156E2A6EF80E007ECE8E /* CapturaUITests */,
                                B5F9154F2A6EF80D007ECE8E /* Products */,
+                               B55541E32C95801B0015F522 /* Frameworks */,
                        );
                        sourceTree = "<group>";
                };
                        );
                        name = Captura;
                        packageProductDependencies = (
+                               B55541E42C95801B0015F522 /* Sparkle */,
                        );
                        productName = Captura;
                        productReference = B5F9154E2A6EF80D007ECE8E /* Captura.app */;
                        );
                        mainGroup = B5F915452A6EF80D007ECE8E;
                        packageReferences = (
+                               B55541E22C94F86A0015F522 /* XCRemoteSwiftPackageReference "Sparkle" */,
                        );
                        productRefGroup = B5F9154F2A6EF80D007ECE8E /* Products */;
                        projectDirPath = "";
                                CODE_SIGN_ENTITLEMENTS = Captura/Captura.entitlements;
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
-                               CURRENT_PROJECT_VERSION = 3;
+                               CURRENT_PROJECT_VERSION = 4;
                                DEVELOPMENT_ASSET_PATHS = "\"Captura/Preview Content\"";
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                ENABLE_HARDENED_RUNTIME = YES;
                                        "@executable_path/../Frameworks",
                                );
                                MACOSX_DEPLOYMENT_TARGET = 13.0;
-                               MARKETING_VERSION = 1.0.1;
+                               MARKETING_VERSION = 1.1.0;
                                PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.Captura;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SWIFT_EMIT_LOC_STRINGS = YES;
                                CODE_SIGN_ENTITLEMENTS = Captura/Captura.entitlements;
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
-                               CURRENT_PROJECT_VERSION = 3;
+                               CURRENT_PROJECT_VERSION = 4;
                                DEVELOPMENT_ASSET_PATHS = "\"Captura/Preview Content\"";
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                ENABLE_HARDENED_RUNTIME = YES;
                                        "@executable_path/../Frameworks",
                                );
                                MACOSX_DEPLOYMENT_TARGET = 13.0;
-                               MARKETING_VERSION = 1.0.1;
+                               MARKETING_VERSION = 1.1.0;
                                PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.Captura;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SWIFT_EMIT_LOC_STRINGS = YES;
                };
 /* End XCConfigurationList section */
 
+/* Begin XCRemoteSwiftPackageReference section */
+               B55541E22C94F86A0015F522 /* XCRemoteSwiftPackageReference "Sparkle" */ = {
+                       isa = XCRemoteSwiftPackageReference;
+                       repositoryURL = "https://github.com/sparkle-project/Sparkle";
+                       requirement = {
+                               kind = upToNextMajorVersion;
+                               minimumVersion = 2.6.4;
+                       };
+               };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+               B55541E42C95801B0015F522 /* Sparkle */ = {
+                       isa = XCSwiftPackageProductDependency;
+                       package = B55541E22C94F86A0015F522 /* XCRemoteSwiftPackageReference "Sparkle" */;
+                       productName = Sparkle;
+               };
+/* End XCSwiftPackageProductDependency section */
+
 /* Begin XCVersionGroup section */
                B5278B3C2A74420F009F6462 /* Captura.xcdatamodeld */ = {
                        isa = XCVersionGroup;
diff --git a/Captura.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Captura.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644 (file)
index 0000000..5ace476
--- /dev/null
@@ -0,0 +1,15 @@
+{
+  "originHash" : "e721da7f9826abdffcb6185e886155efa2514bd6234475f1afa893e29eb258d6",
+  "pins" : [
+    {
+      "identity" : "sparkle",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/sparkle-project/Sparkle",
+      "state" : {
+        "revision" : "0ef1ee0220239b3776f433314515fd849025673f",
+        "version" : "2.6.4"
+      }
+    }
+  ],
+  "version" : 3
+}
index 272be1a148cb263bf5c811ea554e40fe92dd02a4..b8404acd9c05f4a689a2e15a15f0f7dea2b05c86 100644 (file)
@@ -14,8 +14,8 @@
             filePath = "Captura/CapturaApp.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "346"
-            endingLineNumber = "346"
+            startingLineNumber = "356"
+            endingLineNumber = "356"
             landmarkName = "failed(_:)"
             landmarkType = "7">
          </BreakpointContent>
             filePath = "Captura/CapturaApp.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "291"
-            endingLineNumber = "291"
-            landmarkName = "startRecording()"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "A8CCA767-DD2D-482B-8F95-026C4A0BD9FA"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "Captura/Domain/CapturaCaptureSession.swift"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "42"
-            endingLineNumber = "42"
-            landmarkName = "startRecording()"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "DE0C260E-5AA4-404B-B50E-83DAF27C9532"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "Captura/Domain/CapturaCaptureSession.swift"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "37"
-            endingLineNumber = "37"
+            startingLineNumber = "301"
+            endingLineNumber = "301"
             landmarkName = "startRecording()"
             landmarkType = "7">
          </BreakpointContent>
index 14e266cb24e711f19f25e96bf9e95375943b4b03..e49ef6d6622a27f7fcd5c899227a11f4c022e306 100644 (file)
@@ -2,6 +2,7 @@ import SwiftUI
 import Cocoa
 import Combine
 import AVFoundation
+import Sparkle
 
 @main
 struct CapturaApp: App {
@@ -38,6 +39,10 @@ struct CapturaApp: App {
   var remoteFiles: [CapturaRemoteFile] = []
   var captureSessionConfiguration: CaptureSessionConfiguration = CaptureSessionConfiguration()
   
+  // Sparkle Configuration
+  @IBOutlet var checkForUpdatesMenuItem: NSMenuItem!
+  let updaterController: SPUStandardUpdaterController = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil)
+  
   @objc dynamic var scriptedPreferences: ScriptedPreferences = ScriptedPreferences()
   
   func applicationDidFinishLaunching(_ notification: Notification) {
@@ -89,6 +94,11 @@ struct CapturaApp: App {
     statusItem.menu?.addItem(NSMenuItem.separator())
     statusItem.menu?.addItem(NSMenuItem(title: "Open Local Folder", action: #selector(CapturaAppDelegate.onOpenFolder), keyEquivalent: ""))
     statusItem.menu?.addItem(NSMenuItem.separator())
+    
+    checkForUpdatesMenuItem = NSMenuItem(title: "Check for Updates", action: #selector(SPUStandardUpdaterController.checkForUpdates(_:)), keyEquivalent: "")
+    checkForUpdatesMenuItem.target = updaterController
+    statusItem.menu?.addItem(checkForUpdatesMenuItem)
+    
     statusItem.menu?.addItem(NSMenuItem(title: "Preferences", action: #selector(CapturaAppDelegate.onOpenPreferences), keyEquivalent: ""))
     statusItem.menu?.addItem(NSMenuItem(title: "Quit", action: #selector(CapturaAppDelegate.onQuit), keyEquivalent: ""))
   }
index 17891551f310b240dc914d9496417fcbb6fcb904..e997f3dd7aeb54b44b423d146898f6cf015e0e96 100644 (file)
@@ -2,6 +2,10 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
+       <key>SUFeedURL</key>
+       <string>https://captura.tranquil.systems/appcast.xml</string>
+       <key>SUPublicEDKey</key>
+       <string>lacD9VFVjJO55y+hEy+ReU4S0xbrnbdhncui1qLsmfI=</string>
        <key>CFBundleURLTypes</key>
        <array>
                <dict>
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..dd8bf56
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+project_name := Captura
+derived_data_path := ~/Library/Developer/Xcode/DerivedData
+sparkle_path := $(shell find $(derived_data_path) -type d -path '*artifacts/sparkle/Sparkle' -print -quit)
+build_directory := builds
+sparkle_account := tranquil.systems
+
+
+distribute: archive package generate_appcast
+
+package:
+       @scripts/package.sh "$(project_name)" "$(build_directory)"
+
+generate_appcast:
+       @$(sparkle_path)/bin/generate_appcast --account $(sparkle_account) $(build_directory)
+
+archive: prepare
+       xcodebuild -project $(project_name).xcodeproj -scheme $(project_name) -configuration Release -archivePath $(build_directory)/$(project_name).xcarchive archive && xcodebuild -exportArchive -archivePath $(build_directory)/$(project_name).xcarchive -exportPath $(build_directory) -exportOptionsPlist export_options.plist
+
+prepare:
+       mkdir -p $(build_directory)
+
+.PHONY: package prepare archive generate_appcast package distribute
index 9230a9d318119fd9a45d12818955610f7ad73312..f2e8cfca764ffb090222ea77ae488f34f65752ff 100644 (file)
--- a/README.md
+++ b/README.md
@@ -29,3 +29,14 @@ where the file is available. The status code *MUST* be 201 Created.
 
 Any response code other than 201 Created will be treated as an error. Captura
 will not re-attempt an upload.
+
+## Building
+
+For development, build the app using xcode. For release, a makefile is provided
+with commands to archive and package. If you just want the built and signed app
+you can use `make archive`. To generate the whole package use `make distribute`
+
+### Signing
+
+There's no automated handling of signing. For the app to be signed correctly,
+update the signing configuration in the xcode project.
diff --git a/export_options.plist b/export_options.plist
new file mode 100644 (file)
index 0000000..bb805c5
--- /dev/null
@@ -0,0 +1,10 @@
+<?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>method</key>
+    <string>developer-id</string>
+    <key>signingStyle</key>
+    <string>automatic</string>
+</dict>
+</plist>
diff --git a/scripts/package.sh b/scripts/package.sh
new file mode 100755 (executable)
index 0000000..477693a
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+set -e
+
+
+if [ "$#" -ne 2 ]; then
+       echo "Usage: $0 <project_name> <build_directory>"
+       exit 1
+fi
+
+project_name="$1"
+build_directory="$2"
+
+app_path="${build_directory}/${project_name}.app"
+app_version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${app_path}/Contents/Info.plist)
+tmp_dir=$(mktemp -d)
+dmg_path="${build_directory}/${project_name}-${app_version}.dmg"
+cp -R "${app_path}" "${tmp_dir}"
+ln -s /Applications "${tmp_dir}/Applications"
+hdiutil create -volname "${project_name}" -srcfolder "${tmp_dir}" -ov -format UDZO "${dmg_path}"
+rm -rf "${tmp_dir}"