從零寫一個Cocoa庫依賴管理工具(一):建立工程結構和添加依賴

工程結構

初步結構以下圖git

屏幕快照 2020-01-10 下午6.41.29.png

暫時一共有7個Target,和SPM大體同樣,隨着項目進行會調整:github

  1. nabla:包含main.swift。
  2. Commands:全部的命令行。
  3. Build:提供編譯功能,如將一個將依賴庫編譯成framework。
  4. PackageGraph:依賴管理。
  5. PageModel:包含所須要的一些基本Model。
  6. SourceControl:負責git下載和管理依賴庫。
  7. Workspace:一個工程的全部操做的管理者。
  8. Xcodeproj:表示一個xocde的工程結構,提供修改xcodeproj,和生成xcworkspace的能力。

依賴的庫

在寫的時候一來爲了減小依賴,二來確實蘋果官方的庫寫的挺好,因此會盡可能用蘋果官方庫。寫一個命令行工具通常須要有三個基礎能力:swift

寫好命令行:如今開源的有CommanderCommandant,這個是Carthage社區的,Guaka。然而這些咱們都不會用,蘋果官方的swift-tools-support-coreArgumentParser提供這種能力,只不過上手要稍微難一些,SPM和llbuild都是使用swift-tools-support-core。xcode

路徑搜索和文件管理: 如今開源的有PathKitPath.swiftPath.swift是Homebrew做者寫的,用過挺不錯的,不過咱們依然選擇使用蘋果官方的swift-tools-support-coreAbsolutePathbash

調用其餘命令行工具:好比咱們須要調用git命令和xcodebuild命令,如今開源的有SwiftShellSwiftCLI,咱們依舊選着蘋果官方的swift-tools-support-coreProcess😂,這個工具備一個缺點就是不能設置currentDirectoryPath,不過咱們也用不到。固然你也能夠本身實現,簡單版就以下所示:app

func exec(_ cmd: String, currentDirectory: String? = nil, env: [String: String]? = nil, _ args: [String]) -> (output: String, error: String, exitCode: Int32) {

    let task = Process()
    task.launchPath = cmd
    task.arguments = args
    if let currentDirectory = currentDirectory {
        task.currentDirectoryPath = currentDirectory
    }
    if let env = env {
        task.environment = mergeEnv(env)
    }

    let outpipe = Pipe()
    task.standardOutput = outpipe
    let errpipe = Pipe()
    task.standardError = errpipe

    task.launch()

    let outdata = outpipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: outdata, encoding: .utf8)!.trimmingCharacters(in: .whitespacesAndNewlines)

    let errdata = errpipe.fileHandleForReading.readDataToEndOfFile()
    let error = String(data: errdata, encoding: .utf8)!.trimmingCharacters(in: .whitespacesAndNewlines)

    task.waitUntilExit()
    let status = task.terminationStatus

    return (output, error, status)
}

func mergeEnv(_ env: [String: String]) -> [String: String] {
    var e = ProcessInfo.processInfo.environment
    for (key, value) in env {
        e[key] = value
    }
    return e
}

複製代碼

最後由於咱們暫時是經過.yml文件來配置項目和依賴,因此須要引入Yams工具

配置Package.swift

工程結構和依賴庫都已經定好了,配置Package.swift就比較簡單了,這裏就不細講了,能夠直接拉下來工程看代碼。ui

編寫Makefile

咱們須要經過Makefile來編譯咱們項目,而後將生成的可執行命令行工具nabla拷貝到/usr/local/bin來方便咱們在終端調試,暫時只先實現最簡單功能。spa

usr_local ?= /usr/local

bindir = $(usr_local)/bin
libdir = $(usr_local)/lib

build:
	swift build -c release --disable-sandbox

install: build
	install ".build/release/nabla" "$(bindir)"

uninstall:
	rm -rf "$(bindir)/nabla"
    
clean:
	rm -rf .build

.PHONY: build install uninstall clean

複製代碼

這裏只有一個點須要注意,--disable-sandbox,這樣纔有用戶home directory的讀寫權限。命令行

你們在調試的時候只須要執行如下操做在終端調試nabla了。

$ git clone https://github.com/woshiccm/Pecker.git
$ cd Pecker
$ make install
複製代碼

項目地址

Nabla

最後

才寫了第一篇就感受好花時間並且寫的又亂又水😓。

相關文章
相關標籤/搜索