Skip to content

Commit

Permalink
Refactor static functions/entities in Library (#679)
Browse files Browse the repository at this point in the history
Reduce the impact of hidden dependencies on BundleConfiguration and
Constants.shared

Fixes #656
  • Loading branch information
keeshux authored Oct 4, 2024
1 parent 4b0bc7f commit 5fb6f4f
Show file tree
Hide file tree
Showing 19 changed files with 175 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
"kind" : "remoteSourceControl",
"location" : "[email protected]:passepartoutvpn/passepartoutkit-source",
"state" : {
"revision" : "2e61214462dcf6ad9e211d8fdbd611c6755845c4",
"version" : "0.8.0"
"revision" : "779910e268e79f1004a95285ac2485255d88bb21"
}
},
{
Expand Down
5 changes: 3 additions & 2 deletions Passepartout/App/PassepartoutApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ private extension PassepartoutApp {
registry: context.registry
)
.onLoad {
CommonLibrary.configureLogging(
PassepartoutConfiguration.shared.configureLogging(
to: BundleConfiguration.urlForAppLog,
parameters: Constants.shared.log
parameters: Constants.shared.log,
logsPrivateData: UserDefaults.appGroup.bool(forKey: AppPreference.logsPrivateData.key)
)
AppUI.configure(with: context)
}
Expand Down
4 changes: 2 additions & 2 deletions Passepartout/Library/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ let package = Package(
)
],
dependencies: [
.package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", from: "0.8.0"),
// .package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", revision: "2e61214462dcf6ad9e211d8fdbd611c6755845c4"),
// .package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", from: "0.8.0"),
.package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", revision: "779910e268e79f1004a95285ac2485255d88bb21"),
// .package(path: "../../../passepartoutkit-source"),
.package(url: "[email protected]:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.8.0"),
// .package(url: "[email protected]:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import PassepartoutKit
import UtilsLibrary

extension AppData {

// TODO: #656, make non-static
public static func cdProfileRepositoryV3(
registry: Registry,
coder: ProfileCoder,
Expand Down
14 changes: 5 additions & 9 deletions Passepartout/Library/Sources/AppUI/AppUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@
import Foundation
import PassepartoutKit

// TODO: #656, make non-static
public struct AppUI {
private init() {
}

public enum AppUI {
public static func configure(with context: AppContext) {
assertMissingModuleImplementations()
}
Expand All @@ -40,11 +36,11 @@ private extension AppUI {
static func assertMissingModuleImplementations() {
ModuleType.allCases.forEach { moduleType in
let module = moduleType.newModule()
guard module as? ModuleTypeProviding != nil else {
fatalError("\(moduleType): does not implement ModuleTypeProviding")
guard module is ModuleTypeProviding else {
fatalError("\(moduleType): is not ModuleTypeProviding")
}
guard module as? any ModuleViewProviding != nil else {
fatalError("\(moduleType): does not implement ModuleViewProviding")
guard module is any ModuleViewProviding else {
fatalError("\(moduleType): is not ModuleViewProviding")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Issue+App.swift
// Issue+Metadata.swift
// Passepartout
//
// Created by Davide De Rosa on 9/18/24.
Expand Down Expand Up @@ -28,23 +28,35 @@ import Foundation
import PassepartoutKit

extension Issue {
struct Metadata {
let configuration: PassepartoutConfiguration

// TODO: #656, make non-static
static func with(versionString: String, purchasedProducts: Set<AppProduct>, tunnel: Tunnel) async -> Self {
let appLog = CommonLibrary.currentLog(parameters: Constants.shared.log)
let versionString: String

let purchasedProducts: Set<AppProduct>

let tunnel: Tunnel

let urlForTunnelLog: URL

let parameters: Constants.Log
}

static func withMetadata(_ metadata: Metadata) async -> Issue {
let appLog = metadata.configuration.currentLog(parameters: metadata.parameters)
.joined(separator: "\n")
.data(using: .utf8)

let tunnelLog: Data?

// live tunnel log
if await tunnel.status != .inactive {
tunnelLog = await tunnel.currentLog(parameters: Constants.shared.log)
if await metadata.tunnel.status != .inactive {
tunnelLog = await metadata.tunnel.currentLog(parameters: metadata.parameters)
.joined(separator: "\n")
.data(using: .utf8)
}
// latest persisted tunnel log
else if let latestTunnelEntry = CommonLibrary.availableLogs(at: BundleConfiguration.urlForTunnelLog)
else if let latestTunnelEntry = metadata.configuration.availableLogs(at: metadata.urlForTunnelLog)
.max(by: { $0.key < $1.key }) {

tunnelLog = try? Data(contentsOf: latestTunnelEntry.value)
Expand All @@ -55,13 +67,15 @@ extension Issue {
}

return Issue(
appLine: "\(Strings.Unlocalized.appName) \(versionString)",
purchasedProducts: purchasedProducts,
appLine: "\(Strings.Unlocalized.appName) \(metadata.versionString)",
purchasedProducts: metadata.purchasedProducts,
appLog: appLog,
tunnelLog: tunnelLog
)
}
}

extension Issue {
var to: String {
Constants.shared.emails.issues
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,18 @@ import SwiftUI
import UtilsLibrary

extension DebugLogView {

// TODO: #656, make non-static
static func withApp(parameters: Constants.Log) -> DebugLogView {
DebugLogView {
CommonLibrary.currentLog(parameters: parameters)
PassepartoutConfiguration.shared.currentLog(parameters: parameters)
}
}

// TODO: #656, make non-static
static func withTunnel(_ tunnel: Tunnel, parameters: Constants.Log) -> DebugLogView {
DebugLogView {
await tunnel.currentLog(parameters: parameters)
}
}

// TODO: #656, make non-static
static func withURL(_ url: URL) -> DebugLogView {
DebugLogView {
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ struct DiagnosticsView: View {
@EnvironmentObject
var iapManager: IAPManager

@AppStorage(AppPreference.logsPrivateData.key, store: .group)
@AppStorage(AppPreference.logsPrivateData.key, store: .appGroup)
private var logsPrivateData = false

var availableTunnelLogs: () -> [LogEntry] = {
CommonLibrary.availableLogs(at: BundleConfiguration.urlForTunnelLog)
PassepartoutConfiguration.shared.availableLogs(at: BundleConfiguration.urlForTunnelLog)
.sorted {
$0.key > $1.key
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#if os(iOS)

import CommonLibrary
import PassepartoutKit
import SwiftUI
import UIKit
Expand All @@ -33,24 +34,7 @@ import UtilsLibrary
extension ReportIssueButton: View {
var body: some View {
HStack {
Button(title) {
Task {
isPending = true
defer {
isPending = false
}
let issue = await Issue.with(
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel
)
guard MailComposerView.canSendMail() else {
openMailTo(with: issue)
return
}
issueBeingReported = issue
}
}
Button(title, action: sendEmail)
if isPending {
Spacer()
ProgressView()
Expand All @@ -75,21 +59,29 @@ extension ReportIssueButton: View {
}
}

private extension Issue {
var attachments: [MailComposerView.Attachment] {
var list: [MailComposerView.Attachment] = []
let mimeType = Strings.Unlocalized.Issues.attachmentMimeType
if let appLog {
list.append(.init(data: appLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.appLogFilename))
}
if let tunnelLog {
list.append(.init(data: tunnelLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.tunnelLogFilename))
private extension ReportIssueButton {
func sendEmail() {
Task {
isPending = true
defer {
isPending = false
}
let issue = await Issue.withMetadata(.init(
configuration: .shared,
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel,
urlForTunnelLog: BundleConfiguration.urlForTunnelLog,
parameters: Constants.shared.log
))
guard MailComposerView.canSendMail() else {
openMailTo(with: issue)
return
}
issueBeingReported = issue
}
return list
}
}

private extension ReportIssueButton {
func openMailTo(with issue: Issue) {
guard let url = URL.mailto(to: issue.to, subject: issue.subject, body: issue.body) else {
return
Expand All @@ -102,4 +94,18 @@ private extension ReportIssueButton {
}
}

private extension Issue {
var attachments: [MailComposerView.Attachment] {
var list: [MailComposerView.Attachment] = []
let mimeType = Strings.Unlocalized.Issues.attachmentMimeType
if let appLog {
list.append(.init(data: appLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.appLogFilename))
}
if let tunnelLog {
list.append(.init(data: tunnelLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.tunnelLogFilename))
}
return list
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,39 @@

#if os(macOS)

import CommonLibrary
import PassepartoutKit
import SwiftUI

extension ReportIssueButton: View {
var body: some View {
Button(title) {
Button(title, action: sendEmail)
.disabled(isPending)
}
}

private extension ReportIssueButton {
func sendEmail() {
Task {
guard let service = NSSharingService(named: .composeEmail) else {
isUnableToEmail = true
return
}
Task {
let issue = await Issue.with(
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel
)
service.recipients = [issue.to]
service.subject = issue.subject
service.perform(withItems: issue.items)
isPending = true
defer {
isPending = false
}
let issue = await Issue.withMetadata(.init(
configuration: .shared,
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel,
urlForTunnelLog: BundleConfiguration.urlForTunnelLog,
parameters: Constants.shared.log
))
service.recipients = [issue.to]
service.subject = issue.subject
service.perform(withItems: issue.items)
}
}
}
Expand Down
Loading

0 comments on commit 5fb6f4f

Please sign in to comment.