commit 7942399f089e769c7ed3ce520ac42c14a2c76bab
Author: Anton Konyahin <me@konyahin.xyz>
Date: Fri, 31 Dec 2021 17:15:31 +0300
first commit
Diffstat:
7 files changed, 172 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+/.build
+/Packages
+/*.xcodeproj
+xcuserdata/
diff --git a/Package.swift b/Package.swift
@@ -0,0 +1,21 @@
+// swift-tools-version:5.3
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "chponk",
+ platforms: [
+ .macOS(.v10_12)
+ ],
+ dependencies: [
+ ],
+ targets: [
+ .target(
+ name: "chponk",
+ dependencies: []),
+ .testTarget(
+ name: "chponkTests",
+ dependencies: ["chponk"]),
+ ]
+)
diff --git a/README.md b/README.md
@@ -0,0 +1,3 @@
+# chponk
+
+A description of this package.
diff --git a/Sources/chponk/main.swift b/Sources/chponk/main.swift
@@ -0,0 +1,80 @@
+import AppKit
+import Foundation
+
+if CommandLine.arguments.count < 2 {
+ print("Usage: chponk minutes [title]")
+ exit(0)
+}
+let originalTime = Int(CommandLine.arguments[1])! * 60
+var time = originalTime
+
+let title = CommandLine.arguments.count > 2 ? CommandLine.arguments[2] : ""
+
+let app = NSApplication.shared
+let statusItem = NSStatusBar.system
+ .statusItem(withLength: NSStatusItem.variableLength)
+
+let menu = NSMenu()
+menu.addItem(
+ NSMenuItem(
+ title: "Repeat \(formatTime(time:originalTime))",
+ action: #selector(app.again),
+ keyEquivalent: ""))
+menu.addItem(
+ NSMenuItem(
+ title: "Stop",
+ action: #selector(app.reset),
+ keyEquivalent: ""))
+menu.addItem(
+ NSMenuItem(
+ title: "Quit",
+ action: #selector(app.quit),
+ keyEquivalent: ""))
+statusItem.menu = menu
+
+app.again()
+app.setActivationPolicy(.prohibited)
+app.run()
+
+extension NSApplication {
+ @objc func again() {
+ time = originalTime
+ startTimer()
+ refreshStatusBar()
+ }
+
+ @objc func reset() {
+ time = 0
+ refreshStatusBar()
+ }
+
+ @objc func quit() {
+ exit(0)
+ }
+}
+
+func refreshStatusBar() {
+ if (time > 0) {
+ statusItem.button?.title = "\(title) \(formatTime(time:time)) \u{1F3C3}"
+ } else {
+ statusItem.button?.title = "\u{1F6B6}"
+ }
+}
+
+func startTimer() {
+ Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) {
+ timer in
+ time -= 1
+ refreshStatusBar()
+ if (time <= 0) {
+ NSSound(named: NSSound.Name("Purr"))?.play()
+ timer.invalidate()
+ }
+ }
+}
+
+func formatTime(time: Int) -> String {
+ let minutes = String(format: "%.02d", time / 60)
+ let seconds = String(format: "%.02d", time % 60)
+ return "\(minutes):\(seconds)"
+}
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
@@ -0,0 +1,7 @@
+import XCTest
+
+import chponkTests
+
+var tests = [XCTestCaseEntry]()
+tests += chponkTests.allTests()
+XCTMain(tests)
diff --git a/Tests/chponkTests/XCTestManifests.swift b/Tests/chponkTests/XCTestManifests.swift
@@ -0,0 +1,9 @@
+import XCTest
+
+#if !canImport(ObjectiveC)
+public func allTests() -> [XCTestCaseEntry] {
+ return [
+ testCase(chponkTests.allTests),
+ ]
+}
+#endif
diff --git a/Tests/chponkTests/chponkTests.swift b/Tests/chponkTests/chponkTests.swift
@@ -0,0 +1,47 @@
+import XCTest
+import class Foundation.Bundle
+
+final class chponkTests: XCTestCase {
+ func testExample() throws {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct
+ // results.
+
+ // Some of the APIs that we use below are available in macOS 10.13 and above.
+ guard #available(macOS 10.13, *) else {
+ return
+ }
+
+ let fooBinary = productsDirectory.appendingPathComponent("chponk")
+
+ let process = Process()
+ process.executableURL = fooBinary
+
+ let pipe = Pipe()
+ process.standardOutput = pipe
+
+ try process.run()
+ process.waitUntilExit()
+
+ let data = pipe.fileHandleForReading.readDataToEndOfFile()
+ let output = String(data: data, encoding: .utf8)
+
+ XCTAssertEqual(output, "Hello, world!\n")
+ }
+
+ /// Returns path to the built products directory.
+ var productsDirectory: URL {
+ #if os(macOS)
+ for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
+ return bundle.bundleURL.deletingLastPathComponent()
+ }
+ fatalError("couldn't find the products directory")
+ #else
+ return Bundle.main.bundleURL
+ #endif
+ }
+
+ static var allTests = [
+ ("testExample", testExample),
+ ]
+}