Skip to content

Commit

Permalink
Merge branch 'b4.11.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
sdpopov-keyvariable committed Jan 23, 2024
2 parents 4fd2209 + b195443 commit 58ce46d
Showing 1 changed file with 39 additions and 15 deletions.
54 changes: 39 additions & 15 deletions Sources/kvKit/KvInstallKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ public struct KvInstallKit { private init() { }

// MARK: Working with Bundles

/// Copies the application bundle and the shared libraries to *destinationURL*.
public static func copyBundle(to destinationURL: URL, shell: KvShell = .init()) throws {
let sourceRootURL = Bundle.main.bundleURL
/// Copies given *bundle* and the shared libraries to *destinationURL*.
///
/// - Parameter bundle: If `nil` then `.main` bundle is copied.
public static func copyBundle(_ bundle: Bundle? = nil, to destinationURL: URL, shell: KvShell = .init()) throws {
let sourceRootURL = (bundle ?? .main).bundleURL
let temporaryRootURL = destinationURL
.appendingPathExtension("new")

Expand Down Expand Up @@ -200,30 +202,52 @@ public struct KvInstallKit { private init() { }
}


/// Replaces file item at given URL, changes ower to the user and sets minimum access rights to copies files.
/// Replaces file item at given URL, changes ower to the user and sets minimum access rights to copied files.
///
/// - Note: The replacing procedure uses backups.
public func replaceItem(at originalURL: URL, withItemAt replacementURL: URL, shell: KvShell = .init()) throws {
let fileManager = FileManager.default
let temporaryURL = try LeastPrivilegedUser.temporaryURL(toReplaceItemAt: originalURL)

try shell.run("mv", with: [ replacementURL.path, temporaryURL.path ]).orThrow()

try ownAndSetMinimumPermissions(toItemAt: temporaryURL, shell: shell)
try KvFileKit.replaceItem(at: originalURL, withItemAt: temporaryURL)
}


/// Replaces file item at given path with contents of given *bundle*, changes ower to the user and sets minimum access rights to copied files.
///
/// - Parameter bundle: If `nil` then `.main` bundle is copied.
///
/// - Note: The replacing procedure uses backups.
public func replaceBundleItem(at originalURL: URL, with bundle: Bundle? = nil, shell: KvShell = .init()) throws {
let temporaryURL = try LeastPrivilegedUser.temporaryURL(toReplaceItemAt: originalURL)

try KvInstallKit.copyBundle(bundle, to: temporaryURL, shell: shell)

try ownAndSetMinimumPermissions(toItemAt: temporaryURL, shell: shell)
try KvFileKit.replaceItem(at: originalURL, withItemAt: temporaryURL)
}


/// Appends .new extension and removes file item at resulting path if exists.
private static func temporaryURL(toReplaceItemAt originalURL: URL) throws -> URL {
let temporaryURL = originalURL
.appendingPathExtension("new")

// Removal of existing temporary item.
if fileManager.fileExists(atPath: temporaryURL.path) {
do { try fileManager.removeItem(at: temporaryURL) }
if FileManager.default.fileExists(atPath: temporaryURL.path) {
do { try FileManager.default.removeItem(at: temporaryURL) }
catch { throw InstallError.unableToRemoveTemporaryItem(temporaryURL, error) }
}

// Move replacement to temporary path.
try shell.run("mv", with: [ replacementURL.path, temporaryURL.path ]).orThrow()
return temporaryURL
}

// Permissions
do {
try shell.run("chown", with: [ "-fR", login, temporaryURL.path ]).orThrow()
try shell.run("chmod", with: [ "-fR", "u=rX,go-rwx", temporaryURL.path ]).orThrow()
}

try KvFileKit.replaceItem(at: originalURL, withItemAt: temporaryURL)
private func ownAndSetMinimumPermissions(toItemAt url: URL, shell: KvShell = .init()) throws {
try shell.run("chown", with: [ "-fR", login, url.path ]).orThrow()
try shell.run("chmod", with: [ "-fR", "u=rX,go-rwx", url.path ]).orThrow()
}

}
Expand Down

0 comments on commit 58ce46d

Please sign in to comment.