Skip to content

Commit

Permalink
Merge pull request #12 from faberNovel/feature/fixes
Browse files Browse the repository at this point in the history
Feature/fixes
  • Loading branch information
gaetanzanella authored Jul 22, 2021
2 parents 126bcee + e1bd438 commit d825f57
Show file tree
Hide file tree
Showing 19 changed files with 280 additions and 124 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ xcuserdata
*.xcodeproj
Utilities/Docker/*.tar.gz
.swiftpm
Package.resolved
/build
*.pyc
12 changes: 12 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@

All notable changes to this project will be documented in this file.

## [0.1.3]

### Fixed

- Fixed relative URL parameters #7
- Fixed empty code snippets folder #11

### Updated

- Updated `xcresource snippet remove`: it can not delete custom snippets
- Updated CLI messages

## [0.1.2]

### Updated
Expand Down
16 changes: 16 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "swift-argument-parser",
"repositoryURL": "https://github.com/apple/swift-argument-parser",
"state": {
"branch": null,
"revision": "831ed5e860a70e745bc1337830af4786b2576881",
"version": "0.4.1"
}
}
]
},
"version": 1
}
15 changes: 7 additions & 8 deletions Sources/CLI/XCSnippet/InstallSnippetsCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@ struct InstallSnippetsCommand: ParsableCommand {
// MARK: - ParsableCommand

func run() throws {
guard let url = URL(string: url) else { throw Error.invalidURL }
try XCSnippetCLI().downloadSnippets(
for: .init(namespace),
from: .git(
url: url,
reference: GitReference(pointer),
folderPath: snippetsPath
)
let cli = XCSnippetCLI()
let list = try cli.installSnippets(
url: url,
pointer: pointer,
namespace: namespace,
snippetsPath: snippetsPath
)
print("🎉 \(list.snippets.count) snippets successfully installed")
}
}
21 changes: 4 additions & 17 deletions Sources/CLI/XCSnippet/ListSnippetsCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,11 @@ struct ListSnippetsCommand: ParsableCommand {

func run() throws {
let cli = XCSnippetCLI()
if let namespace = namespace {
let xcnamespace = XCSnippetNamespace(namespace)
try cli.describe(xcnamespace)
} else {
let namespaces = try cli.snippetNamespaces()
try namespaces.forEach { namespace in
try cli.describe(namespace)
try cli.snippetList(namespace: namespace).forEach { namespace, list in
print("#", namespace.name)
list.snippets.forEach { snippet in
print("-", snippet.name)
}
}
}
}

private extension XCSnippetCLI {

func describe(_ namespace: XCSnippetNamespace) throws {
print("#", namespace.name)
try snippetList(for: namespace).snippets.forEach { snippet in
print("-", snippet.name)
}
}
}
6 changes: 3 additions & 3 deletions Sources/CLI/XCSnippet/RemoveSnippetsCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ struct RemoveSnippetsCommand: ParsableCommand {

@Option(
name: .shortAndLong,
help: "The snippet namespace to delete."
help: "The snippet namespace to delete. All the snippets are deleted if not specified."
)
var namespace: String = "FABERNOVEL"
var namespace: String?

public static let configuration = CommandConfiguration(
commandName: "remove",
Expand All @@ -19,6 +19,6 @@ struct RemoveSnippetsCommand: ParsableCommand {
// MARK: - ParsableCommand

func run() throws {
try XCSnippetCLI().removeSnippets(for: XCSnippetNamespace(namespace))
try XCSnippetCLI().removeSnippets(namespace: namespace)
}
}
20 changes: 6 additions & 14 deletions Sources/CLI/XCTemplate/InstallTemplatesCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,12 @@ struct InstallTemplatesCommand: ParsableCommand {
// MARK: - ParsableCommand

func run() throws {
guard let url = URL(string: url) else {
throw Error.invalidURL
}
let templateNamespace = XCTemplateNamespace(namespace)
let cli = XCTemplateCLI()
try cli.downloadTemplates(
for: templateNamespace,
from: .git(
url: url,
reference: GitReference(pointer),
folderPath: templatesPath
)
let folder = try XCTemplateCLI().downloadTemplates(
url: url,
pointer: pointer,
namespace: namespace,
templatesPath: templatesPath
)
let folder = try cli.templateFolder(for: templateNamespace)
print("\(folder.templateCount()) templates successfully installed 🎉")
print("🎉 \(folder.templateCount()) templates successfully installed")
}
}
8 changes: 1 addition & 7 deletions Sources/CLI/XCTemplate/ListTemplatesCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@ struct ListTemplatesCommand: ParsableCommand {
// MARK: - ParsableCommand

func run() throws {
let folder: XCTemplateFolder
let cli = XCTemplateCLI()
if let namespace = namespace {
folder = try cli.templateFolder(for: XCTemplateNamespace(namespace))
} else {
folder = try cli.rootTemplateFolder()
}
let folder = try XCTemplateCLI().templateFolder(namespace: namespace)
if folder.isEmpty() {
print("No templates installed")
} else {
Expand Down
2 changes: 1 addition & 1 deletion Sources/CLI/XCTemplate/RemoveTemplatesCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ struct RemoveTemplatesCommand: ParsableCommand {
// MARK: - ParsableCommand

func run() throws {
try XCTemplateCLI().removeTemplates(for: XCTemplateNamespace(namespace))
try XCTemplateCLI().removeTemplates(namespace: namespace)
}
}
2 changes: 1 addition & 1 deletion Sources/XCResource/Shared/Shell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public struct GitReference {

enum ShellCommand {
case open(path: String)
case gitDownload(url: String, reference: GitReference, destionation: String)
case gitDownload(url: String, reference: GitReference, destination: String)
}

class Shell {
Expand Down
46 changes: 35 additions & 11 deletions Sources/XCResource/XCSnippet/XCSnippetCLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,45 @@ public class XCSnippetCLI {

// MARK: - Public

public func downloadSnippets(for namespace: XCSnippetNamespace,
from source: XCSnippetSource) throws {
try library.installSnippets(for: namespace, from: source)
public func installSnippets(url: String,
pointer: String,
namespace: String,
snippetsPath: String) throws -> XCSnippetList {
let url = try URLInputParser().absoluteURL(fromInput: url)
let namespace = XCSnippetNamespace(namespace)
try library.installSnippets(
for: namespace,
from: .git(
url: url,
reference: GitReference(pointer),
folderPath: snippetsPath
)
)
return try library.snippetList(for: namespace)
}

public func removeSnippets(for namespace: XCSnippetNamespace) throws {
try library.removeSnippets(for: namespace)
public func removeSnippets(namespace: String?) throws {
if let namespace = namespace {
let xcnamespace = XCSnippetNamespace(namespace)
try library.removeSnippets(for: xcnamespace)
} else {
let namespaces = try library.snippetNamespaces().filter { $0 != .xcodeDefault }
try namespaces.forEach { namespace in
try library.removeSnippets(for:namespace)
}
}
}

public func snippetList(for namespace: XCSnippetNamespace) throws -> XCSnippetList {
try library.snippetList(for: namespace)
}

public func snippetNamespaces() throws -> [XCSnippetNamespace] {
try library.snippetNamespaces()
public func snippetList(namespace: String?) throws -> [XCSnippetNamespace: XCSnippetList] {
if let namespace = namespace {
let xcnamespace = XCSnippetNamespace(namespace)
return [xcnamespace: try library.snippetList(for: xcnamespace)]
} else {
let namespaces = try library.snippetNamespaces()
return Dictionary(uniqueKeysWithValues: try namespaces.map {
($0, try library.snippetList(for: $0))
})
}
}

public func openSnippetFolder() throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct GitSourceSnippetDownloadingStrategy: XCSnippetDownloadingStrategy {
try? fileManager.removeItem(at: tmp)
}
try Shell().execute(
.gitDownload(url: url.absoluteString, reference: reference, destionation: tmp.path)
.gitDownload(url: url.absoluteString, reference: reference, destination: tmp.path)
)
let snippetsDirectoryURL = tmp.appendingPathComponent(folderPath)
let snippetURLs = try fileManager.contentsOfDirectory(at: snippetsDirectoryURL)
Expand Down
18 changes: 12 additions & 6 deletions Sources/XCResource/XCSnippet/XCSnippetLibrary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,32 @@ import Foundation

public class XCSnippetLibrary {

private let fileManager: FileManager
private let snippetFileManager: XCSnippetFileManager
private let downloader: XCSnippetsDownloader
private let urlProvider: XCSnippetFolderURLProviding

// MARK: - Life Cycle

public convenience init() {
let snippetFileManager = XCSnippetFileManager(fileManager: .default)
public convenience init(fileManager: FileManager = .default) {
let snippetFileManager = XCSnippetFileManager(fileManager: fileManager)
self.init(
fileManager: fileManager,
snippetFileManager: snippetFileManager,
downloader: XCSnippetsDownloader(
fileManager: .default,
fileManager: fileManager,
snippetFileManager: snippetFileManager,
strategyFactory: XCSnippetDownloadingStrategyFactory(fileManager: .default)
strategyFactory: XCSnippetDownloadingStrategyFactory(fileManager: fileManager)
),
urlProvider: NativeNamespaceFolderURLProvider()
)
}

internal init(snippetFileManager: XCSnippetFileManager,
internal init(fileManager: FileManager,
snippetFileManager: XCSnippetFileManager,
downloader: XCSnippetsDownloader,
urlProvider: XCSnippetFolderURLProviding) {
self.fileManager = fileManager
self.snippetFileManager = snippetFileManager
self.downloader = downloader
self.urlProvider = urlProvider
Expand All @@ -34,8 +38,10 @@ public class XCSnippetLibrary {

public func installSnippets(for namespace: XCSnippetNamespace,
from source: XCSnippetSource) throws {
let destination = urlProvider.rootSnippetFolderURL()
try? fileManager.createDirectory(at: destination, withIntermediateDirectories: true, attributes: nil)
try downloader.downloadSnippets(
at: urlProvider.rootSnippetFolderURL(),
at: destination,
from: source,
namespace: namespace
)
Expand Down
6 changes: 0 additions & 6 deletions Sources/XCResource/XCSnippet/XCSnippetsDownloader.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
//
// File.swift
//
//
// Created by Gaétan Zanella on 07/07/2021.
//

import Foundation

Expand Down
40 changes: 40 additions & 0 deletions Sources/XCResource/XCTemplate/URLInputParser.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

import Foundation

class URLInputParser {

enum ParsingError: Error {
case invalidURL
}

func absoluteURL(fromInput url: String) throws -> URL {
let resultURL: URL
// Issue #7: Handling relative URLs
let fileURL = URL(fileURLWithPath: url)
if url.hasPrefix("~") {
resultURL = expandTildeInPath(url)
} else if url.hasPrefix("/") || fileURL.isReachable() {
resultURL = fileURL
} else if let url = URL(string: url) {
resultURL = url
} else {
throw ParsingError.invalidURL
}
return resultURL.absoluteURL
}

private func expandTildeInPath(_ path: String) -> URL {
URL(fileURLWithPath: NSString(string: path).expandingTildeInPath).standardized
}
}

private extension URL {

func isReachable() -> Bool {
do {
return try checkResourceIsReachable()
} catch {
return false
}
}
}
Loading

0 comments on commit d825f57

Please sign in to comment.