Restructured the folder structure of the library target.

This commit is contained in:
2025-01-17 23:21:25 +01:00
parent 6955d816ef
commit 04bd2a1160
12 changed files with 2 additions and 2 deletions
@@ -0,0 +1,35 @@
import Foundation
extension URL {
// MARK: Initialisers
init(at filePath: String) {
if #available(macOS 13.0, *) {
self = URL(filePath: filePath)
} else {
self = URL(fileURLWithPath: filePath)
}
}
// MARK: Computed
var pathString: String {
if #available(macOS 13.0, *) {
path()
} else {
path
}
}
// MARK: Functions
func appendingPath(_ path: String) -> URL {
if #available(macOS 13.0, *) {
appending(path: path)
} else {
appendingPathComponent(path)
}
}
}
@@ -0,0 +1,27 @@
import Foundation
public protocol FileServicing {
// MARK: Computed
var currentFolder: URL { get async }
// MARK: Functions
func copyItem(from source: URL, to destination: URL) async throws (FileServiceError)
func createFolder(at location: URL) async throws (FileServiceError)
func deleteItem(at location: URL) async throws (FileServiceError)
func isItemExists(at location: URL) async throws (FileServiceError) -> Bool
}
// MARK: - Errors
public enum FileServiceError: Error, Equatable {
case folderNotCreated
case itemNotCopied
case itemAlreadyExists
case itemNotDeleted
case itemNotExists
case itemNotFileURL
}
@@ -0,0 +1,74 @@
import Foundation
public struct FileService: FileServicing {
// MARK: Properties
private let fileManager: FileManager
// MARK: Initialisers
public init(fileManager: FileManager = .default) {
self.fileManager = fileManager
}
// MARK: Computed
public var currentFolder: URL {
get async {
.init(at: fileManager.currentDirectoryPath)
}
}
// MARK: Functions
public func copyItem(from source: URL, to destination: URL) async throws (FileServiceError) {
guard try await isItemExists(at: source) else {
throw FileServiceError.itemNotExists
}
guard try await !isItemExists(at: destination) else {
throw FileServiceError.itemAlreadyExists
}
do {
try fileManager.copyItem(at: source, to: destination)
} catch {
throw FileServiceError.itemNotCopied
}
}
public func createFolder(at location: URL) async throws (FileServiceError) {
guard try await !isItemExists(at: location) else {
throw FileServiceError.itemAlreadyExists
}
do {
try fileManager.createDirectory(at: location, withIntermediateDirectories: true)
} catch {
throw FileServiceError.folderNotCreated
}
}
public func deleteItem(at location: URL) async throws (FileServiceError) {
guard try await isItemExists(at: location) else {
throw FileServiceError.itemNotExists
}
do {
try fileManager.removeItem(at: location)
} catch {
throw FileServiceError.itemNotDeleted
}
}
public func isItemExists(at location: URL) async throws (FileServiceError) -> Bool {
guard location.isFileURL else {
throw FileServiceError.itemNotFileURL
}
let filePath = location.pathString
return fileManager.fileExists(atPath: filePath)
}
}
+53
View File
@@ -0,0 +1,53 @@
import Foundation
public struct CopyFilesTask {
// MARK: Properties
private let fileService: FileServicing
// MARK: Initialisers
public init(fileService: FileServicing) {
self.fileService = fileService
}
// MARK: Functions
public func callAsFunction(to rootFolder: URL) async throws {
let filesFolder = URL(at: .folderFiles)
for fileToCopy in Self.filesToCopy {
try await fileService.copyItem(
from: filesFolder.appendingPath(fileToCopy),
to: rootFolder.appendingPath(fileToCopy)
)
}
}
}
// MARK: - Helpers
extension CopyFilesTask {
// MARK: Constants
static let filesToCopy: [String] = [
.fileDockerIgnore,
.fileGitIgnore,
.fileLicense,
.fileReadme
]
}
// MARK: - URL+Constants
private extension String {
static let folderFiles = "./Resources/Files"
static let fileDockerIgnore = ".dockerignore"
static let fileGitIgnore = ".gitignore"
static let fileLicense = "LICENSE"
static let fileReadme = "README.md"
}
@@ -0,0 +1,49 @@
import Foundation
public struct CreateFoldersTask {
// MARK: Properties
private let fileService: FileServicing
// MARK: Initialisers
public init(fileService: FileServicing) {
self.fileService = fileService
}
// MARK: Functions
public func callAsFunction(at rootFolder: URL) async throws {
let folders = Self.foldersToCreate.map { rootFolder.appendingPath($0) }
for folder in folders {
try await fileService.createFolder(at: folder)
}
}
}
// MARK: - Helpers
extension CreateFoldersTask {
// MARK: Constants
static let foldersToCreate: [String] = [
.folderApp,
.folderAppInfrastructure,
.folderAppTestCases,
.folderAppTestSources
]
}
// MARK: - String+Constants
private extension String {
static let folderApp = "Sources/App"
static let folderAppInfrastructure = "Sources/AppInfrastructure"
static let folderAppTestCases = "Tests/App/Cases"
static let folderAppTestSources = "Tests/App/Sources"
}
@@ -0,0 +1,44 @@
import Foundation
public struct CreateRootFolderTask {
// MARK: Properties
private let fileService: FileServicing
// MARK: Initialisers
public init(fileService: FileServicing) {
self.fileService = fileService
}
// MARK: Functions
public func callAsFunction(
name: String,
at location: URL? = nil
) async throws -> URL {
guard !name.isEmpty else {
throw CreateRootFolderError.nameIsEmpty
}
let rootFolder = if let location {
location
} else {
await fileService.currentFolder
}
let newFolder = rootFolder.appendingPath(name)
try await fileService.createFolder(at: newFolder)
return newFolder
}
}
// MARK: - Errors
public enum CreateRootFolderError: Error {
case nameIsEmpty
}