Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux building #4

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,23 @@ jobs:

- name: Run tests
run: swift test -v

build-linux:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Swift 6.0
uses: swift-actions/setup-swift@v2.2.0
with:
swift-version: "6.0"

- name: Verify Swift version
run: swift --version

- name: Build
run: swift build -v

- name: Run tests
run: swift test -v
3 changes: 3 additions & 0 deletions Demos/SwiftIMAPCLI/OSLogHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//

import Foundation

#if canImport(OSLog)
import OSLog
import Logging

Expand Down Expand Up @@ -57,3 +59,4 @@ struct OSLogHandler: LogHandler {
os_log("%{public}@", log: log, type: type, message.description)
}
}
#endif
129 changes: 61 additions & 68 deletions Demos/SwiftIMAPCLI/main.swift
Original file line number Diff line number Diff line change
@@ -1,128 +1,121 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book

import Foundation
import SwiftIMAP
import os
import Logging
import SwiftDotenv
import NIOIMAP

// Set default log level to info - will only show important logs
// Per the cursor rules: Use OS_LOG_DISABLE=1 to see log output as needed
#if canImport(os)
import os
#endif

#if os(Linux)
LoggingSystem.bootstrap { label in
var handler = StreamLogHandler.standardOutput(label: label)
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
handler.logLevel = .trace
} else {
handler.logLevel = .info
}
return handler
}
#else
LoggingSystem.bootstrap { label in
// Create an OSLog-based logger
let category = label.split(separator: ".").last?.description ?? "default"
let osLogger = OSLog(subsystem: "com.cocoanetics.SwiftIMAPCLI", category: category)

// Set log level to info by default (or trace if verbose logging is enabled)
var handler = OSLogHandler(label: label, log: osLogger)
// Check if we need verbose logging
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
handler.logLevel = .trace
} else {
handler.logLevel = .info
}

return handler
}
#endif

// Create a logger for the main application using Swift Logging
let logger = Logger(label: "com.cocoanetics.SwiftIMAPCLI.Main")

print("📧 SwiftIMAPCLI - Email Reading Test")

do {
// Configure SwiftDotenv with the specified path
print("🔍 Looking for .env file...")

// Try loading the .env file
do {
try Dotenv.configure()
print("✅ Environment configuration loaded successfully")
} catch {
print("❌ Failed to load .env file: \(error.localizedDescription)")
exit(1)
}

// Print the loaded variables to verify

print("📋 Loaded environment variables:")

// Access IMAP credentials using dynamic member lookup with case pattern matching
guard case let .string(host) = Dotenv["IMAP_HOST"] else {
print("❌ IMAP_HOST not found in .env file")
logger.error("IMAP_HOST not found in .env file")
exit(1)
}

print(" IMAP_HOST: \(host)")

guard case let .integer(port) = Dotenv["IMAP_PORT"] else {
print("❌ IMAP_PORT not found or invalid in .env file")
logger.error("IMAP_PORT not found or invalid in .env file")
exit(1)
}

print(" IMAP_PORT: \(port)")

guard case let .string(username) = Dotenv["IMAP_USERNAME"] else {
print("❌ IMAP_USERNAME not found in .env file")
logger.error("IMAP_USERNAME not found in .env file")
exit(1)
}

print(" IMAP_USERNAME: \(username)")

guard case let .string(password) = Dotenv["IMAP_PASSWORD"] else {
logger.error("IMAP_PASSWORD not found in .env file")
exit(1)
}

logger.info("IMAP credentials loaded successfully")
logger.info("Host: \(host)")
logger.info("Port: \(port)")
logger.info("Username: \(username)")

// Create an IMAP server instance

let server = IMAPServer(host: host, port: port)

do {
try await server.connect()
try await server.login(username: username, password: password)

// List special folders
let specialFolders = try await server.listSpecialUseMailboxes()

// Display special folders
print("\nSpecial Folders:")
for folder in specialFolders {
print("- \(folder.name)")
}

guard let inbox = specialFolders.inbox else {
fatalError("INBOX mailbox not found")
}

// Select the INBOX mailbox and get mailbox information
let mailboxStatus = try await server.selectMailbox(inbox.name)

// Use the convenience method to get the latest 10 messages
if let latestMessagesSet = mailboxStatus.latest(10) {
let emails = try await server.fetchMessages(using: latestMessagesSet)

print("\n📧 Latest Emails (\(emails.count)) 📧")

for (index, email) in emails.enumerated() {
print("\n[\(index + 1)/\(emails.count)] \(email.debugDescription)")
print("---")
}
} else {
print("No messages found in INBOX")
}

try await server.disconnect()
} catch {
logger.error("Error: \(error.localizedDescription)")
exit(1)
}

do {
try await server.connect()
try await server.login(username: username, password: password)

let specialFolders = try await server.listSpecialUseMailboxes()

print("\nSpecial Folders:")
for folder in specialFolders {
print("- \(folder.name)")
}

guard let inbox = specialFolders.inbox else {
fatalError("INBOX mailbox not found")
}

let mailboxStatus = try await server.selectMailbox(inbox.name)

if let latestMessagesSet = mailboxStatus.latest(10) {
let emails = try await server.fetchMessages(using: latestMessagesSet)

print("\n📧 Latest Emails (\(emails.count)) 📧")

for (index, email) in emails.enumerated() {
print("\n[\(index + 1)/\(emails.count)] \(email.debugDescription)")
print("---")
}
} else {
print("No messages found in INBOX")
}

try await server.disconnect()
} catch {
logger.error("Error: \(error.localizedDescription)")
exit(1)
}
}
3 changes: 3 additions & 0 deletions Demos/SwiftSMTPCLI/OSLogHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//

import Foundation

#if canImport(OSLog)
import OSLog
import Logging

Expand Down Expand Up @@ -57,3 +59,4 @@ struct OSLogHandler: LogHandler {
os_log("%{public}@", log: log, type: type, message.description)
}
}
#endif
25 changes: 18 additions & 7 deletions Demos/SwiftSMTPCLI/main.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book

import Foundation
import SwiftSMTP
import OSLog
import Logging
import SwiftDotenv
import SwiftMailCore

#if canImport(OSLog)
import OSLog
#endif

#if os(Linux)
LoggingSystem.bootstrap { label in
var handler = StreamLogHandler.standardOutput(label: label)
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
handler.logLevel = .trace
} else {
handler.logLevel = .info
}
return handler
}
#else
// Set default log level to info - will only show important logs
// Per the cursor rules: Use OS_LOG_DISABLE=1 to see log output as needed
LoggingSystem.bootstrap { label in
Expand All @@ -18,7 +29,7 @@ LoggingSystem.bootstrap { label in
// Set log level to info by default (or trace if SWIFT_LOG_LEVEL is set to trace)
var handler = OSLogHandler(label: label, log: osLogger)

// Check if we need verbose logging
// Check if we need verbose logging
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
handler.logLevel = .trace
} else {
Expand All @@ -27,6 +38,7 @@ LoggingSystem.bootstrap { label in

return handler
}
#endif

// Create a logger for the main application using Swift Logging
let logger = Logger(label: "com.cocoanetics.SwiftSMTPCLI.Main")
Expand Down Expand Up @@ -74,7 +86,7 @@ do {
// Login with credentials
print("Authenticating...")

let authSuccess = try await server.authenticate(username: username, password: password)
let authSuccess = try await server.authenticate(username: username, password: password)

if authSuccess {
logger.info("Authentication successful")
Expand Down Expand Up @@ -114,4 +126,3 @@ do {
logger.error("Error: \(error.localizedDescription)")
exit(1)
}

Loading
Loading