diff --git a/Sources/swcomp/Containers/TarCommand.swift b/Sources/swcomp/Containers/TarCommand.swift index 54ec091d..c37db1ea 100644 --- a/Sources/swcomp/Containers/TarCommand.swift +++ b/Sources/swcomp/Containers/TarCommand.swift @@ -92,94 +92,10 @@ class TarCommand: Command { print("Creating new container at \"\(self.archive.value)\" from \"\(inputPath)\"") print("d = directory, f = file, l = symbolic link") } - let entries = try self.createEntries(inputPath, verbose.value) + let entries = try TarEntry.createEntries(inputPath, verbose.value) let containerData = TarContainer.create(from: entries) try containerData.write(to: URL(fileURLWithPath: self.archive.value)) } } - private func createEntries(_ inputPath: String, _ verbose: Bool) throws -> [TarEntry] { - let inputURL = URL(fileURLWithPath: inputPath) - let fileManager = FileManager.default - - let fileAttributes = try fileManager.attributesOfItem(atPath: inputPath) - - let name = inputURL.relativePath - - let entryType: ContainerEntryType - if let typeFromAttributes = fileAttributes[.type] as? FileAttributeType { - switch typeFromAttributes { - case .typeBlockSpecial: - entryType = .blockSpecial - case .typeCharacterSpecial: - entryType = .characterSpecial - case .typeDirectory: - entryType = .directory - case .typeRegular: - entryType = .regular - case .typeSocket: - entryType = .socket - case .typeSymbolicLink: - entryType = .symbolicLink - case .typeUnknown: - entryType = .unknown - default: - entryType = .unknown - } - } else { - entryType = .unknown - } - - var info = TarEntryInfo(name: name, type: entryType) - info.creationTime = fileAttributes[.creationDate] as? Date - info.groupID = (fileAttributes[.groupOwnerAccountID] as? NSNumber)?.intValue - info.ownerGroupName = fileAttributes[.groupOwnerAccountName] as? String - info.modificationTime = fileAttributes[.modificationDate] as? Date - info.ownerID = (fileAttributes[.ownerAccountID] as? NSNumber)?.intValue - info.ownerUserName = fileAttributes[.ownerAccountName] as? String - if let posixPermissions = (fileAttributes[.posixPermissions] as? NSNumber)?.intValue { - info.permissions = Permissions(rawValue: UInt32(truncatingIfNeeded: posixPermissions)) - } - - var entryData = Data() - if entryType == .symbolicLink { - info.linkName = try fileManager.destinationOfSymbolicLink(atPath: inputPath) - } else if entryType != .directory { - entryData = try Data(contentsOf: URL(fileURLWithPath: inputPath)) - } - - if verbose { - var log = "" - switch entryType { - case .regular: - log += "f: " - case .directory: - log += "d: " - case .symbolicLink: - log += "l:" - default: - log += "u: " - } - log += name - if entryType == .symbolicLink { - log += " -> " + info.linkName - } - print(log) - } - - let entry = TarEntry(info: info, data: entryData) - - var entries = [TarEntry]() - entries.append(entry) - - if entryType == .directory { - for subPath in try fileManager.contentsOfDirectory(atPath: inputPath) { - entries.append(contentsOf: try self.createEntries(inputURL.appendingPathComponent(subPath).relativePath, - verbose)) - } - } - - return entries - } - } diff --git a/Sources/swcomp/Extensions/TarEntry+Create.swift b/Sources/swcomp/Extensions/TarEntry+Create.swift new file mode 100644 index 00000000..2e6ddcaa --- /dev/null +++ b/Sources/swcomp/Extensions/TarEntry+Create.swift @@ -0,0 +1,96 @@ +// Copyright (c) 2021 Timofey Solomko +// Licensed under MIT License +// +// See LICENSE for license information + +import Foundation +import SWCompression +import SwiftCLI + +extension TarEntry { + + static func createEntries(_ inputPath: String, _ verbose: Bool) throws -> [TarEntry] { + let inputURL = URL(fileURLWithPath: inputPath) + let fileManager = FileManager.default + + let fileAttributes = try fileManager.attributesOfItem(atPath: inputPath) + + let name = inputURL.relativePath + + let entryType: ContainerEntryType + if let typeFromAttributes = fileAttributes[.type] as? FileAttributeType { + switch typeFromAttributes { + case .typeBlockSpecial: + entryType = .blockSpecial + case .typeCharacterSpecial: + entryType = .characterSpecial + case .typeDirectory: + entryType = .directory + case .typeRegular: + entryType = .regular + case .typeSocket: + entryType = .socket + case .typeSymbolicLink: + entryType = .symbolicLink + case .typeUnknown: + entryType = .unknown + default: + entryType = .unknown + } + } else { + entryType = .unknown + } + + var info = TarEntryInfo(name: name, type: entryType) + info.creationTime = fileAttributes[.creationDate] as? Date + info.groupID = (fileAttributes[.groupOwnerAccountID] as? NSNumber)?.intValue + info.ownerGroupName = fileAttributes[.groupOwnerAccountName] as? String + info.modificationTime = fileAttributes[.modificationDate] as? Date + info.ownerID = (fileAttributes[.ownerAccountID] as? NSNumber)?.intValue + info.ownerUserName = fileAttributes[.ownerAccountName] as? String + if let posixPermissions = (fileAttributes[.posixPermissions] as? NSNumber)?.intValue { + info.permissions = Permissions(rawValue: UInt32(truncatingIfNeeded: posixPermissions)) + } + + var entryData = Data() + if entryType == .symbolicLink { + info.linkName = try fileManager.destinationOfSymbolicLink(atPath: inputPath) + } else if entryType != .directory { + entryData = try Data(contentsOf: URL(fileURLWithPath: inputPath)) + } + + if verbose { + var log = "" + switch entryType { + case .regular: + log += "f: " + case .directory: + log += "d: " + case .symbolicLink: + log += "l:" + default: + log += "u: " + } + log += name + if entryType == .symbolicLink { + log += " -> " + info.linkName + } + print(log) + } + + let entry = TarEntry(info: info, data: entryData) + + var entries = [TarEntry]() + entries.append(entry) + + if entryType == .directory { + for subPath in try fileManager.contentsOfDirectory(atPath: inputPath) { + entries.append(contentsOf: try self.createEntries(inputURL.appendingPathComponent(subPath).relativePath, + verbose)) + } + } + + return entries + } + +}