-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add asset download command to improve supporting source file setup (#101
) Usage: `$ mockingbird download <asset>` - `starter-pack` Starter supporting source files The command will download an asset bundle from the current versioned release and unarchive the `.zip` bundle. Bundles are safely merged with existing files on disk, such that files will never be overwritten.
- Loading branch information
1 parent
986d155
commit 0ffb6a8
Showing
15 changed files
with
3,990 additions
and
3,664 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>CFBundleDevelopmentRegion</key> | ||
<string>en</string> | ||
<key>CFBundleExecutable</key> | ||
<string>$(EXECUTABLE_NAME)</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>$(PRODUCT_NAME)</string> | ||
<key>CFBundlePackageType</key> | ||
<string>FMWK</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0</string> | ||
<key>CFBundleSignature</key> | ||
<string>????</string> | ||
<key>CFBundleVersion</key> | ||
<string>$(CURRENT_PROJECT_VERSION)</string> | ||
<key>NSPrincipalClass</key> | ||
<string></string> | ||
</dict> | ||
</plist> |
Large diffs are not rendered by default.
Oops, something went wrong.
2 changes: 1 addition & 1 deletion
2
Mockingbird.xcodeproj/xcshareddata/xcschemes/MockingbirdFramework.xcscheme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
MockingbirdCli/Interface/Commands/DownloadCommand.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// | ||
// DownloadCommand.swift | ||
// MockingbirdCli | ||
// | ||
// Created by Andrew Chang on 4/26/20. | ||
// | ||
|
||
import Foundation | ||
import MockingbirdGenerator | ||
import PathKit | ||
import SPMUtility | ||
import ZIPFoundation | ||
|
||
enum AssetBundleType: String, ArgumentKind, CaseIterable, CustomStringConvertible { | ||
case starterPack = "starter-pack" | ||
|
||
init(argument: String) throws { | ||
guard AssetBundleType(rawValue: argument) != nil else { | ||
let allOptions = AssetBundleType.allCases.map({ $0.rawValue }).joined(separator: ", ") | ||
throw ArgumentParserError.invalidValue( | ||
argument: "asset", | ||
error: .custom("\(argument.singleQuoted) is not a valid download type, expected: \(allOptions)") | ||
) | ||
} | ||
self.init(rawValue: argument)! | ||
} | ||
|
||
static var completion: ShellCompletion { | ||
return .values(AssetBundleType.allCases.map({ | ||
(value: $0.rawValue, description: "\($0)") | ||
})) | ||
} | ||
|
||
var description: String { | ||
switch self { | ||
case .starterPack: return "Starter supporting source files." | ||
} | ||
} | ||
|
||
private func assetBundleUrl(for fileName: String) -> Foundation.URL { | ||
return Foundation.URL(string: | ||
"https://github.com/birdrides/mockingbird/releases/download/\(mockingbirdVersion)/\(fileName)" | ||
)! | ||
} | ||
var url: Foundation.URL { | ||
switch self { | ||
case .starterPack: return assetBundleUrl(for: "MockingbirdSupport.zip") | ||
} | ||
} | ||
} | ||
|
||
final class DownloadCommand: BaseCommand { | ||
private enum Constants { | ||
static let name = "download" | ||
static let overview = "Download and unpack a compatible asset bundle." | ||
|
||
static let excludedAssetRootDirectories: Set<String> = [ | ||
"__MACOSX", | ||
] | ||
static let excludedAssetFileNames: Set<String> = [ | ||
".DS_Store", | ||
] | ||
} | ||
override var name: String { return Constants.name } | ||
override var overview: String { return Constants.overview } | ||
|
||
private let assetBundleTypeArgument: PositionalArgument<AssetBundleType> | ||
private let projectPathArgument: OptionArgument<PathArgument> | ||
|
||
required init(parser: ArgumentParser) { | ||
let subparser = parser.add(subparser: Constants.name, overview: Constants.overview) | ||
self.assetBundleTypeArgument = subparser.addAssetBundleType() | ||
self.projectPathArgument = subparser.addProjectPath() | ||
super.init(parser: subparser) | ||
} | ||
|
||
override func run(with arguments: ArgumentParser.Result, | ||
environment: [String: String], | ||
workingPath: Path) throws { | ||
let projectPath = try arguments.getProjectPath(using: projectPathArgument, | ||
environment: environment, | ||
workingPath: workingPath) | ||
let inferredRootPath = projectPath.parent() | ||
|
||
try super.run(with: arguments, environment: environment, workingPath: workingPath) | ||
guard let type = arguments.get(assetBundleTypeArgument) else { return } | ||
|
||
print("Downloading asset bundle from \(type.url)") | ||
guard let fileUrl = downloadAssetBundle(type.url) else { | ||
log("Unable to download asset bundle \(type.rawValue.singleQuoted)", type: .error) | ||
exit(1) | ||
} | ||
|
||
log("Temporary asset bundle data stored at \(fileUrl)") | ||
print("Extracting downloaded asset bundle to \(Path().absolute())") | ||
guard let archive = Archive(url: fileUrl, accessMode: .read) else { | ||
log("The downloaded asset bundle is corrupted", type: .error) | ||
exit(1) | ||
} | ||
|
||
try self.extractAssetBundle(archive, to: inferredRootPath) | ||
flushLogs() | ||
print("Successfully loaded asset bundle \(type.rawValue.singleQuoted) into \(inferredRootPath)") | ||
} | ||
|
||
private func downloadAssetBundle(_ url: Foundation.URL) -> Foundation.URL? { | ||
let semaphore = DispatchSemaphore(value: 0) | ||
var fileUrl: Foundation.URL? | ||
URLSession.shared.downloadTask(with: url) { (url, _, error) in | ||
if let error = error { log(error) } | ||
fileUrl = url | ||
semaphore.signal() | ||
}.resume() | ||
semaphore.wait() | ||
return fileUrl | ||
} | ||
|
||
private func extractAssetBundle(_ archive: Archive, to path: Path) throws { | ||
let basePath = path.absolute() | ||
for entry in archive { | ||
let entryPath = Path(entry.path) | ||
guard | ||
let firstComponent = entryPath.components.first, | ||
!Constants.excludedAssetRootDirectories.contains(firstComponent) | ||
else { | ||
log("Skipping excluded asset bundle entry based on root directory at \(entryPath)") | ||
continue | ||
} | ||
guard !Constants.excludedAssetFileNames.contains(entryPath.lastComponent) else { | ||
log("Skipping excluded asset bundle entry based on file name at \(entryPath)") | ||
continue | ||
} | ||
|
||
let destinationPath = basePath + entryPath | ||
guard !destinationPath.exists else { | ||
logWarning("Skipping existing asset bundle contents at \(entryPath)") | ||
continue | ||
} | ||
_ = try archive.extract(entry, to: destinationPath.url) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.