Skip to content

Commit 59d5618

Browse files
committed
feat: Support single-formatter configurations with inline validation
1 parent 961e8c1 commit 59d5618

5 files changed

Lines changed: 182 additions & 87 deletions

File tree

EditorExtension/SourceEditorCommand.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ public class SourceEditorCommand: NSObject, XCSourceEditorCommand
4141

4242
configuration.withConfigurations
4343
{
44-
if uti == .swiftSource
44+
if uti == .swiftSource, let config = $0.swiftFormat?.path
4545
{
46-
self.format( buffer: invocation.buffer, executable: "swiftformat", arguments: [ "--config", $0.swiftFormat.path ] )
46+
self.format( buffer: invocation.buffer, executable: "swiftformat", arguments: [ "--config", config ] )
4747
}
4848

4949
$0.finished()

Shared/Configuration.swift

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,21 @@ import Foundation
2929
public class Configuration: NSObject, Codable
3030
{
3131
@objc public dynamic var name: String
32-
@objc public dynamic var swiftFormat: URL
33-
@objc public dynamic var uncrustify: URL
32+
@objc public dynamic var swiftFormat: URL?
33+
@objc public dynamic var uncrustify: URL?
3434
@objc public dynamic var downloading = false
3535

3636
public static var defaultConfigurations: [ Configuration ]
3737
{
3838
[
39-
Configuration( name: "XS-Labs", swiftFormat: "https://raw.githubusercontent.com/macmade/cgl/main/config/swiftformat-xs", uncrustify: "https://raw.githubusercontent.com/macmade/cgl/main/config/uncrustify.cfg" ),
40-
Configuration( name: "XS-Labs (MIT)", swiftFormat: "https://raw.githubusercontent.com/macmade/cgl/main/config/swiftformat-xs-mit", uncrustify: "https://raw.githubusercontent.com/macmade/cgl/main/config/uncrustify.cfg" ),
41-
Configuration( name: "DigiDNA", swiftFormat: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/swiftformat-ddna", uncrustify: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/uncrustify.cfg" ),
42-
Configuration( name: "DigiDNA (MIT)", swiftFormat: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/swiftformat-ddna-mit", uncrustify: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/uncrustify.cfg" ),
39+
Configuration( name: "XS-Labs", swiftFormat: URL( string: "https://raw.githubusercontent.com/macmade/cgl/main/config/swiftformat-xs" ), uncrustify: URL( string: "https://raw.githubusercontent.com/macmade/cgl/main/config/uncrustify.cfg" ) ),
40+
Configuration( name: "XS-Labs (MIT)", swiftFormat: URL( string: "https://raw.githubusercontent.com/macmade/cgl/main/config/swiftformat-xs-mit" ), uncrustify: URL( string: "https://raw.githubusercontent.com/macmade/cgl/main/config/uncrustify.cfg" ) ),
41+
Configuration( name: "DigiDNA", swiftFormat: URL( string: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/swiftformat-ddna" ), uncrustify: URL( string: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/uncrustify.cfg" ) ),
42+
Configuration( name: "DigiDNA (MIT)", swiftFormat: URL( string: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/swiftformat-ddna-mit" ), uncrustify: URL( string: "https://raw.githubusercontent.com/DigiDNA/cgl/main/config/uncrustify.cfg" ) ),
4343
]
44-
.compactMap { $0 }
4544
}
4645

47-
public convenience init?( name: String, swiftFormat: String, uncrustify: String )
48-
{
49-
guard let swiftFormat = URL( string: swiftFormat ),
50-
let uncrustify = URL( string: uncrustify )
51-
else
52-
{
53-
return nil
54-
}
55-
56-
self.init( name: name, swiftFormat: swiftFormat, uncrustify: uncrustify )
57-
}
58-
59-
public init( name: String, swiftFormat: URL, uncrustify: URL )
46+
public init( name: String, swiftFormat: URL?, uncrustify: URL? )
6047
{
6148
self.name = name
6249
self.swiftFormat = swiftFormat
@@ -106,8 +93,15 @@ public class Configuration: NSObject, Codable
10693

10794
DispatchQueue.global( qos: .userInitiated ).async
10895
{
109-
self.download( url: self.swiftFormat )
110-
self.download( url: self.uncrustify )
96+
if let url = self.swiftFormat
97+
{
98+
self.download( url: url )
99+
}
100+
101+
if let url = self.uncrustify
102+
{
103+
self.download( url: url )
104+
}
111105

112106
DispatchQueue.main.async
113107
{
@@ -138,30 +132,46 @@ public class Configuration: NSObject, Codable
138132
}
139133
}
140134

141-
public func withConfigurations( completion: ( ( swiftFormat: URL, uncrustify: URL, finished: () -> Void ) ) -> Void, error: () -> Void )
135+
public func withConfigurations( completion: ( ( swiftFormat: URL?, uncrustify: URL?, finished: () -> Void ) ) -> Void, error: () -> Void )
142136
{
143-
guard let swiftFormat = self.copy( url: self.swiftFormat ),
144-
let uncrustify = self.copy( url: self.uncrustify )
145-
else
137+
let swiftFormat = self.copy( url: self.swiftFormat )
138+
let uncrustify = self.copy( url: self.uncrustify )
139+
140+
if ( self.swiftFormat != nil && swiftFormat == nil ) || ( self.uncrustify != nil && uncrustify == nil )
146141
{
147-
error()
148142
self.download()
143+
}
144+
145+
if swiftFormat == nil, uncrustify == nil
146+
{
147+
error()
149148

150149
return
151150
}
152151

153152
let finished: () -> Void =
154153
{
155-
try? FileManager.default.removeItem( at: swiftFormat )
156-
try? FileManager.default.removeItem( at: uncrustify )
154+
[
155+
swiftFormat,
156+
uncrustify,
157+
]
158+
.compactMap
159+
{
160+
$0
161+
}
162+
.forEach
163+
{
164+
try? FileManager.default.removeItem( at: $0 )
165+
}
157166
}
158167

159168
completion( ( swiftFormat: swiftFormat, uncrustify: uncrustify, finished: finished ) )
160169
}
161170

162-
private func copy( url: URL ) -> URL?
171+
private func copy( url: URL? ) -> URL?
163172
{
164-
guard let sha256 = url.sha256,
173+
guard let url = url,
174+
let sha256 = url.sha256,
165175
let container = FileManager.sharedContainerURL?.appendingPathComponent( "Configurations" )
166176
else
167177
{

XcodeFormat/Classes/ConfigurationWindowController.swift

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,20 @@ import Cocoa
2626

2727
public class ConfigurationWindowController: NSWindowController
2828
{
29-
@objc public dynamic var name = ""
30-
@objc public dynamic var swiftFormat = ""
31-
@objc public dynamic var uncrustify = ""
32-
@objc public dynamic var configuration: Configuration?
29+
@objc public dynamic var name = "" { didSet { self.resetErrors() } }
30+
@objc public dynamic var swiftFormat = "" { didSet { self.resetErrors() } }
31+
@objc public dynamic var uncrustify = "" { didSet { self.resetErrors() } }
32+
@objc public dynamic var nameError: String?
33+
@objc public dynamic var swiftFormatError: String?
34+
@objc public dynamic var uncrustifyError: String?
35+
@objc public dynamic var otherError: String?
36+
@objc public dynamic var configuration: Configuration?
3337
{
3438
didSet
3539
{
36-
self.name = self.configuration?.name ?? ""
37-
self.swiftFormat = self.configuration?.swiftFormat.absoluteString ?? ""
38-
self.uncrustify = self.configuration?.uncrustify.absoluteString ?? ""
40+
self.name = self.configuration?.name ?? ""
41+
self.swiftFormat = self.configuration?.swiftFormat?.absoluteString ?? ""
42+
self.uncrustify = self.configuration?.uncrustify?.absoluteString ?? ""
3943
}
4044
}
4145

@@ -87,31 +91,33 @@ public class ConfigurationWindowController: NSWindowController
8791
return
8892
}
8993

90-
guard self.name.isEmpty == false,
91-
self.swiftFormat.isEmpty == false,
92-
self.uncrustify.isEmpty == false
93-
else
94+
if self.name.isEmpty
9495
{
95-
let alert = NSAlert()
96-
alert.messageText = "Invalid Values"
97-
alert.informativeText = "Please enter a valid value for all fields."
96+
self.nameError = "Please enter a name"
9897

99-
alert.addButton( withTitle: "OK" )
100-
alert.runModal()
98+
return
99+
}
100+
101+
if self.swiftFormat.isEmpty, self.uncrustify.isEmpty
102+
{
103+
self.otherError = "Please enter at least one configuration URL"
101104

102105
return
103106
}
104107

105-
guard let swiftFormat = URL( string: self.swiftFormat ),
106-
let uncrustify = URL( string: self.uncrustify )
107-
else
108+
let swiftFormat = URL( string: self.swiftFormat )
109+
let uncrustify = URL( string: self.uncrustify )
110+
111+
if self.swiftFormat.isEmpty == false, swiftFormat == nil
108112
{
109-
let alert = NSAlert()
110-
alert.messageText = "Invalid URLs"
111-
alert.informativeText = "Please enter valid URLs."
113+
self.swiftFormatError = "Please enter a valid URL"
112114

113-
alert.addButton( withTitle: "OK" )
114-
alert.runModal()
115+
return
116+
}
117+
118+
if self.uncrustify.isEmpty == false, uncrustify == nil
119+
{
120+
self.uncrustifyError = "Please enter a valid URL"
115121

116122
return
117123
}
@@ -130,4 +136,12 @@ public class ConfigurationWindowController: NSWindowController
130136
sheet.orderOut( nil )
131137
window.endSheet( sheet, returnCode: .OK )
132138
}
139+
140+
private func resetErrors()
141+
{
142+
self.nameError = nil
143+
self.swiftFormatError = nil
144+
self.uncrustifyError = nil
145+
self.otherError = nil
146+
}
133147
}

0 commit comments

Comments
 (0)