diff --git a/Sources/AdventOfCode.swift b/Sources/AdventOfCode.swift index f199437..848f6fd 100644 --- a/Sources/AdventOfCode.swift +++ b/Sources/AdventOfCode.swift @@ -1,8 +1,34 @@ import ArgumentParser +import Foundation // Add each new day implementation to this array: let allChallenges: [any AdventDay] = [ - Day00() + Day00(), +// Day01(), +// Day02(), +// Day03(), +// Day04(), +// Day05(), +// Day06(), +// Day07(), +// Day08(), +// Day09(), +// Day10(), +// Day11(), +// Day12(), +// Day13(), +// Day14(), +// Day15(), +// Day16(), +// Day17(), +// Day18(), +// Day19(), +// Day20(), +// Day21(), +// Day22(), +// Day23(), +// Day24(), +// Day25(), ] @main @@ -10,6 +36,9 @@ struct AdventOfCode: AsyncParsableCommand { @Argument(help: "The day of the challenge. For December 1st, use '1'.") var day: Int? + @Flag(help: "Create new code, data, and test files for the next day.") + var new: Bool = false + @Flag(help: "Benchmark the time taken by the solution") var benchmark: Bool = false @@ -57,6 +86,16 @@ struct AdventOfCode: AsyncParsableCommand { } func run() async throws { + if self.new { + let day = (allChallenges.last?.day ?? 0) + 1 + try createFiles(for: day) + let year = Calendar(identifier: .gregorian).component(.year, from: Date()) + try uncommentAllChallenges(for: day) + print("See your question at https://adventofcode.com/\(year)/day/\(day)") + print("Good luck!") + return + } + let challenges = if all { allChallenges @@ -78,4 +117,49 @@ struct AdventOfCode: AsyncParsableCommand { } } } + + private func createFiles(for day: Int) throws { + let fileManager = FileManager.default + let currentPath = fileManager.currentDirectoryPath + let className = String(format: "Day%02d", Int(day)) + + // Data file + let newDataFilePath = "\(currentPath)/Sources/Data/\(className).txt" + try createFile(atPath: newDataFilePath, content: "") + + // Code file + let templateFilePath = "\(currentPath)/Sources/DayTemplate.swift" + let newCodeFilePath = "\(currentPath)/Sources/\(className).swift" + let newCodeFileContent = try String(contentsOfFile: templateFilePath, encoding: .utf8) + .replacingOccurrences(of: "DayTemplate", with: className) + try createFile(atPath: newCodeFilePath, content: newCodeFileContent) + + // Test file + let templateTestFilePath = "\(currentPath)/Tests/DayTemplate.swift" + let newTestFilePath = "\(currentPath)/Tests/\(className).swift" + let newTestFileContent = try String(contentsOfFile: templateTestFilePath, encoding: .utf8) + .replacingOccurrences(of: "DayTemplate", with: className) + try createFile(atPath: newTestFilePath, content: newTestFileContent) + } + + private func createFile(atPath path: String, content: String) throws { + let fileManager = FileManager.default + guard !fileManager.fileExists(atPath: path) else { + fatalError("File already exists at \(path).") + } + try content.write(toFile: path, atomically: true, encoding: .utf8) + print("Created \(path)") + } + + private func uncommentAllChallenges(for day: Int) throws { + let fileManager = FileManager.default + let currentPath = fileManager.currentDirectoryPath + let filePath = "\(currentPath)/Sources/AdventOfCode.swift" + let className = String(format: "Day%02d", Int(day)) + + let fileContent = try String(contentsOfFile: filePath, encoding: .utf8) + let newFileContent = fileContent.replacingOccurrences(of: "// \(className)()", with: " \(className)()") + try newFileContent.write(toFile: filePath, atomically: true, encoding: .utf8) + } + } diff --git a/Sources/DayTemplate.swift b/Sources/DayTemplate.swift new file mode 100644 index 0000000..80c92c6 --- /dev/null +++ b/Sources/DayTemplate.swift @@ -0,0 +1,16 @@ +import Foundation + +final class DayTemplate: AdventDay { + + init(data: String) { + } + + func part1() -> Any { + return 0 + } + + func part2() -> Any { + return 0 + } + +} diff --git a/Tests/DayTemplate.swift b/Tests/DayTemplate.swift new file mode 100644 index 0000000..7fedf35 --- /dev/null +++ b/Tests/DayTemplate.swift @@ -0,0 +1,21 @@ +import Testing + +@testable import AdventOfCode + +final class DayTemplateTests { + + let testData = """ + + """ + + @Test func testPart1() async throws { + let challenge = DayTemplate(data: testData) + #expect(String(describing: challenge.part1()) == "") + } + + @Test func testPart2() async throws { + let challenge = DayTemplate(data: testData) + #expect(String(describing: challenge.part2()) == "") + } + +}