mirror of
https://github.com/mas-cli/mas
synced 2024-11-21 19:23:01 +00:00
Merge pull request #350 from mas-cli/spm
📦 Declare mas as a Swift Package
This commit is contained in:
commit
9277a8b7cc
179 changed files with 285 additions and 2426 deletions
2
.github/config.yml
vendored
2
.github/config.yml
vendored
|
@ -1,2 +0,0 @@
|
|||
todo:
|
||||
exclude: "^Carthage/"
|
6
.github/workflows/build-test.yml
vendored
6
.github/workflows/build-test.yml
vendored
|
@ -17,16 +17,14 @@ jobs:
|
|||
# https://github.com/actions/checkout#usage
|
||||
- uses: actions/checkout@master
|
||||
with:
|
||||
# Fetch tags for script/version
|
||||
fetch-depth: 0
|
||||
# https://docs.github.com/en/actions/reference/authentication-in-a-workflow
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Bootstrap
|
||||
run: script/bootstrap
|
||||
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsenv
|
||||
env:
|
||||
# Carthage looks for GITHUB_ACCESS_TOKEN
|
||||
# https://github.com/Carthage/Carthage/blob/master/Source/CarthageKit/GitHub.swift#L118
|
||||
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build
|
||||
run: script/build
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -22,9 +22,11 @@
|
|||
.VolumeIcon.icns
|
||||
._*
|
||||
.apdisk
|
||||
.build/
|
||||
.envrc
|
||||
.fseventsd
|
||||
.rubygems/
|
||||
.swiftpm/
|
||||
Carthage/
|
||||
DerivedData
|
||||
Pods/
|
||||
|
@ -34,3 +36,4 @@ build/
|
|||
default.profraw
|
||||
releases/
|
||||
xcuserdata
|
||||
Sources/MasKit/Package.swift
|
||||
|
|
|
@ -15,3 +15,6 @@ rubocop:
|
|||
|
||||
shellcheck:
|
||||
enabled: true
|
||||
|
||||
swiftlint:
|
||||
enabled: false
|
||||
|
|
2
Brewfile
2
Brewfile
|
@ -1,5 +1,3 @@
|
|||
brew "carthage"
|
||||
brew "make"
|
||||
brew "shfmt"
|
||||
brew "swift-format"
|
||||
brew "swiftformat"
|
||||
|
|
|
@ -1,69 +1,6 @@
|
|||
{
|
||||
"entries": {
|
||||
"brew": {
|
||||
"carthage": {
|
||||
"version": "0.37.0",
|
||||
"bottle": {
|
||||
"rebuild": 0,
|
||||
"root_url": "https://ghcr.io/v2/homebrew/core",
|
||||
"files": {
|
||||
"arm64_big_sur": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/carthage/blobs/sha256:cd0c716682b5b094b82a589fb79def4eb696f70a3fd92423923a5cb86c2c79b3",
|
||||
"sha256": "cd0c716682b5b094b82a589fb79def4eb696f70a3fd92423923a5cb86c2c79b3"
|
||||
},
|
||||
"big_sur": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/carthage/blobs/sha256:0770b4dd885f3018031c2d27fc090a34027d5856a248f33fa2a415d58da74632",
|
||||
"sha256": "0770b4dd885f3018031c2d27fc090a34027d5856a248f33fa2a415d58da74632"
|
||||
},
|
||||
"catalina": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/carthage/blobs/sha256:8a07c198835cb179d4054313b199ce126e64bb9414eaaa91f55162a4aed63134",
|
||||
"sha256": "8a07c198835cb179d4054313b199ce126e64bb9414eaaa91f55162a4aed63134"
|
||||
},
|
||||
"mojave": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/carthage/blobs/sha256:7fb777ac169aa4cb05683f0f8bfb5b56dbb0b0e8b673df995ef2fb2bbe0d90d2",
|
||||
"sha256": "7fb777ac169aa4cb05683f0f8bfb5b56dbb0b0e8b673df995ef2fb2bbe0d90d2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"make": {
|
||||
"version": "4.3",
|
||||
"bottle": {
|
||||
"rebuild": 1,
|
||||
"root_url": "https://ghcr.io/v2/homebrew/core",
|
||||
"files": {
|
||||
"arm64_big_sur": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/make/blobs/sha256:eab3fbc3688aecec0fe90b8d0fe3cb7beb84ed773ba0411fc2f855c66deaf882",
|
||||
"sha256": "eab3fbc3688aecec0fe90b8d0fe3cb7beb84ed773ba0411fc2f855c66deaf882"
|
||||
},
|
||||
"big_sur": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/make/blobs/sha256:2019ba646e4471d42e09c28a0992c59dd82e292bf8275b0b3bfcce3220ef9c1b",
|
||||
"sha256": "2019ba646e4471d42e09c28a0992c59dd82e292bf8275b0b3bfcce3220ef9c1b"
|
||||
},
|
||||
"catalina": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/make/blobs/sha256:39fc5ebff5ff708c2e3eea597b9f2eb79b910a122d30c3ac9bb93ebe313f030c",
|
||||
"sha256": "39fc5ebff5ff708c2e3eea597b9f2eb79b910a122d30c3ac9bb93ebe313f030c"
|
||||
},
|
||||
"mojave": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/make/blobs/sha256:0c0a08eef68bcd78b0345f5f57a6efffcc7be877bcb3b803f39ac8916b882477",
|
||||
"sha256": "0c0a08eef68bcd78b0345f5f57a6efffcc7be877bcb3b803f39ac8916b882477"
|
||||
},
|
||||
"high_sierra": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/make/blobs/sha256:429177235322c3209e1657bea36364cd84222075b636939f6ed93a1cd04aeb21",
|
||||
"sha256": "429177235322c3209e1657bea36364cd84222075b636939f6ed93a1cd04aeb21"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shfmt": {
|
||||
"version": "3.2.4",
|
||||
"bottle": {
|
||||
|
|
1
Cartfile
1
Cartfile
|
@ -1 +0,0 @@
|
|||
github "Carthage/Commandant"
|
|
@ -1,2 +0,0 @@
|
|||
github "Quick/Quick"
|
||||
github "Quick/Nimble"
|
|
@ -1,3 +0,0 @@
|
|||
github "Carthage/Commandant" "0.18.0"
|
||||
github "Quick/Nimble" "v9.0.1"
|
||||
github "Quick/Quick" "v3.1.2"
|
10
Dangerfile
10
Dangerfile
|
@ -8,14 +8,12 @@
|
|||
|
||||
# Sometimes it's a README fix, or something like that - which isn't relevant for
|
||||
# including in a project's CHANGELOG for example
|
||||
has_app_changes = !git.modified_files.grep(/MasKit/).empty?
|
||||
has_test_changes = !git.modified_files.grep(/MasKitTests/).empty?
|
||||
has_app_changes = !git.modified_files.grep(/Sources/).empty?
|
||||
has_test_changes = !git.modified_files.grep(/Tests/).empty?
|
||||
|
||||
is_version_bump = git.modified_files.sort == [
|
||||
"mas/mas-Info.plist",
|
||||
"mas-cli.xcodeproj/project.pbxproj",
|
||||
"MasKit/SupportingFiles/Info.plist",
|
||||
"MasKitTests/SupportingFiles/Info.plist"
|
||||
"Package.swift",
|
||||
"MasKit/SupportingFiles/Package.swift"
|
||||
].sort
|
||||
message(":bookmark: Version bump!") if is_version_bump
|
||||
|
||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -24,13 +24,17 @@ GEM
|
|||
no_proxy_fix
|
||||
octokit (~> 4.7)
|
||||
terminal-table (>= 1, < 4)
|
||||
faraday (1.3.0)
|
||||
faraday (1.4.1)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-http-cache (2.2.0)
|
||||
faraday (>= 0.8)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.1.0)
|
||||
git (1.8.1)
|
||||
rchardet (~> 1.8)
|
||||
kramdown (2.3.1)
|
||||
|
@ -40,7 +44,7 @@ GEM
|
|||
multipart-post (2.1.1)
|
||||
nap (1.1.0)
|
||||
no_proxy_fix (0.1.2)
|
||||
octokit (4.20.0)
|
||||
octokit (4.21.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
open4 (1.3.4)
|
||||
|
|
|
@ -18,27 +18,14 @@ class Mas < Formula
|
|||
sha256 cellar: :any, el_capitan: "d54d864976f78665d5175fd9e69ab81b3911fa28fd6ae627b61a18d55d68191a"
|
||||
end
|
||||
|
||||
depends_on "carthage" => :build
|
||||
depends_on :macos
|
||||
if Hardware::CPU.arm?
|
||||
depends_on xcode: ["12.2", :build]
|
||||
else
|
||||
depends_on xcode: ["11.4", :build]
|
||||
depends_on xcode: ["12.0", :build]
|
||||
end
|
||||
|
||||
def install
|
||||
# Working around build issues in dependencies
|
||||
# - Prevent warnings from causing build failures
|
||||
# - Prevent linker errors by telling all lib builds to use max size install names
|
||||
xcconfig = buildpath/"Overrides.xcconfig"
|
||||
xcconfig.write <<~EOS
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO
|
||||
OTHER_LDFLAGS = -headerpad_max_install_names
|
||||
EOS
|
||||
ENV["XCODE_XCCONFIG_FILE"] = xcconfig
|
||||
|
||||
# Only build necessary dependencies
|
||||
system "carthage", "bootstrap", "--platform", "macOS", "Commandant"
|
||||
system "script/install", prefix
|
||||
|
||||
bash_completion.install "contrib/completion/mas-completion.bash" => "mas"
|
||||
|
|
|
@ -13,27 +13,14 @@ class Mas < Formula
|
|||
sha256 cellar: :any, catalina: "2e7ffedf674543f98c2b95868b6a23db208cb2e6a3ec1ddbb3553ddab0cf9a68"
|
||||
end
|
||||
|
||||
depends_on "carthage" => :build
|
||||
depends_on :macos
|
||||
if Hardware::CPU.arm?
|
||||
depends_on xcode: ["12.2", :build]
|
||||
else
|
||||
depends_on xcode: ["11.4", :build]
|
||||
depends_on xcode: ["12.0", :build]
|
||||
end
|
||||
|
||||
def install
|
||||
# Working around build issues in dependencies
|
||||
# - Prevent warnings from causing build failures
|
||||
# - Prevent linker errors by telling all lib builds to use max size install names
|
||||
xcconfig = buildpath/"Overrides.xcconfig"
|
||||
xcconfig.write <<~EOS
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO
|
||||
OTHER_LDFLAGS = -headerpad_max_install_names
|
||||
EOS
|
||||
ENV["XCODE_XCCONFIG_FILE"] = xcconfig
|
||||
|
||||
# Only build necessary dependencies
|
||||
system "carthage", "bootstrap", "--platform", "macOS", "Commandant"
|
||||
system "script/install", prefix
|
||||
|
||||
bash_completion.install "contrib/completion/mas-completion.bash" => "mas"
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</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>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 Andrew Naylor. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// MasKit.h
|
||||
// MasKit
|
||||
//
|
||||
// Created by Ben Chatelain on 7/8/18.
|
||||
// Copyright © 2018 Andrew Naylor. All rights reserved.
|
||||
//
|
||||
|
||||
@import Foundation;
|
||||
|
||||
//! Project version number for MasKit.
|
||||
FOUNDATION_EXPORT double MasKitVersionNumber;
|
||||
|
||||
//! Project version string for MasKit.
|
||||
FOUNDATION_EXPORT const unsigned char MasKitVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <MasKit/PublicHeader.h>
|
|
@ -1,85 +0,0 @@
|
|||
//
|
||||
// OutputListener.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 1/7/19.
|
||||
// Copyright © 2019 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Test helper for monitoring strings written to stdout. Modified from:
|
||||
/// https://medium.com/@thesaadismail/eavesdropping-on-swifts-print-statements-57f0215efb42
|
||||
class OutputListener {
|
||||
/// consumes the messages on STDOUT
|
||||
let inputPipe = Pipe()
|
||||
|
||||
/// outputs messages back to STDOUT
|
||||
let outputPipe = Pipe()
|
||||
|
||||
/// Buffers strings written to stdout
|
||||
var contents = ""
|
||||
|
||||
init() {
|
||||
// Set up a read handler which fires when data is written to our inputPipe
|
||||
inputPipe.fileHandleForReading.readabilityHandler = { [weak self] fileHandle in
|
||||
strongify(self) { context in
|
||||
let data = fileHandle.availableData
|
||||
if let string = String(data: data, encoding: String.Encoding.utf8) {
|
||||
context.contents += string
|
||||
}
|
||||
|
||||
// Write input back to stdout
|
||||
context.outputPipe.fileHandleForWriting.write(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension OutputListener {
|
||||
/// Sets up the "tee" of piped output, intercepting stdout then passing it through.
|
||||
///
|
||||
/// ## [dup2 documentation](https://linux.die.net/man/2/dup2)
|
||||
/// `int dup2(int oldfd, int newfd);`
|
||||
/// `dup2()` makes `newfd` be the copy of `oldfd`, closing `newfd` first if necessary.
|
||||
func openConsolePipe() {
|
||||
var dupStatus: Int32
|
||||
|
||||
// Copy STDOUT file descriptor to outputPipe for writing strings back to STDOUT
|
||||
dupStatus = dup2(stdoutFileDescriptor, outputPipe.fileHandleForWriting.fileDescriptor)
|
||||
// Status should equal newfd
|
||||
assert(dupStatus == outputPipe.fileHandleForWriting.fileDescriptor)
|
||||
|
||||
// Intercept STDOUT with inputPipe
|
||||
// newFileDescriptor is the pipe's file descriptor and the old file descriptor is STDOUT_FILENO
|
||||
dupStatus = dup2(inputPipe.fileHandleForWriting.fileDescriptor, stdoutFileDescriptor)
|
||||
// Status should equal newfd
|
||||
assert(dupStatus == stdoutFileDescriptor)
|
||||
|
||||
// Don't have any tests on stderr yet
|
||||
// dup2(inputPipe.fileHandleForWriting.fileDescriptor, stderr)
|
||||
}
|
||||
|
||||
/// Tears down the "tee" of piped output.
|
||||
func closeConsolePipe() {
|
||||
// Restore stdout
|
||||
freopen("/dev/stdout", "a", stdout)
|
||||
|
||||
[inputPipe.fileHandleForReading, outputPipe.fileHandleForWriting]
|
||||
.forEach { file in
|
||||
file.closeFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension OutputListener {
|
||||
/// File descriptor for stdout (aka STDOUT_FILENO)
|
||||
var stdoutFileDescriptor: Int32 {
|
||||
FileHandle.standardOutput.fileDescriptor
|
||||
}
|
||||
|
||||
/// File descriptor for stderr (aka STDERR_FILENO)
|
||||
var stderrFileDescriptor: Int32 {
|
||||
FileHandle.standardError.fileDescriptor
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</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>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
</dict>
|
||||
</plist>
|
61
Package.resolved
Normal file
61
Package.resolved
Normal file
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "Commandant",
|
||||
"repositoryURL": "https://github.com/Carthage/Commandant.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "a1671cf728db837cf5ec1980a80d276bbba748f6",
|
||||
"version": "0.18.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "CwlCatchException",
|
||||
"repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "f809deb30dc5c9d9b78c872e553261a61177721a",
|
||||
"version": "2.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "CwlPreconditionTesting",
|
||||
"repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "02b7a39a99c4da27abe03cab2053a9034379639f",
|
||||
"version": "2.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Nimble",
|
||||
"repositoryURL": "https://github.com/Quick/Nimble.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "7a54aaf19a8ef16f67787c260fda81ead7ba4d67",
|
||||
"version": "9.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Quick",
|
||||
"repositoryURL": "https://github.com/Quick/Quick.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "8cce6acd38f965f5baa3167b939f86500314022b",
|
||||
"version": "3.1.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Version",
|
||||
"repositoryURL": "https://github.com/mxcl/Version.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "a94b48f36763c05629fc102837398505032dead9",
|
||||
"version": "2.0.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
70
Package.swift
Normal file
70
Package.swift
Normal file
|
@ -0,0 +1,70 @@
|
|||
// swift-tools-version:5.3
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "mas",
|
||||
platforms: [
|
||||
.macOS(.v10_11),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
.executable(
|
||||
name: "mas",
|
||||
targets: ["mas"]
|
||||
),
|
||||
.library(
|
||||
name: "MasKit",
|
||||
targets: ["MasKit"]
|
||||
),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
.package(url: "https://github.com/Carthage/Commandant.git", from: "0.18.0"),
|
||||
.package(url: "https://github.com/Quick/Nimble.git", from: "9.0.1"),
|
||||
.package(url: "https://github.com/Quick/Quick.git", from: "3.1.2"),
|
||||
.package(url: "https://github.com/mxcl/Version.git", from: "2.0.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "mas",
|
||||
dependencies: ["MasKit"],
|
||||
swiftSettings: [
|
||||
.unsafeFlags([
|
||||
"-I", "Sources/PrivateFrameworks/CommerceKit",
|
||||
"-I", "Sources/PrivateFrameworks/StoreFoundation",
|
||||
]),
|
||||
]
|
||||
),
|
||||
.target(
|
||||
name: "MasKit",
|
||||
dependencies: ["Commandant", "Version"],
|
||||
swiftSettings: [
|
||||
.unsafeFlags([
|
||||
"-I", "Sources/PrivateFrameworks/CommerceKit",
|
||||
"-I", "Sources/PrivateFrameworks/StoreFoundation",
|
||||
]),
|
||||
],
|
||||
linkerSettings: [
|
||||
.linkedFramework("CommerceKit"),
|
||||
.linkedFramework("StoreFoundation"),
|
||||
.unsafeFlags(["-F", "/System/Library/PrivateFrameworks"]),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "MasKitTests",
|
||||
dependencies: ["MasKit", "Nimble", "Quick"],
|
||||
resources: [.copy("JSON")],
|
||||
swiftSettings: [
|
||||
.unsafeFlags([
|
||||
"-I", "Sources/PrivateFrameworks/CommerceKit",
|
||||
"-I", "Sources/PrivateFrameworks/StoreFoundation",
|
||||
]),
|
||||
]
|
||||
),
|
||||
],
|
||||
swiftLanguageVersions: [.v5]
|
||||
)
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>BundleIsVersionChecked</key>
|
||||
<true/>
|
||||
<key>BundleOverwriteAction</key>
|
||||
<string>upgrade</string>
|
||||
<key>ChildBundles</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BundleOverwriteAction</key>
|
||||
<string></string>
|
||||
<key>RootRelativeBundlePath</key>
|
||||
<string>Frameworks/MasKit.framework/Versions/A/Frameworks/Commandant.framework</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>RootRelativeBundlePath</key>
|
||||
<string>Frameworks/MasKit.framework</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
|
@ -5,7 +5,7 @@
|
|||
<options customize="never" require-scripts="false"/>
|
||||
<volume-check>
|
||||
<allowed-os-versions>
|
||||
<os-version min="10.10"/>
|
||||
<os-version min="10.11"/>
|
||||
</allowed-os-versions>
|
||||
</volume-check>
|
||||
<choices-outline>
|
||||
|
|
|
@ -8,7 +8,7 @@ A simple command line interface for the Mac App Store. Designed for scripting an
|
|||
[![Swift 5](https://img.shields.io/badge/Language-Swift_5-orange.svg)](https://swift.org)
|
||||
[![GitHub Release](https://img.shields.io/github/release/mas-cli/mas.svg)](https://github.com/mas-cli/mas/releases)
|
||||
[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
|
||||
[![Pipeline Status](https://jenkins.log-g.co/buildStatus/icon?job=mas-cli/mas/master)](https://jenkins.log-g.co/job/mas-cli/job/mas/job/master/)
|
||||
[![Build & Test](https://github.com/mas-cli/mas/actions/workflows/build-test.yml/badge.svg?branch=master)](https://github.com/mas-cli/mas/actions/workflows/build-test.yml?query=branch%3Amaster)
|
||||
|
||||
## 📲 Install
|
||||
|
||||
|
@ -205,7 +205,7 @@ reattach-to-user-namespace mas install
|
|||
|
||||
## ℹ️ Build from source
|
||||
|
||||
You can now build from Xcode by opening `mas-cli.xcodeproj`, or from the Terminal:
|
||||
You can build from Xcode by opening the root `mas` directory, or from the Terminal:
|
||||
|
||||
```bash
|
||||
script/build
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
import Commandant
|
||||
import Foundation
|
||||
|
||||
private let markerValue = "appstore"
|
||||
private let masScheme = "macappstore"
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
import Commandant
|
||||
import Foundation
|
||||
|
||||
/// Command which displays a list of installed apps which have available updates
|
||||
/// ready to be installed from the Mac App Store.
|
|
@ -31,7 +31,7 @@ public struct SignInCommand: CommandProtocol {
|
|||
printInfo("Signing in to Apple ID: \(options.username)")
|
||||
|
||||
let password: String = {
|
||||
if options.password == "", !options.dialog {
|
||||
if options.password.isEmpty, !options.dialog {
|
||||
return String(validatingUTF8: getpass("Password: "))!
|
||||
}
|
||||
return options.password
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
import Commandant
|
||||
import Foundation
|
||||
|
||||
/// Command which upgrades apps with new versions available in the Mac App Store.
|
||||
public struct UpgradeCommand: CommandProtocol {
|
|
@ -18,10 +18,7 @@ public struct VersionCommand: CommandProtocol {
|
|||
|
||||
/// Runs the command.
|
||||
public func run(_: Options) -> Result<Void, MASError> {
|
||||
let plist = Bundle.main.infoDictionary
|
||||
if let versionString = plist?["CFBundleShortVersionString"] {
|
||||
print(versionString)
|
||||
}
|
||||
print(Package.Version)
|
||||
return .success(())
|
||||
}
|
||||
}
|
|
@ -19,18 +19,6 @@ protocol AppLibrary {
|
|||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
func installedApp(forId: UInt64) -> SoftwareProduct?
|
||||
|
||||
/// Finds an app by it's bundle identifier.
|
||||
///
|
||||
/// - Parameter forBundleId: Bundle identifier of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
func installedApp(forBundleId: String) -> SoftwareProduct?
|
||||
|
||||
/// Finds an app by name.
|
||||
///
|
||||
/// - Parameter named: Name of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
func installedApp(named: String) -> SoftwareProduct?
|
||||
|
||||
/// Uninstalls an app.
|
||||
///
|
||||
/// - Parameter app: App to be removed.
|
|
@ -19,18 +19,14 @@ struct AppListFormatter {
|
|||
/// - Returns: Multiliune text outoutp.
|
||||
static func format(products: [SoftwareProduct]) -> String {
|
||||
// find longest appName for formatting, default 50
|
||||
let maxLength =
|
||||
products.map(\.appNameOrBbundleIdentifier)
|
||||
.max(by: { $1.count > $0.count })?
|
||||
.count
|
||||
?? nameColumnMinWidth
|
||||
let maxLength = products.map(\.appNameOrBundleIdentifier.count).max() ?? nameColumnMinWidth
|
||||
|
||||
var output: String = ""
|
||||
|
||||
for product in products {
|
||||
let appId = product.itemIdentifier.stringValue
|
||||
.padding(toLength: idColumnMinWidth, withPad: " ", startingAt: 0)
|
||||
let appName = product.appNameOrBbundleIdentifier.padding(toLength: maxLength, withPad: " ", startingAt: 0)
|
||||
let appName = product.appNameOrBundleIdentifier.padding(toLength: maxLength, withPad: " ", startingAt: 0)
|
||||
let version = product.bundleVersion
|
||||
|
||||
output += "\(appId) \(appName) (\(version))\n"
|
|
@ -13,6 +13,23 @@ import Foundation
|
|||
/// Terminal Control Sequence Indicator
|
||||
let csi = "\u{001B}["
|
||||
|
||||
var printObserver: ((String) -> Void)?
|
||||
|
||||
// Override global print for testability.
|
||||
// See MasKitTests/OutputListener.swift.
|
||||
func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
|
||||
let output = items
|
||||
.map { "\($0)" }
|
||||
.joined(separator: separator)
|
||||
.appending(terminator)
|
||||
|
||||
if let observer = printObserver {
|
||||
observer(output)
|
||||
}
|
||||
|
||||
Swift.print(output)
|
||||
}
|
||||
|
||||
func printInfo(_ message: String) {
|
||||
guard isatty(fileno(stdout)) != 0 else {
|
||||
print("==> \(message)")
|
|
@ -29,8 +29,8 @@ extension SoftwareProduct {
|
|||
}
|
||||
|
||||
/// Returns bundleIdentifier if appName is empty string.
|
||||
var appNameOrBbundleIdentifier: String {
|
||||
appName == "" ? bundleIdentifier : appName
|
||||
var appNameOrBundleIdentifier: String {
|
||||
appName.isEmpty ? bundleIdentifier : appName
|
||||
}
|
||||
|
||||
func isOutdatedWhenComparedTo(_ storeApp: SearchResult) -> Bool {
|
|
@ -59,16 +59,11 @@ class InfoCommandSpec: QuickSpec {
|
|||
it("displays app details") {
|
||||
storeSearch.apps[result.trackId] = result
|
||||
let output = OutputListener()
|
||||
output.openConsolePipe()
|
||||
|
||||
let result = cmd.run(InfoCommand.Options(appId: result.trackId))
|
||||
|
||||
expect(result).to(beSuccess())
|
||||
// output is async so need to wait for contents to be updated
|
||||
expect(output.contents).toEventuallyNot(beEmpty())
|
||||
expect(output.contents) == expectedOutput
|
||||
|
||||
output.closeConsolePipe()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
// Copyright © 2019 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Nimble
|
||||
import Quick
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue