mirror of
https://github.com/mas-cli/mas
synced 2025-02-16 12:38:30 +00:00
Merge branch 'main' into 562-apple-id
This commit is contained in:
commit
a24bcdd1e9
28 changed files with 158 additions and 154 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -25,6 +25,7 @@
|
||||||
.build/
|
.build/
|
||||||
.envrc
|
.envrc
|
||||||
.fseventsd
|
.fseventsd
|
||||||
|
.idea/
|
||||||
.rubygems/
|
.rubygems/
|
||||||
.swiftpm/
|
.swiftpm/
|
||||||
Carthage/
|
Carthage/
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
#
|
#
|
||||||
# https://github.com/realm/SwiftLint#configuration
|
# https://github.com/realm/SwiftLint#configuration
|
||||||
#
|
#
|
||||||
|
---
|
||||||
disabled_rules:
|
disabled_rules:
|
||||||
- non_optional_string_data_conversion
|
- non_optional_string_data_conversion
|
||||||
- trailing_comma
|
- trailing_comma
|
||||||
|
|
||||||
excluded:
|
excluded:
|
||||||
- docs
|
- docs
|
||||||
|
|
||||||
opening_brace:
|
opening_brace:
|
||||||
allow_multiline_func: true
|
ignore_multiline_function_signatures: true
|
||||||
|
ignore_multiline_statement_conditions: true
|
||||||
|
|
1
Brewfile
1
Brewfile
|
@ -1,6 +1,7 @@
|
||||||
brew "markdownlint-cli"
|
brew "markdownlint-cli"
|
||||||
brew "shellcheck"
|
brew "shellcheck"
|
||||||
brew "shfmt"
|
brew "shfmt"
|
||||||
|
brew "swift-format"
|
||||||
brew "swiftformat"
|
brew "swiftformat"
|
||||||
|
|
||||||
# Already installed on GitHub Actions runner.
|
# Already installed on GitHub Actions runner.
|
||||||
|
|
|
@ -8,7 +8,7 @@ We love pull requests from everyone. By participating in this project, you agree
|
||||||
- [Open an issue](https://github.com/mas-cli/mas/issues/new) to simply ask a question or request a new feature.
|
- [Open an issue](https://github.com/mas-cli/mas/issues/new) to simply ask a question or request a new feature.
|
||||||
- Search for similar issues with the
|
- Search for similar issues with the
|
||||||
[ERROR MESSAGE](https://github.com/mas-cli/mas/issues?utf8=%E2%9C%93&q=is%3Aopen+ERROR+MESSAGE)
|
[ERROR MESSAGE](https://github.com/mas-cli/mas/issues?utf8=%E2%9C%93&q=is%3Aopen+ERROR+MESSAGE)
|
||||||
you are exeriencing.
|
you are experiencing.
|
||||||
- If one doesn't exist, [open a new issue](https://github.com/mas-cli/mas/issues/new)
|
- If one doesn't exist, [open a new issue](https://github.com/mas-cli/mas/issues/new)
|
||||||
- Clearly describe the issue including steps to reproduce when it is a bug.
|
- Clearly describe the issue including steps to reproduce when it is a bug.
|
||||||
- Include the earliest version of `mas` that you know has the issue.
|
- Include the earliest version of `mas` that you know has the issue.
|
||||||
|
|
|
@ -64,33 +64,6 @@
|
||||||
"version": "2.1.1"
|
"version": "2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"package": "swift-argument-parser",
|
|
||||||
"repositoryURL": "https://github.com/apple/swift-argument-parser.git",
|
|
||||||
"state": {
|
|
||||||
"branch": null,
|
|
||||||
"revision": "c8ed701b513cf5177118a175d85fbbbcd707ab41",
|
|
||||||
"version": "1.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"package": "swift-format",
|
|
||||||
"repositoryURL": "https://github.com/apple/swift-format",
|
|
||||||
"state": {
|
|
||||||
"branch": "release/5.9",
|
|
||||||
"revision": "1323e87eced56bdcfed1bb78af1f16f39274d032",
|
|
||||||
"version": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"package": "swift-syntax",
|
|
||||||
"repositoryURL": "https://github.com/apple/swift-syntax.git",
|
|
||||||
"state": {
|
|
||||||
"branch": "release/5.9",
|
|
||||||
"revision": "9a101b70eee2a9dec04f92d2d47b22ebe57a1aae",
|
|
||||||
"version": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"package": "Version",
|
"package": "Version",
|
||||||
"repositoryURL": "https://github.com/mxcl/Version.git",
|
"repositoryURL": "https://github.com/mxcl/Version.git",
|
||||||
|
|
|
@ -75,30 +75,3 @@ let package = Package(
|
||||||
],
|
],
|
||||||
swiftLanguageVersions: [.v5]
|
swiftLanguageVersions: [.v5]
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://github.com/apple/swift-format#matching-swift-format-to-your-swift-version-swift-57-and-earlier
|
|
||||||
#if compiler(>=5.8)
|
|
||||||
package.dependencies += [
|
|
||||||
.package(url: "https://github.com/apple/swift-format", .branch("release/5.9"))
|
|
||||||
]
|
|
||||||
#elseif compiler(>=5.7)
|
|
||||||
package.dependencies += [
|
|
||||||
.package(url: "https://github.com/apple/swift-format", .branch("release/5.7"))
|
|
||||||
]
|
|
||||||
#elseif compiler(>=5.6)
|
|
||||||
package.dependencies += [
|
|
||||||
.package(url: "https://github.com/apple/swift-format", .branch("release/5.6"))
|
|
||||||
]
|
|
||||||
#elseif compiler(>=5.5)
|
|
||||||
package.dependencies += [
|
|
||||||
.package(url: "https://github.com/apple/swift-format", .branch("swift-5.5-branch"))
|
|
||||||
]
|
|
||||||
#elseif compiler(>=5.4)
|
|
||||||
package.dependencies += [
|
|
||||||
.package(url: "https://github.com/apple/swift-format", .branch("swift-5.4-branch"))
|
|
||||||
]
|
|
||||||
#elseif compiler(>=5.3)
|
|
||||||
package.dependencies += [
|
|
||||||
.package(url: "https://github.com/apple/swift-format", .branch("swift-5.3-branch"))
|
|
||||||
]
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -109,7 +109,6 @@ $ mas lucky twitter
|
||||||
|
|
||||||
> Please note that this command will not allow you to install (or even purchase) an app for the first time:
|
> Please note that this command will not allow you to install (or even purchase) an app for the first time:
|
||||||
use the `purchase` command in that case.
|
use the `purchase` command in that case.
|
||||||
> ⛔ The `purchase` command is not supported as of macOS 10.15 Catalina. Please see [Known Issues](#%EF%B8%8F-known-issues).
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ mas purchase 768053424
|
$ mas purchase 768053424
|
||||||
|
@ -190,10 +189,9 @@ docs for more details.
|
||||||
## ⚠️ Known Issues
|
## ⚠️ Known Issues
|
||||||
|
|
||||||
Over time, Apple has changed the APIs used by `mas` to manage App Store apps, limiting its capabilities. Please sign in
|
Over time, Apple has changed the APIs used by `mas` to manage App Store apps, limiting its capabilities. Please sign in
|
||||||
or purchase apps using the App Store app instead. Subsequent redownloads can be performed with `mas install`.
|
using the App Store app instead. Subsequent redownloads can be performed with `mas install`.
|
||||||
|
|
||||||
- ⛔️ The `signin` command is not supported as of macOS 10.13 High Sierra. [#164](https://github.com/mas-cli/mas/issues/164)
|
- ⛔️ The `signin` command is not supported as of macOS 10.13 High Sierra. [#164](https://github.com/mas-cli/mas/issues/164)
|
||||||
- ⛔️ The `purchase` command is not supported as of macOS 10.15 Catalina. [#289](https://github.com/mas-cli/mas/issues/289)
|
|
||||||
- ⛔️ The `account` command is not supported as of macOS 12 Monterey. [#417](https://github.com/mas-cli/mas/issues/417)
|
- ⛔️ The `account` command is not supported as of macOS 12 Monterey. [#417](https://github.com/mas-cli/mas/issues/417)
|
||||||
|
|
||||||
The versions `mas` sees from the app bundles on your Mac don't always match the versions reported by the App Store for
|
The versions `mas` sees from the app bundles on your Mac don't always match the versions reported by the App Store for
|
||||||
|
|
|
@ -69,7 +69,7 @@ public struct LuckyCommand: CommandProtocol {
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - appId: App identifier
|
/// - appId: App identifier
|
||||||
/// - options: command opetions.
|
/// - options: command options.
|
||||||
/// - Returns: Result of the operation.
|
/// - Returns: Result of the operation.
|
||||||
fileprivate func install(_ appId: UInt64, options: Options) -> Result<Void, MASError> {
|
fileprivate func install(_ appId: UInt64, options: Options) -> Result<Void, MASError> {
|
||||||
// Try to download applications with given identifiers and collect results
|
// Try to download applications with given identifiers and collect results
|
||||||
|
|
|
@ -29,12 +29,6 @@ public struct PurchaseCommand: CommandProtocol {
|
||||||
|
|
||||||
/// Runs the command.
|
/// Runs the command.
|
||||||
public func run(_ options: Options) -> Result<Void, MASError> {
|
public func run(_ options: Options) -> Result<Void, MASError> {
|
||||||
if #available(macOS 10.15, *) {
|
|
||||||
// Purchases are no longer possible as of Catalina.
|
|
||||||
// https://github.com/mas-cli/mas/issues/289
|
|
||||||
return .failure(.notSupported)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to download applications with given identifiers and collect results
|
// Try to download applications with given identifiers and collect results
|
||||||
let appIds = options.appIds.filter { appId in
|
let appIds = options.appIds.filter { appId in
|
||||||
if let product = appLibrary.installedApp(forId: appId) {
|
if let product = appLibrary.installedApp(forId: appId) {
|
||||||
|
|
|
@ -28,9 +28,9 @@ protocol AppLibrary {
|
||||||
|
|
||||||
/// Common logic
|
/// Common logic
|
||||||
extension AppLibrary {
|
extension AppLibrary {
|
||||||
/// Finds an app by name.
|
/// Finds an app by ID.
|
||||||
///
|
///
|
||||||
/// - Parameter id: MAS ID for app.
|
/// - Parameter forId: MAS ID for app.
|
||||||
/// - Returns: Software Product of app if found; nil otherwise.
|
/// - Returns: Software Product of app if found; nil otherwise.
|
||||||
func installedApp(forId identifier: UInt64) -> SoftwareProduct? {
|
func installedApp(forId identifier: UInt64) -> SoftwareProduct? {
|
||||||
let appId = NSNumber(value: identifier)
|
let appId = NSNumber(value: identifier)
|
||||||
|
|
|
@ -108,7 +108,7 @@ class MasStoreSearch: StoreSearch {
|
||||||
do {
|
do {
|
||||||
return try JSONDecoder().decode(SearchResultList.self, from: data).results
|
return try JSONDecoder().decode(SearchResultList.self, from: data).results
|
||||||
} catch {
|
} catch {
|
||||||
throw MASError.jsonParsing(error: error as NSError)
|
throw MASError.jsonParsing(data: data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Copyright © 2020 mas-cli. All rights reserved.
|
// Copyright © 2020 mas-cli. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
/// Somewhat analygous to CKSoftwareMap
|
/// Somewhat analogous to CKSoftwareMap
|
||||||
protocol SoftwareMap {
|
protocol SoftwareMap {
|
||||||
func allSoftwareProducts() -> [SoftwareProduct]
|
func allSoftwareProducts() -> [SoftwareProduct]
|
||||||
func product(for bundleIdentifier: String) -> SoftwareProduct?
|
func product(for bundleIdentifier: String) -> SoftwareProduct?
|
||||||
|
|
|
@ -31,7 +31,7 @@ public enum MASError: Error, Equatable {
|
||||||
case uninstallFailed
|
case uninstallFailed
|
||||||
|
|
||||||
case noData
|
case noData
|
||||||
case jsonParsing(error: NSError?)
|
case jsonParsing(data: Data?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - CustomStringConvertible
|
// MARK: - CustomStringConvertible
|
||||||
|
@ -90,8 +90,16 @@ extension MASError: CustomStringConvertible {
|
||||||
return "Uninstall failed"
|
return "Uninstall failed"
|
||||||
case .noData:
|
case .noData:
|
||||||
return "Service did not return data"
|
return "Service did not return data"
|
||||||
case .jsonParsing:
|
case .jsonParsing(let data):
|
||||||
return "Unable to parse response JSON"
|
if let data {
|
||||||
|
if let unparsable = String(data: data, encoding: .utf8) {
|
||||||
|
return "Unable to parse response as JSON: \n\(unparsable)"
|
||||||
|
} else {
|
||||||
|
return "Received defective response"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "Received empty response"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@ enum AppListFormatter {
|
||||||
|
|
||||||
/// Formats text output with list results.
|
/// Formats text output with list results.
|
||||||
///
|
///
|
||||||
/// - Parameter products: List of sortware products app data.
|
/// - Parameter products: List of software products app data.
|
||||||
/// - Returns: Multiliune text outoutp.
|
/// - Returns: Multiline text output.
|
||||||
static func format(products: [SoftwareProduct]) -> String {
|
static func format(products: [SoftwareProduct]) -> String {
|
||||||
// find longest appName for formatting, default 50
|
// find longest appName for formatting, default 50
|
||||||
let maxLength = products.map(\.appNameOrBundleIdentifier.count).max() ?? nameColumnMinWidth
|
let maxLength = products.map(\.appNameOrBundleIdentifier.count).max() ?? nameColumnMinWidth
|
||||||
|
|
|
@ -13,7 +13,7 @@ enum SearchResultFormatter {
|
||||||
/// Formats text output with search results.
|
/// Formats text output with search results.
|
||||||
///
|
///
|
||||||
/// - Parameter results: Search results with app data
|
/// - Parameter results: Search results with app data
|
||||||
/// - Returns: Multiliune text outoutp.
|
/// - Returns: Multiline text output.
|
||||||
static func format(results: [SearchResult], includePrice: Bool = false) -> String {
|
static func format(results: [SearchResult], includePrice: Bool = false) -> String {
|
||||||
// find longest appName for formatting, default 50
|
// find longest appName for formatting, default 50
|
||||||
let maxLength = results.map(\.trackName.count).max() ?? 50
|
let maxLength = results.map(\.trackName.count).max() ?? 50
|
||||||
|
|
|
@ -10,7 +10,6 @@ struct SearchResult: Decodable {
|
||||||
var bundleId: String
|
var bundleId: String
|
||||||
var currentVersionReleaseDate: String
|
var currentVersionReleaseDate: String
|
||||||
var fileSizeBytes: String?
|
var fileSizeBytes: String?
|
||||||
var kind: String
|
|
||||||
var minimumOsVersion: String
|
var minimumOsVersion: String
|
||||||
var price: Double?
|
var price: Double?
|
||||||
var sellerName: String
|
var sellerName: String
|
||||||
|
@ -24,7 +23,6 @@ struct SearchResult: Decodable {
|
||||||
bundleId: String = "",
|
bundleId: String = "",
|
||||||
currentVersionReleaseDate: String = "",
|
currentVersionReleaseDate: String = "",
|
||||||
fileSizeBytes: String = "0",
|
fileSizeBytes: String = "0",
|
||||||
kind: String = "",
|
|
||||||
minimumOsVersion: String = "",
|
minimumOsVersion: String = "",
|
||||||
price: Double = 0.0,
|
price: Double = 0.0,
|
||||||
sellerName: String = "",
|
sellerName: String = "",
|
||||||
|
@ -37,7 +35,6 @@ struct SearchResult: Decodable {
|
||||||
self.bundleId = bundleId
|
self.bundleId = bundleId
|
||||||
self.currentVersionReleaseDate = currentVersionReleaseDate
|
self.currentVersionReleaseDate = currentVersionReleaseDate
|
||||||
self.fileSizeBytes = fileSizeBytes
|
self.fileSizeBytes = fileSizeBytes
|
||||||
self.kind = kind
|
|
||||||
self.minimumOsVersion = minimumOsVersion
|
self.minimumOsVersion = minimumOsVersion
|
||||||
self.price = price
|
self.price = price
|
||||||
self.sellerName = sellerName
|
self.sellerName = sellerName
|
||||||
|
|
|
@ -28,15 +28,13 @@ extension SoftwareProduct {
|
||||||
/// - Parameter storeApp: App from search result.
|
/// - Parameter storeApp: App from search result.
|
||||||
/// - Returns: true if the app is outdated; false otherwise.
|
/// - Returns: true if the app is outdated; false otherwise.
|
||||||
func isOutdatedWhenComparedTo(_ storeApp: SearchResult) -> Bool {
|
func isOutdatedWhenComparedTo(_ storeApp: SearchResult) -> Bool {
|
||||||
// Only look at min OS version if we have one, also only consider macOS apps
|
// If storeApp requires a version of macOS newer than the running version, do not consider self outdated.
|
||||||
// Replace string literal with MasStoreSearch.Entity once `search` branch is merged.
|
if let osVersion = Version(tolerant: storeApp.minimumOsVersion) {
|
||||||
if let osVersion = Version(tolerant: storeApp.minimumOsVersion), storeApp.kind == "mac-software" {
|
|
||||||
let requiredVersion = OperatingSystemVersion(
|
let requiredVersion = OperatingSystemVersion(
|
||||||
majorVersion: osVersion.major,
|
majorVersion: osVersion.major,
|
||||||
minorVersion: osVersion.minor,
|
minorVersion: osVersion.minor,
|
||||||
patchVersion: osVersion.patch
|
patchVersion: osVersion.patch
|
||||||
)
|
)
|
||||||
// Don't consider an app outdated if the version in the app store requires a higher OS version.
|
|
||||||
guard ProcessInfo.processInfo.isOperatingSystemAtLeast(requiredVersion) else {
|
guard ProcessInfo.processInfo.isOperatingSystemAtLeast(requiredVersion) else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,7 @@ public class PurchaseCommandSpec: QuickSpec {
|
||||||
it("purchases apps") {
|
it("purchases apps") {
|
||||||
let cmd = PurchaseCommand()
|
let cmd = PurchaseCommand()
|
||||||
let result = cmd.run(PurchaseCommand.Options(appIds: []))
|
let result = cmd.run(PurchaseCommand.Options(appIds: []))
|
||||||
expect(result)
|
expect(result).to(beSuccess())
|
||||||
.to(
|
|
||||||
beFailure { error in
|
|
||||||
expect(error) == .notSupported
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class AppLibraryMock: AppLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Members not part of the AppLibrary protocol that are only for test state managment.
|
/// Members not part of the AppLibrary protocol that are only for test state management.
|
||||||
extension AppLibraryMock {
|
extension AppLibraryMock {
|
||||||
/// Clears out the list of installed apps.
|
/// Clears out the list of installed apps.
|
||||||
func reset() {
|
func reset() {
|
||||||
|
|
|
@ -122,7 +122,7 @@ class MASErrorTestCase: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testJsonParsing() {
|
func testJsonParsing() {
|
||||||
error = .jsonParsing(error: nil)
|
error = .jsonParsing(data: nil)
|
||||||
XCTAssertEqual(error.description, "Unable to parse response JSON")
|
XCTAssertEqual(error.description, "Received empty response")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@ public class SoftwareProductSpec: QuickSpec {
|
||||||
itemIdentifier: 111
|
itemIdentifier: 111
|
||||||
)
|
)
|
||||||
|
|
||||||
let currentApp = SearchResult(kind: "mac-software", version: "1.0.0")
|
let currentApp = SearchResult(version: "1.0.0")
|
||||||
let appUpdate = SearchResult(kind: "mac-software", version: "2.0.0")
|
let appUpdate = SearchResult(version: "2.0.0")
|
||||||
let higherOs = SearchResult(kind: "mac-software", minimumOsVersion: "99.0.0", version: "3.0.0")
|
let higherOs = SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0")
|
||||||
let updateIos = SearchResult(kind: "software", minimumOsVersion: "99.0.0", version: "3.0.0")
|
let updateIos = SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0")
|
||||||
|
|
||||||
it("is not outdated when there is no new version available") {
|
it("is not outdated when there is no new version available") {
|
||||||
expect(app.isOutdatedWhenComparedTo(currentApp)) == false
|
expect(app.isOutdatedWhenComparedTo(currentApp)) == false
|
||||||
|
@ -37,11 +37,11 @@ public class SoftwareProductSpec: QuickSpec {
|
||||||
it("is outdated when there is a new version available") {
|
it("is outdated when there is a new version available") {
|
||||||
expect(app.isOutdatedWhenComparedTo(appUpdate)) == true
|
expect(app.isOutdatedWhenComparedTo(appUpdate)) == true
|
||||||
}
|
}
|
||||||
it("is not outdated when the new version requires a higher OS version") {
|
it("is not outdated when the new version of mac-software requires a higher OS version") {
|
||||||
expect(app.isOutdatedWhenComparedTo(higherOs)) == false
|
expect(app.isOutdatedWhenComparedTo(higherOs)) == false
|
||||||
}
|
}
|
||||||
it("ignores minimum iOS version") {
|
it("is not outdated when the new version of software requires a higher OS version") {
|
||||||
expect(app.isOutdatedWhenComparedTo(updateIos)) == true
|
expect(app.isOutdatedWhenComparedTo(updateIos)) == false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ case let .success(data):
|
||||||
print("The response returned successfully \(data)")
|
print("The response returned successfully \(data)")
|
||||||
|
|
||||||
case let .failure(error):
|
case let .failure(error):
|
||||||
print("An error occured: \(error)")
|
print("An error occurred: \(error)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Organization
|
// MARK: Organization
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -eu
|
||||||
#
|
#
|
||||||
# script/bootstrap
|
# script/bootstrap
|
||||||
# mas
|
# mas
|
||||||
|
@ -6,10 +6,17 @@
|
||||||
# Installs development dependencies and builds project dependencies.
|
# Installs development dependencies and builds project dependencies.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
mas_dir="$(readlink -fn "$(dirname "${BASH_SOURCE:-"${0}"}")/..")"
|
||||||
|
|
||||||
|
if ! cd -- "${mas_dir}"; then
|
||||||
|
printf $'Error: Could not cd into mas directory: %s\n' "${mas_dir}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
script/clean
|
script/clean
|
||||||
|
|
||||||
echo "==> 👢 Bootstrapping"
|
printf $'==> 👢 Bootstrapping\n'
|
||||||
|
|
||||||
# Install Homebrew tools
|
# Install Homebrew tools
|
||||||
rm -f Brewfile.lock.json
|
rm -f Brewfile.lock.json
|
||||||
|
|
15
script/build
15
script/build
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -eu
|
||||||
#
|
#
|
||||||
# script/build
|
# script/build
|
||||||
# mas
|
# mas
|
||||||
|
@ -6,9 +6,16 @@
|
||||||
# Builds the Swift Package.
|
# Builds the Swift Package.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
mas_dir="$(readlink -fn "$(dirname "${BASH_SOURCE:-"${0}"}")/..")"
|
||||||
|
|
||||||
|
if ! cd -- "${mas_dir}"; then
|
||||||
|
printf $'Error: Could not cd into mas directory: %s\n' "${mas_dir}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Build for the host architecture by default.
|
# Build for the host architecture by default.
|
||||||
ARCH=()
|
ARCH=()
|
||||||
if [[ "$1" == '--universal' ]]; then
|
if [[ "${#}" -gt 1 && "${1}" == '--universal' ]]; then
|
||||||
ARCH=(--arch arm64 --arch x86_64)
|
ARCH=(--arch arm64 --arch x86_64)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -21,6 +28,6 @@ fi
|
||||||
echo "==> 🏗️ Building mas ($(script/version))"
|
echo "==> 🏗️ Building mas ($(script/version))"
|
||||||
swift build \
|
swift build \
|
||||||
--configuration release \
|
--configuration release \
|
||||||
"${ARCH[@]}" \
|
"${ARCH[@]+"${ARCH[@]}"}" \
|
||||||
--disable-sandbox \
|
--disable-sandbox \
|
||||||
"${CACHE[@]}"
|
"${CACHE[@]+"${CACHE[@]}"}"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -eu
|
||||||
#
|
#
|
||||||
# script/format
|
# script/format
|
||||||
# mas
|
# mas
|
||||||
|
@ -6,34 +6,42 @@
|
||||||
# Linting checks for development and CI.
|
# Linting checks for development and CI.
|
||||||
#
|
#
|
||||||
# Automatically formats and fixes style violations using various tools.
|
# Automatically formats and fixes style violations using various tools.
|
||||||
# Additionally runs `lint` to report any remaining style violations.
|
|
||||||
#
|
#
|
||||||
# Please keep in sync with script/lint.
|
# Please keep in sync with script/lint.
|
||||||
#
|
#
|
||||||
|
|
||||||
echo "==> 🚨 Formatting mas"
|
mas_dir="$(readlink -fn "$(dirname "${BASH_SOURCE:-"${0}"}")/..")"
|
||||||
|
|
||||||
for LINTER in markdownlint shfmt swiftformat swiftlint; do
|
if ! cd -- "${mas_dir}"; then
|
||||||
|
printf $'Error: Could not cd into mas directory: %s\n' "${mas_dir}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf $'==> 🚨 Formatting mas\n'
|
||||||
|
|
||||||
|
for LINTER in markdownlint shfmt swift-format swiftformat swiftlint; do
|
||||||
if [[ ! -x "$(command -v ${LINTER})" ]]; then
|
if [[ ! -x "$(command -v ${LINTER})" ]]; then
|
||||||
echo "error: ${LINTER} is not installed. Run 'script/bootstrap' or 'brew install ${LINTER}'."
|
printf $'error: %s is not installed. Run \'script/bootstrap\' or \'brew install %s\'.\n' "${LINTER}" "${LINTER}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo
|
|
||||||
echo "--> 🖊 Markdown"
|
|
||||||
markdownlint --config .markdownlint.json --fix .github .
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "--> 🕊️ Swift"
|
|
||||||
for SOURCE in Package.swift Sources Tests; do
|
for SOURCE in Package.swift Sources Tests; do
|
||||||
swiftformat ${SOURCE}
|
printf -- $'--> 🕊 %s swift-format\n' "${SOURCE}"
|
||||||
swift run swift-format format --in-place --recursive ${SOURCE}
|
swift-format format --in-place --recursive "${SOURCE}"
|
||||||
swiftlint lint --fix --strict ${SOURCE}
|
printf -- $'--> 🕊 %s swiftformat\n' "${SOURCE}"
|
||||||
|
swiftformat "${SOURCE}"
|
||||||
|
printf -- $'--> 🕊 %s swiftlint\n' "${SOURCE}"
|
||||||
|
swiftlint --fix --strict "${SOURCE}"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo
|
printf -- $'--> 📜 Bash shfmt\n'
|
||||||
echo "--> 📜 Bash"
|
shfmt \
|
||||||
shfmt -i 2 -l -w contrib/ script/
|
--write \
|
||||||
|
--list \
|
||||||
|
--indent 2 \
|
||||||
|
--case-indent \
|
||||||
|
contrib/ script/
|
||||||
|
|
||||||
script/lint
|
printf -- $'--> 〽️ Markdown\n'
|
||||||
|
markdownlint --config .markdownlint.json --fix .github .
|
||||||
|
|
75
script/lint
75
script/lint
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -u
|
||||||
#
|
#
|
||||||
# script/lint
|
# script/lint
|
||||||
# mas
|
# mas
|
||||||
|
@ -10,32 +10,63 @@
|
||||||
# Please keep in sync with script/format.
|
# Please keep in sync with script/format.
|
||||||
#
|
#
|
||||||
|
|
||||||
echo "==> 🚨 Linting mas"
|
set -o pipefail
|
||||||
|
|
||||||
for LINTER in git markdownlint periphery shfmt swiftformat swiftlint; do
|
mas_dir="$(readlink -fn "$(dirname "${BASH_SOURCE:-"${0}"}")/..")"
|
||||||
if [[ ! -x "$(command -v ${LINTER})" ]]; then
|
|
||||||
echo "error: ${LINTER} is not installed. Run 'script/bootstrap' or 'brew install ${LINTER}'."
|
if ! cd -- "${mas_dir}"; then
|
||||||
|
printf $'Error: Could not cd into mas directory: %s\n' "${mas_dir}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf $'==> 🚨 Linting mas (%s)\n' "$(script/version)"
|
||||||
|
|
||||||
|
for linter in git markdownlint periphery shellcheck shfmt swift-format swiftformat swiftlint; do
|
||||||
|
if [[ ! -x "$(command -v ${linter})" ]]; then
|
||||||
|
printf $'error: %s is not installed. Run \'script/bootstrap\' or \'brew install %s\'.\n' "${linter}" "${linter}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "--> 🌳 Git"
|
exit_code=0
|
||||||
git diff --check
|
for source in Package.swift Sources Tests; do
|
||||||
|
printf -- $'--> 🕊 %s swift-format\n' "${source}"
|
||||||
echo
|
swift-format lint --strict --recursive "${source}"
|
||||||
echo "--> 🖊 Markdown"
|
((exit_code |= "${?}"))
|
||||||
markdownlint --config .markdownlint.json .github .
|
printf -- $'--> 🕊 %s swiftformat\n' "${source}"
|
||||||
|
script -q /dev/null swiftformat --lint --strict "${source}" |
|
||||||
echo
|
(grep -vxE $'Running SwiftFormat\\.\\.\\.\r|\\(lint mode - no files will be changed\\.\\)\r|Reading (?:config|swift-version) file at .*|\033\[32mSwiftFormat completed in \\d+\\.\\d+s\\.\033\\[0m\r|0/\\d+ files require formatting\\.\r' || true)
|
||||||
echo "--> 🕊️ Swift"
|
((exit_code |= "${?}"))
|
||||||
for SOURCE in Package.swift Sources Tests; do
|
printf -- $'--> 🕊 %s swiftlint\n' "${source}"
|
||||||
swiftformat --lint ${SOURCE}
|
swiftlint --strict --quiet "${source}" 2> \
|
||||||
swift run swift-format lint --recursive ${SOURCE}
|
>((grep -vxF $'warning: Configuration option \'allow_multiline_func\' in \'opening_brace\' rule is deprecated. Use the option \'ignore_multiline_function_signatures\' instead.' || true) >&2)
|
||||||
swiftlint lint --strict ${SOURCE}
|
((exit_code |= "${?}"))
|
||||||
done
|
done
|
||||||
periphery scan
|
|
||||||
|
|
||||||
echo
|
printf -- $'--> 🐚 Bash shellcheck\n'
|
||||||
echo "--> 📜 Bash"
|
|
||||||
shellcheck --shell=bash script/*
|
shellcheck --shell=bash script/*
|
||||||
shfmt -d -i 2 -l contrib/ script/
|
((exit_code |= "${?}"))
|
||||||
|
|
||||||
|
printf -- $'--> 📜 Bash shfmt\n'
|
||||||
|
shfmt \
|
||||||
|
--diff \
|
||||||
|
--list \
|
||||||
|
--indent 2 \
|
||||||
|
--case-indent \
|
||||||
|
contrib/ script/
|
||||||
|
((exit_code |= "${?}"))
|
||||||
|
|
||||||
|
printf -- $'--> 〽️ Markdown\n'
|
||||||
|
markdownlint --config .markdownlint.json .github .
|
||||||
|
((exit_code |= "${?}"))
|
||||||
|
|
||||||
|
printf -- $'--> 🌳 Git\n'
|
||||||
|
PAGER='cat' git diff --check
|
||||||
|
((exit_code |= "${?}"))
|
||||||
|
|
||||||
|
printf -- $'--> 🌀 Periphery\n'
|
||||||
|
script -q /dev/null periphery scan --strict --quiet --disable-update-check |
|
||||||
|
(grep -vxF $'\033[0;1;32m* \033[0;0m\033[0;1mNo unused code detected.\033[0;0m\r\n' || true)
|
||||||
|
((exit_code |= "${?}"))
|
||||||
|
|
||||||
|
exit "${exit_code}"
|
||||||
|
|
12
script/test
12
script/test
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -eu
|
||||||
#
|
#
|
||||||
# script/test
|
# script/test
|
||||||
# mas
|
# mas
|
||||||
|
@ -6,5 +6,13 @@
|
||||||
# Runs mas tests.
|
# Runs mas tests.
|
||||||
#
|
#
|
||||||
|
|
||||||
echo "==> ✅ Testing"
|
mas_dir="$(readlink -fn "$(dirname "${BASH_SOURCE:-"${0}"}")/..")"
|
||||||
|
|
||||||
|
if ! cd -- "${mas_dir}"; then
|
||||||
|
printf $'Error: Could not cd into mas directory: %s\n' "${mas_dir}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf $'==> ✅ Testing mas (%s)\n' "$(script/version)"
|
||||||
|
|
||||||
swift test
|
swift test
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -eu
|
||||||
#
|
#
|
||||||
# script/version
|
# script/version
|
||||||
# mas
|
# mas
|
||||||
|
@ -9,12 +9,17 @@
|
||||||
# This no longer works with MARKETING_VERSION build setting in Info.plist
|
# This no longer works with MARKETING_VERSION build setting in Info.plist
|
||||||
# agvtool what-marketing-version -terse1
|
# agvtool what-marketing-version -terse1
|
||||||
|
|
||||||
|
mas_dir="$(readlink -fn "$(dirname "${BASH_SOURCE:-"${0}"}")/..")"
|
||||||
|
|
||||||
|
if ! cd -- "${mas_dir}"; then
|
||||||
|
printf $'Error: Could not cd into mas directory: %s\n' "${mas_dir}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
VERSION=$(git describe --abbrev=0 --tags)
|
VERSION=$(git describe --abbrev=0 --tags)
|
||||||
VERSION=${VERSION#v}
|
VERSION=${VERSION#v}
|
||||||
|
|
||||||
SCRIPT_PATH=$(dirname "$(which "$0")")
|
cat <<EOF >"Sources/MasKit/Package.swift"
|
||||||
|
|
||||||
cat <<EOF >"${SCRIPT_PATH}/../Sources/MasKit/Package.swift"
|
|
||||||
// Generated by: script/version
|
// Generated by: script/version
|
||||||
enum Package {
|
enum Package {
|
||||||
static let version = "${VERSION}"
|
static let version = "${VERSION}"
|
||||||
|
|
Loading…
Add table
Reference in a new issue