@@ -11,6 +11,32 @@ struct DevNewCommand: AsyncParsableCommand {
1111
1212 func run( ) async throws {
1313 let name = try await Console . promptRequired ( " Package name: " , existing: self . name)
14+
15+ // TODO: support '-' in package name, replace with _ or CamelCase in Swift identifiers.
16+ var allowedFirstCharacters : CharacterSet = [ " _ " ]
17+ allowedFirstCharacters. insert ( charactersIn: " a " ... " z " )
18+ allowedFirstCharacters. insert ( charactersIn: " A " ... " Z " )
19+
20+ var allowedOtherCharacters = allowedFirstCharacters
21+ allowedOtherCharacters. insert ( charactersIn: " 0 " ... " 9 " )
22+
23+ // promptRequired validates !isEmpty
24+ let firstScalar = name. unicodeScalars. first!
25+ guard allowedFirstCharacters. contains ( firstScalar) else {
26+ throw Console . Error ( """
27+ Package name ' \( name) ' is invalid. \
28+ The package name must start with [a-z, A-Z, or _]. Found ' \( firstScalar) '.
29+ """ )
30+ }
31+
32+ if let firstInvalid = name. rangeOfCharacter ( from: allowedOtherCharacters. inverted) {
33+ let invalidValue = name [ firstInvalid]
34+ throw Console . Error ( """
35+ Package name ' \( name) ' is invalid. \
36+ The package name may only contain [a-z, A-Z, 0-9, and _]. Found ' \( invalidValue) '.
37+ """ )
38+ }
39+
1440 let baseURL = URL ( fileURLWithPath: name)
1541
1642 guard !baseURL. exists else {
0 commit comments