mirror of
https://github.com/kkebo/DNSecure.git
synced 2026-03-11 08:54:36 +00:00
Merge pull request #101 from kkebo/add-ci
This commit is contained in:
commit
d92b2d1999
13 changed files with 157 additions and 37 deletions
21
.github/workflows/ci.yml
vendored
Normal file
21
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: ci
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
container: swift:6.1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: swift format lint -rsp .
|
||||
yamllint:
|
||||
runs-on: ubuntu-latest
|
||||
container: alpine:3.21
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: apk update && apk add yamllint
|
||||
- run: yamllint --version
|
||||
- run: yamllint --strict --config-file .yamllint.yml .
|
||||
79
.swift-format
Normal file
79
.swift-format
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"fileScopedDeclarationPrivacy" : {
|
||||
"accessLevel" : "private"
|
||||
},
|
||||
"indentConditionalCompilationBlocks" : true,
|
||||
"indentSwitchCaseLabels" : false,
|
||||
"indentation" : {
|
||||
"spaces" : 4
|
||||
},
|
||||
"lineBreakAroundMultilineExpressionChainComponents" : true,
|
||||
"lineBreakBeforeControlFlowKeywords" : false,
|
||||
"lineBreakBeforeEachArgument" : true,
|
||||
"lineBreakBeforeEachGenericRequirement" : true,
|
||||
"lineBreakBetweenDeclarationAttributes" : false,
|
||||
"lineLength" : 120,
|
||||
"maximumBlankLines" : 1,
|
||||
"multiElementCollectionTrailingCommas" : true,
|
||||
"noAssignmentInExpressions" : {
|
||||
"allowedFunctions" : [
|
||||
"XCTAssertNoThrow"
|
||||
]
|
||||
},
|
||||
"prioritizeKeepingFunctionOutputTogether" : true,
|
||||
"reflowMultilineStringLiterals" : {
|
||||
"never" : {
|
||||
|
||||
}
|
||||
},
|
||||
"respectsExistingLineBreaks" : true,
|
||||
"rules" : {
|
||||
"AllPublicDeclarationsHaveDocumentation" : false,
|
||||
"AlwaysUseLiteralForEmptyCollectionInit" : true,
|
||||
"AlwaysUseLowerCamelCase" : true,
|
||||
"AmbiguousTrailingClosureOverload" : true,
|
||||
"AvoidRetroactiveConformances" : false,
|
||||
"BeginDocumentationCommentWithOneLineSummary" : true,
|
||||
"DoNotUseSemicolons" : true,
|
||||
"DontRepeatTypeInStaticProperties" : true,
|
||||
"FileScopedDeclarationPrivacy" : true,
|
||||
"FullyIndirectEnum" : true,
|
||||
"GroupNumericLiterals" : true,
|
||||
"IdentifiersMustBeASCII" : true,
|
||||
"NeverForceUnwrap" : false,
|
||||
"NeverUseForceTry" : true,
|
||||
"NeverUseImplicitlyUnwrappedOptionals" : true,
|
||||
"NoAccessLevelOnExtensionDeclaration" : true,
|
||||
"NoAssignmentInExpressions" : true,
|
||||
"NoBlockComments" : true,
|
||||
"NoCasesWithOnlyFallthrough" : true,
|
||||
"NoEmptyLinesOpeningClosingBraces" : true,
|
||||
"NoEmptyTrailingClosureParentheses" : true,
|
||||
"NoLabelsInCasePatterns" : true,
|
||||
"NoLeadingUnderscores" : true,
|
||||
"NoParensAroundConditions" : true,
|
||||
"NoPlaygroundLiterals" : true,
|
||||
"NoVoidReturnOnFunctionSignature" : true,
|
||||
"OmitExplicitReturns" : true,
|
||||
"OneCasePerLine" : true,
|
||||
"OneVariableDeclarationPerLine" : true,
|
||||
"OnlyOneTrailingClosureArgument" : true,
|
||||
"OrderedImports" : true,
|
||||
"ReplaceForEachWithForLoop" : true,
|
||||
"ReturnVoidInsteadOfEmptyTuple" : true,
|
||||
"TypeNamesShouldBeCapitalized" : true,
|
||||
"UseEarlyExits" : true,
|
||||
"UseExplicitNilCheckInConditions" : true,
|
||||
"UseLetInEveryBoundCaseVariable" : true,
|
||||
"UseShorthandTypeNames" : true,
|
||||
"UseSingleLinePropertyGetter" : true,
|
||||
"UseSynthesizedInitializer" : true,
|
||||
"UseTripleSlashForDocumentationComments" : true,
|
||||
"UseWhereClausesInForLoops" : true,
|
||||
"ValidateDocumentationComments" : true
|
||||
},
|
||||
"spacesAroundRangeFormationOperators" : false,
|
||||
"spacesBeforeEndOfLineComments" : 2,
|
||||
"tabWidth" : 4,
|
||||
"version" : 1
|
||||
}
|
||||
7
.yamllint.yml
Normal file
7
.yamllint.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
extends: default
|
||||
|
||||
rules:
|
||||
line-length: false
|
||||
document-start: false
|
||||
truthy:
|
||||
check-keys: false
|
||||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Kenta Kubo on 7/1/20.
|
||||
//
|
||||
|
||||
import os.log
|
||||
import SwiftUI
|
||||
import os.log
|
||||
|
||||
let logger = Logger()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ extension NEOnDemandRuleInterfaceType: @retroactive CustomStringConvertible {
|
|||
case .any:
|
||||
return "Any"
|
||||
#if os(macOS)
|
||||
case .ethernet:
|
||||
return "Ethernet"
|
||||
case .ethernet:
|
||||
return "Ethernet"
|
||||
#endif
|
||||
case .wiFi:
|
||||
return "Wi-Fi"
|
||||
#if os(iOS)
|
||||
case .cellular:
|
||||
return "Cellular"
|
||||
case .cellular:
|
||||
return "Cellular"
|
||||
#endif
|
||||
default:
|
||||
return "Unknown"
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ enum Presets {
|
|||
configuration: .dnsOverTLS(
|
||||
DoTConfiguration(
|
||||
servers: [
|
||||
"116.202.176.26",
|
||||
"116.202.176.26"
|
||||
],
|
||||
serverName: "dot.libredns.gr"
|
||||
)
|
||||
|
|
@ -137,7 +137,7 @@ enum Presets {
|
|||
configuration: .dnsOverHTTPS(
|
||||
DoHConfiguration(
|
||||
servers: [
|
||||
"116.202.176.26",
|
||||
"116.202.176.26"
|
||||
],
|
||||
serverURL: URL(string: "https://doh.libredns.gr/dns-query")
|
||||
)
|
||||
|
|
@ -148,7 +148,7 @@ enum Presets {
|
|||
configuration: .dnsOverHTTPS(
|
||||
DoHConfiguration(
|
||||
servers: [
|
||||
"116.202.176.26",
|
||||
"116.202.176.26"
|
||||
],
|
||||
serverURL: URL(string: "https://doh.libredns.gr/ads")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ enum Configuration {
|
|||
|
||||
func toDNSSettings() -> NEDNSSettings {
|
||||
switch self {
|
||||
case let .dnsOverTLS(configuration):
|
||||
case .dnsOverTLS(let configuration):
|
||||
return configuration.toDNSSettings()
|
||||
case let .dnsOverHTTPS(configuration):
|
||||
case .dnsOverHTTPS(let configuration):
|
||||
return configuration.toDNSSettings()
|
||||
}
|
||||
}
|
||||
|
|
@ -87,10 +87,10 @@ extension Configuration: Codable {
|
|||
var container = encoder.container(keyedBy: Self.CodingKeys.self)
|
||||
|
||||
switch self {
|
||||
case let .dnsOverTLS(configuration):
|
||||
case .dnsOverTLS(let configuration):
|
||||
try container.encode(Self.Base.dnsOverTLS, forKey: .base)
|
||||
try container.encode(configuration, forKey: .dotConfiguration)
|
||||
case let .dnsOverHTTPS(configuration):
|
||||
case .dnsOverHTTPS(let configuration):
|
||||
try container.encode(Self.Base.dnsOverHTTPS, forKey: .base)
|
||||
try container.encode(configuration, forKey: .dohConfiguration)
|
||||
}
|
||||
|
|
@ -200,10 +200,11 @@ extension Resolver: Codable {
|
|||
self.id = try container.decode(UUID.self, forKey: .id)
|
||||
self.name = try container.decode(String.self, forKey: .name)
|
||||
self.configuration = try container.decode(Configuration.self, forKey: .configuration)
|
||||
self.onDemandRules = try container.decodeIfPresent(
|
||||
[OnDemandRule].self,
|
||||
forKey: .onDemandRules
|
||||
) ?? []
|
||||
self.onDemandRules =
|
||||
try container.decodeIfPresent(
|
||||
[OnDemandRule].self,
|
||||
forKey: .onDemandRules
|
||||
) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +219,7 @@ extension Resolvers {
|
|||
extension Resolvers: @retroactive RawRepresentable {
|
||||
public init?(rawValue: String) {
|
||||
guard let data = rawValue.data(using: .utf8),
|
||||
let result = try? JSONDecoder().decode(Self.self, from: data)
|
||||
let result = try? JSONDecoder().decode(Self.self, from: data)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -227,7 +228,7 @@ extension Resolvers: @retroactive RawRepresentable {
|
|||
|
||||
public var rawValue: String {
|
||||
guard let data = try? JSONEncoder().encode(self),
|
||||
let result = String(data: data, encoding: .utf8)
|
||||
let result = String(data: data, encoding: .utf8)
|
||||
else {
|
||||
return "[]"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,8 +90,10 @@ struct ContentView {
|
|||
manager.onDemandRules = server.onDemandRules.toNEOnDemandRules()
|
||||
manager.saveToPreferences { saveError in
|
||||
if let saveError = saveError as NSError? {
|
||||
guard saveError.domain != "NEConfigurationErrorDomain"
|
||||
|| saveError.code != 9 else {
|
||||
guard
|
||||
saveError.domain != "NEConfigurationErrorDomain"
|
||||
|| saveError.code != 9
|
||||
else {
|
||||
// Nothing was changed
|
||||
return
|
||||
}
|
||||
|
|
@ -187,8 +189,9 @@ extension ContentView: View {
|
|||
// FIXME: This is a workaround for self.$severs[i].
|
||||
// That cannot save settings as soon as it is modified.
|
||||
guard let id = self.usedID,
|
||||
let uuid = UUID(uuidString: id),
|
||||
let server = self.servers.find(by: uuid) else {
|
||||
let uuid = UUID(uuidString: id),
|
||||
let server = self.servers.find(by: uuid)
|
||||
else {
|
||||
return
|
||||
}
|
||||
self.saveSettings(of: server)
|
||||
|
|
@ -263,8 +266,9 @@ extension ContentView: View {
|
|||
// FIXME: This is a workaround for self.$severs[i].
|
||||
// That cannot save settings as soon as it is modified.
|
||||
guard let id = self.usedID,
|
||||
let uuid = UUID(uuidString: id),
|
||||
let server = self.servers.find(by: uuid) else {
|
||||
let uuid = UUID(uuidString: id),
|
||||
let server = self.servers.find(by: uuid)
|
||||
else {
|
||||
return
|
||||
}
|
||||
self.saveSettings(of: server)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ struct RestorationView {
|
|||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var selection = Set<Resolver>()
|
||||
@State private var keyword = ""
|
||||
let onAdd: (Set<Resolver>) -> ()
|
||||
let onAdd: (Set<Resolver>) -> Void
|
||||
|
||||
private var servers: Resolvers {
|
||||
guard !self.keyword.isEmpty else { return Presets.servers }
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ extension RuleView: View {
|
|||
} header: {
|
||||
Text("Interface Type Match")
|
||||
} footer: {
|
||||
Text("If the current primary network interface is of this type and all of the other conditions in the rule match, then the rule matches.")
|
||||
Text(
|
||||
"If the current primary network interface is of this type and all of the other conditions in the rule match, then the rule matches."
|
||||
)
|
||||
}
|
||||
|
||||
if self.rule.interfaceType.ssidIsUsed {
|
||||
|
|
@ -65,7 +67,9 @@ extension RuleView: View {
|
|||
Text("SSID Match")
|
||||
}
|
||||
} footer: {
|
||||
Text("If the Service Set Identifier (SSID) of the current primary connected network matches one of the strings in this array and all of the other conditions in the rule match, then the rule matches.")
|
||||
Text(
|
||||
"If the Service Set Identifier (SSID) of the current primary connected network matches one of the strings in this array and all of the other conditions in the rule match, then the rule matches."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +96,9 @@ extension RuleView: View {
|
|||
Text("DNS Search Domain Match")
|
||||
}
|
||||
} footer: {
|
||||
Text("If the current default search domain is equal to one of the strings in this array and all of the other conditions in the rule match, then the rule matches.")
|
||||
Text(
|
||||
"If the current default search domain is equal to one of the strings in this array and all of the other conditions in the rule match, then the rule matches."
|
||||
)
|
||||
}
|
||||
|
||||
Section {
|
||||
|
|
@ -118,7 +124,9 @@ extension RuleView: View {
|
|||
Text("DNS Server Address Match")
|
||||
}
|
||||
} footer: {
|
||||
Text("If each of the current default DNS servers is equal to one of the strings in this array and all of the other conditions in the rule match, then the rule matches.")
|
||||
Text(
|
||||
"If each of the current default DNS servers is equal to one of the strings in this array and all of the other conditions in the rule match, then the rule matches."
|
||||
)
|
||||
}
|
||||
|
||||
Section {
|
||||
|
|
@ -132,7 +140,9 @@ extension RuleView: View {
|
|||
} header: {
|
||||
Text("Probe URL Match")
|
||||
} footer: {
|
||||
Text("If a request sent to this URL results in a HTTP 200 OK response and all of the other conditions in the rule match, then the rule matches. If you don't want to use this rule, leave it empty.")
|
||||
Text(
|
||||
"If a request sent to this URL results in a HTTP 200 OK response and all of the other conditions in the rule match, then the rule matches. If you don't want to use this rule, leave it empty."
|
||||
)
|
||||
}
|
||||
}
|
||||
.navigationTitle(self.rule.name)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import DNSecure
|
||||
|
||||
class DNSecureTests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
|
@ -29,5 +29,4 @@ class DNSecureTests: XCTestCase {
|
|||
// Put the code you want to measure the time of here.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
import XCTest
|
||||
|
||||
class DNSecureUITests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
// This file is automatically generated.
|
||||
// Do not edit it by hand because the contents will be replaced.
|
||||
|
||||
import PackageDescription
|
||||
import AppleProductTypes
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "DNSecure",
|
||||
|
|
@ -24,13 +24,13 @@ let package = Package(
|
|||
accentColor: .asset("AccentColor"),
|
||||
supportedDeviceFamilies: [
|
||||
.pad,
|
||||
.phone
|
||||
.phone,
|
||||
],
|
||||
supportedInterfaceOrientations: [
|
||||
.portrait,
|
||||
.landscapeRight,
|
||||
.landscapeLeft,
|
||||
.portraitUpsideDown(.when(deviceFamilies: [.pad]))
|
||||
.portraitUpsideDown(.when(deviceFamilies: [.pad])),
|
||||
],
|
||||
appCategory: .utilities
|
||||
)
|
||||
|
|
@ -46,6 +46,6 @@ let package = Package(
|
|||
"DNSecure"
|
||||
],
|
||||
path: "DNSecureTests"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue