mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-18 11:13:28 +01:00
XCode project for app, moved app project to folder
This commit is contained in:
61
SideStoreApp/Sources/Cargo/swiftlint/Commands/Analyze.swift
Normal file
61
SideStoreApp/Sources/Cargo/swiftlint/Commands/Analyze.swift
Normal file
@@ -0,0 +1,61 @@
|
||||
import ArgumentParser
|
||||
import SwiftLintFramework
|
||||
|
||||
extension SwiftLint {
|
||||
struct Analyze: AsyncParsableCommand {
|
||||
static let configuration = CommandConfiguration(abstract: "Run analysis rules")
|
||||
|
||||
@OptionGroup
|
||||
var common: LintOrAnalyzeArguments
|
||||
@Option(help: pathOptionDescription(for: .analyze))
|
||||
var path: String?
|
||||
@Flag(help: quietOptionDescription(for: .analyze))
|
||||
var quiet = false
|
||||
@Option(help: "The path of the full xcodebuild log to use when running AnalyzerRules.")
|
||||
var compilerLogPath: String?
|
||||
@Option(help: "The path of a compilation database to use when running AnalyzerRules.")
|
||||
var compileCommands: String?
|
||||
@Argument(help: pathsArgumentDescription(for: .analyze))
|
||||
var paths = [String]()
|
||||
|
||||
func run() async throws {
|
||||
let allPaths: [String]
|
||||
if let path {
|
||||
queuedPrintError("""
|
||||
warning: The --path option is deprecated. Pass the path(s) to analyze last to the swiftlint command.
|
||||
""")
|
||||
allPaths = [path] + paths
|
||||
} else if !paths.isEmpty {
|
||||
allPaths = paths
|
||||
} else {
|
||||
allPaths = [""] // Analyze files in current working directory if no paths were specified.
|
||||
}
|
||||
let options = LintOrAnalyzeOptions(
|
||||
mode: .analyze,
|
||||
paths: allPaths,
|
||||
useSTDIN: false,
|
||||
configurationFiles: common.config,
|
||||
strict: common.leniency == .strict,
|
||||
lenient: common.leniency == .lenient,
|
||||
forceExclude: common.forceExclude,
|
||||
useExcludingByPrefix: common.useAlternativeExcluding,
|
||||
useScriptInputFiles: common.useScriptInputFiles,
|
||||
benchmark: common.benchmark,
|
||||
reporter: common.reporter,
|
||||
quiet: quiet,
|
||||
output: common.output,
|
||||
progress: common.progress,
|
||||
cachePath: nil,
|
||||
ignoreCache: true,
|
||||
enableAllRules: false,
|
||||
autocorrect: common.fix,
|
||||
format: common.format,
|
||||
compilerLogPath: compilerLogPath,
|
||||
compileCommands: compileCommands,
|
||||
inProcessSourcekit: common.inProcessSourcekit
|
||||
)
|
||||
|
||||
try await LintOrAnalyzeCommand.run(options)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
extension RulesFilter.ExcludingOptions {
|
||||
static func excludingOptions(byCommandLineOptions rulesFilterOptions: RulesFilterOptions) -> Self {
|
||||
var excludingOptions: Self = []
|
||||
|
||||
switch rulesFilterOptions.ruleEnablement {
|
||||
case .enabled:
|
||||
excludingOptions.insert(.disabled)
|
||||
case .disabled:
|
||||
excludingOptions.insert(.enabled)
|
||||
case .none:
|
||||
break
|
||||
}
|
||||
|
||||
if rulesFilterOptions.correctable {
|
||||
excludingOptions.insert(.uncorrectable)
|
||||
}
|
||||
|
||||
return excludingOptions
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import ArgumentParser
|
||||
|
||||
enum RuleEnablementOptions: String, EnumerableFlag {
|
||||
case enabled, disabled
|
||||
|
||||
static func name(for value: RuleEnablementOptions) -> NameSpecification {
|
||||
return .shortAndLong
|
||||
}
|
||||
|
||||
static func help(for value: RuleEnablementOptions) -> ArgumentHelp? {
|
||||
return "Only show \(value.rawValue) rules"
|
||||
}
|
||||
}
|
||||
|
||||
struct RulesFilterOptions: ParsableArguments {
|
||||
@Flag(exclusivity: .exclusive)
|
||||
var ruleEnablement: RuleEnablementOptions?
|
||||
@Flag(name: .shortAndLong, help: "Only display correctable rules")
|
||||
var correctable = false
|
||||
}
|
||||
43
SideStoreApp/Sources/Cargo/swiftlint/Commands/Docs.swift
Normal file
43
SideStoreApp/Sources/Cargo/swiftlint/Commands/Docs.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
import SwiftLintFramework
|
||||
|
||||
extension SwiftLint {
|
||||
struct Docs: ParsableCommand {
|
||||
static let configuration = CommandConfiguration(
|
||||
abstract: "Open SwiftLint documentation website in the default web browser"
|
||||
)
|
||||
|
||||
@Argument(help: "The identifier of the rule to open the documentation for")
|
||||
var ruleID: String?
|
||||
|
||||
func run() throws {
|
||||
var subPage = ""
|
||||
if let ruleID {
|
||||
if primaryRuleList.list[ruleID] == nil {
|
||||
queuedPrintError("There is no rule named '\(ruleID)'. Opening rule directory instead.")
|
||||
subPage = "rule-directory.html"
|
||||
} else {
|
||||
subPage = ruleID + ".html"
|
||||
}
|
||||
}
|
||||
open(URL(string: "https://realm.github.io/SwiftLint/\(subPage)")!)
|
||||
ExitHelper.successfullyExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func open(_ url: URL) {
|
||||
let process = Process()
|
||||
#if os(Linux)
|
||||
process.executableURL = URL(fileURLWithPath: "/usr/bin/env", isDirectory: false)
|
||||
let command = "xdg-open"
|
||||
process.arguments = [command, url.absoluteString]
|
||||
try? process.run()
|
||||
#else
|
||||
process.launchPath = "/usr/bin/env"
|
||||
let command = "open"
|
||||
process.arguments = [command, url.absoluteString]
|
||||
process.launch()
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
import SwiftLintFramework
|
||||
|
||||
extension SwiftLint {
|
||||
struct GenerateDocs: ParsableCommand {
|
||||
static let configuration = CommandConfiguration(
|
||||
abstract: "Generates markdown documentation for selected group of rules"
|
||||
)
|
||||
|
||||
@Option(help: "The directory where the documentation should be saved")
|
||||
var path = "rule_docs"
|
||||
@Option(help: "The path to a SwiftLint configuration file")
|
||||
var config: String?
|
||||
@OptionGroup
|
||||
var rulesFilterOptions: RulesFilterOptions
|
||||
|
||||
func run() throws {
|
||||
let configuration = Configuration(configurationFiles: [config].compactMap({ $0 }))
|
||||
let rulesFilter = RulesFilter(enabledRules: configuration.rules)
|
||||
let rules = rulesFilter.getRules(excluding: .excludingOptions(byCommandLineOptions: rulesFilterOptions))
|
||||
|
||||
try RuleListDocumentation(rules)
|
||||
.write(to: URL(fileURLWithPath: path, isDirectory: true))
|
||||
ExitHelper.successfullyExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
64
SideStoreApp/Sources/Cargo/swiftlint/Commands/Lint.swift
Normal file
64
SideStoreApp/Sources/Cargo/swiftlint/Commands/Lint.swift
Normal file
@@ -0,0 +1,64 @@
|
||||
import ArgumentParser
|
||||
import SwiftLintFramework
|
||||
|
||||
extension SwiftLint {
|
||||
struct Lint: AsyncParsableCommand {
|
||||
static let configuration = CommandConfiguration(abstract: "Print lint warnings and errors")
|
||||
|
||||
@OptionGroup
|
||||
var common: LintOrAnalyzeArguments
|
||||
@Option(help: pathOptionDescription(for: .lint))
|
||||
var path: String?
|
||||
@Flag(help: "Lint standard input.")
|
||||
var useSTDIN = false
|
||||
@Flag(help: quietOptionDescription(for: .lint))
|
||||
var quiet = false
|
||||
@Option(help: "The directory of the cache used when linting.")
|
||||
var cachePath: String?
|
||||
@Flag(help: "Ignore cache when linting.")
|
||||
var noCache = false
|
||||
@Flag(help: "Run all rules, even opt-in and disabled ones, ignoring `only_rules`.")
|
||||
var enableAllRules = false
|
||||
@Argument(help: pathsArgumentDescription(for: .lint))
|
||||
var paths = [String]()
|
||||
|
||||
func run() async throws {
|
||||
let allPaths: [String]
|
||||
if let path {
|
||||
queuedPrintError("""
|
||||
warning: The --path option is deprecated. Pass the path(s) to lint last to the swiftlint command.
|
||||
""")
|
||||
allPaths = [path] + paths
|
||||
} else if !paths.isEmpty {
|
||||
allPaths = paths
|
||||
} else {
|
||||
allPaths = [""] // Lint files in current working directory if no paths were specified.
|
||||
}
|
||||
let options = LintOrAnalyzeOptions(
|
||||
mode: .lint,
|
||||
paths: allPaths,
|
||||
useSTDIN: useSTDIN,
|
||||
configurationFiles: common.config,
|
||||
strict: common.leniency == .strict,
|
||||
lenient: common.leniency == .lenient,
|
||||
forceExclude: common.forceExclude,
|
||||
useExcludingByPrefix: common.useAlternativeExcluding,
|
||||
useScriptInputFiles: common.useScriptInputFiles,
|
||||
benchmark: common.benchmark,
|
||||
reporter: common.reporter,
|
||||
quiet: quiet,
|
||||
output: common.output,
|
||||
progress: common.progress,
|
||||
cachePath: cachePath,
|
||||
ignoreCache: noCache,
|
||||
enableAllRules: enableAllRules,
|
||||
autocorrect: common.fix,
|
||||
format: common.format,
|
||||
compilerLogPath: nil,
|
||||
compileCommands: nil,
|
||||
inProcessSourcekit: common.inProcessSourcekit
|
||||
)
|
||||
try await LintOrAnalyzeCommand.run(options)
|
||||
}
|
||||
}
|
||||
}
|
||||
123
SideStoreApp/Sources/Cargo/swiftlint/Commands/Rules.swift
Normal file
123
SideStoreApp/Sources/Cargo/swiftlint/Commands/Rules.swift
Normal file
@@ -0,0 +1,123 @@
|
||||
import ArgumentParser
|
||||
#if canImport(Darwin)
|
||||
import Darwin
|
||||
#elseif canImport(Glibc)
|
||||
import Glibc
|
||||
#else
|
||||
#error("Unsupported platform")
|
||||
#endif
|
||||
import Foundation
|
||||
@_spi(TestHelper)
|
||||
import SwiftLintFramework
|
||||
import SwiftyTextTable
|
||||
|
||||
extension SwiftLint {
|
||||
struct Rules: ParsableCommand {
|
||||
static let configuration = CommandConfiguration(abstract: "Display the list of rules and their identifiers")
|
||||
|
||||
@Option(help: "The path to a SwiftLint configuration file")
|
||||
var config: String?
|
||||
@OptionGroup
|
||||
var rulesFilterOptions: RulesFilterOptions
|
||||
@Flag(name: .shortAndLong, help: "Display full configuration details")
|
||||
var verbose = false
|
||||
@Argument(help: "The rule identifier to display description for")
|
||||
var ruleID: String?
|
||||
|
||||
func run() throws {
|
||||
if let ruleID {
|
||||
guard let rule = primaryRuleList.list[ruleID] else {
|
||||
throw SwiftLintError.usageError(description: "No rule with identifier: \(ruleID)")
|
||||
}
|
||||
|
||||
rule.description.printDescription()
|
||||
return
|
||||
}
|
||||
|
||||
let configuration = Configuration(configurationFiles: [config].compactMap({ $0 }))
|
||||
let rulesFilter = RulesFilter(enabledRules: configuration.rules)
|
||||
let rules = rulesFilter.getRules(excluding: .excludingOptions(byCommandLineOptions: rulesFilterOptions))
|
||||
let table = TextTable(ruleList: rules, configuration: configuration, verbose: verbose)
|
||||
print(table.render())
|
||||
ExitHelper.successfullyExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension RuleDescription {
|
||||
func printDescription() {
|
||||
print("\(consoleDescription)")
|
||||
|
||||
guard !triggeringExamples.isEmpty else { return }
|
||||
|
||||
func indent(_ string: String) -> String {
|
||||
return string.components(separatedBy: "\n")
|
||||
.map { " \($0)" }
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
print("\nTriggering Examples (violation is marked with '↓'):")
|
||||
for (index, example) in triggeringExamples.enumerated() {
|
||||
print("\nExample #\(index + 1)\n\n\(indent(example.code))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SwiftyTextTable
|
||||
|
||||
private extension TextTable {
|
||||
init(ruleList: RuleList, configuration: Configuration, verbose: Bool) {
|
||||
let columns = [
|
||||
TextTableColumn(header: "identifier"),
|
||||
TextTableColumn(header: "opt-in"),
|
||||
TextTableColumn(header: "correctable"),
|
||||
TextTableColumn(header: "enabled in your config"),
|
||||
TextTableColumn(header: "kind"),
|
||||
TextTableColumn(header: "analyzer"),
|
||||
TextTableColumn(header: "uses sourcekit"),
|
||||
TextTableColumn(header: "configuration")
|
||||
]
|
||||
self.init(columns: columns)
|
||||
let sortedRules = ruleList.list.sorted { $0.0 < $1.0 }
|
||||
func truncate(_ string: String) -> String {
|
||||
let stringWithNoNewlines = string.replacingOccurrences(of: "\n", with: "\\n")
|
||||
let minWidth = "configuration".count - "...".count
|
||||
let configurationStartColumn = 140
|
||||
let maxWidth = verbose ? Int.max : Terminal.currentWidth()
|
||||
let truncatedEndIndex = stringWithNoNewlines.index(
|
||||
stringWithNoNewlines.startIndex,
|
||||
offsetBy: max(minWidth, maxWidth - configurationStartColumn),
|
||||
limitedBy: stringWithNoNewlines.endIndex
|
||||
)
|
||||
if let truncatedEndIndex {
|
||||
return stringWithNoNewlines[..<truncatedEndIndex] + "..."
|
||||
}
|
||||
return stringWithNoNewlines
|
||||
}
|
||||
for (ruleID, ruleType) in sortedRules {
|
||||
let rule = ruleType.init()
|
||||
let configuredRule = configuration.configuredRule(forID: ruleID)
|
||||
addRow(values: [
|
||||
ruleID,
|
||||
(rule is OptInRule) ? "yes" : "no",
|
||||
(rule is CorrectableRule) ? "yes" : "no",
|
||||
configuredRule != nil ? "yes" : "no",
|
||||
ruleType.description.kind.rawValue,
|
||||
(rule is AnalyzerRule) ? "yes" : "no",
|
||||
(rule is SourceKitFreeRule) ? "no" : "yes",
|
||||
truncate((configuredRule ?? rule).configurationDescription)
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct Terminal {
|
||||
static func currentWidth() -> Int {
|
||||
var size = winsize()
|
||||
#if os(Linux)
|
||||
_ = ioctl(CInt(STDOUT_FILENO), UInt(TIOCGWINSZ), &size)
|
||||
#else
|
||||
_ = ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)
|
||||
#endif
|
||||
return Int(size.ws_col)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
|
||||
@main
|
||||
struct SwiftLint: AsyncParsableCommand {
|
||||
static let configuration: CommandConfiguration = {
|
||||
if let directory = ProcessInfo.processInfo.environment["BUILD_WORKSPACE_DIRECTORY"] {
|
||||
FileManager.default.changeCurrentDirectoryPath(directory)
|
||||
}
|
||||
|
||||
return CommandConfiguration(
|
||||
commandName: "swiftlint",
|
||||
abstract: "A tool to enforce Swift style and conventions.",
|
||||
version: Version.value,
|
||||
subcommands: [
|
||||
Analyze.self,
|
||||
Docs.self,
|
||||
GenerateDocs.self,
|
||||
Lint.self,
|
||||
Rules.self,
|
||||
Version.self
|
||||
],
|
||||
defaultSubcommand: Lint.self
|
||||
)
|
||||
}()
|
||||
}
|
||||
23
SideStoreApp/Sources/Cargo/swiftlint/Commands/Version.swift
Normal file
23
SideStoreApp/Sources/Cargo/swiftlint/Commands/Version.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
import ArgumentParser
|
||||
import SwiftLintFramework
|
||||
|
||||
extension SwiftLint {
|
||||
struct Version: ParsableCommand {
|
||||
@Flag(help: "Display full version info")
|
||||
var verbose = false
|
||||
|
||||
static let configuration = CommandConfiguration(abstract: "Display the current version of SwiftLint")
|
||||
|
||||
static var value: String { SwiftLintFramework.Version.current.value }
|
||||
|
||||
func run() throws {
|
||||
if verbose, let buildID = ExecutableInfo.buildID {
|
||||
print("Version:", Self.value)
|
||||
print("Build ID:", buildID)
|
||||
} else {
|
||||
print(Self.value)
|
||||
}
|
||||
ExitHelper.successfullyExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user