localizationCommand/Sources/commandService/commandTool.swift

226 lines
7.4 KiB
Swift

//
// commandProtocol.swift
// localizationCommand
//
// Created by BackNotGod on 2017/3/14.
//
//
import Foundation
import PathKit
import Progress
protocol StringsSearcher {
func search(in content: String)
}
protocol RegexStringsSearcher: StringsSearcher {
var patterns: [String] { get }
}
extension RegexStringsSearcher {
func search(in path: Path) {
for pattern in patterns {
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
print("Failed to create regular expression: \(pattern)".red)
continue
}
let content = parsePathToContent(with: path)
let matches = regex.matches(in: content, options: [], range: content.fullRange)
var extracts : [Values] = []
var errors : [Values] = []
for checkingResult in matches {
let range = checkingResult.rangeAt(0)
let extracted = NSString(string: content).substring(with: range)
guard let strRegex = try? NSRegularExpression(pattern: LOCAL_ERGEX, options: []) else {
print("Failed to create regular expression: \(pattern)".red)
continue
}
let strMatches = strRegex.matches(in: extracted, options: [], range: extracted.fullRange)
let localizedString = NSString(string: extracted).substring(with: strMatches[0].rangeAt(0))
if localizedString.characters.count == 0 {
continue
}
var commont = ""
if strMatches.count > 1 {
commont = NSString(string: extracted).substring(with: strMatches[1].rangeAt(0))
}
let value = Values.init(value: localizedString, comment: "\(commont)")
value.appendClassComent(className: path.lastComponentWithoutExtension, comStr: commont)
guard duplicateRemoval(path: path, value: value,className:path.lastComponentWithoutExtension) else {continue}
let judge = !extracts.contains{isSameValues($0, value2: value)}
guard judge else {continue}
/// over here, if localizedString is isAmbiguous,we analysis error
if localizedString.isAmbiguous {
errors.append(value)
}else{
extracts.append(value)
}
}
if extracts.count > 0 {
if path.lastComponent.contains("swift") {
DataHandleManager.defaltManager.swift_listNode?.insert(values: extracts, className: path.lastComponent, path: path.description)
}else{
DataHandleManager.defaltManager.oc_listNode?.insert(values: extracts, className: path.lastComponent, path: path.description)
}
}
if errors.count > 0 {
DataHandleManager.defaltManager.error_listNode?.insert(values: errors, className: path.lastComponent, path: path.description)
}
}
}
}
/**
Duplicate removal
- parameter value
- returns: if there is no same value return true
*/
func duplicateRemoval(path:Path,value:Values,className:String) -> Bool{
if path.lastComponent.contains("swift") {
return searchSame(link: DataHandleManager.defaltManager.swift_listNode!.head, value: value,className: className)
}
return searchSame(link: DataHandleManager.defaltManager.oc_listNode!.head, value: value,className:className)
}
// if there is no same value return true
func searchSame(link:linkNode?,value:Values,className:String) -> Bool{
guard let _link = link else {return true}
let judge = _link.values.contains{isSameValues($0, value2:value)}
if judge {
_link.values.forEach({ (v) in
if isSameValues(v, value2: value){
v.appendClassComent(className: className, comStr: v.comment)
}
})
return false
}
return searchSame(link: _link.next, value: value,className: className)
}
protocol RegexStringsWriter : StringsSearcher{
func writeToLocalizable (to path:Path)
}
extension RegexStringsWriter {
func writeToLocalizable (to path:Path) {
var content = !writeAppend ? "" : {
return try? path.read(.utf16)
}() ?? ""
let contentArr = contentRegex(content: content)
content += "//-------------------swfit-------------------"
let swift = DataHandleManager.defaltManager.swift_listNode?.head
DataHandleManager.defaltManager.outPutLinkNode(root: swift, action: { valuesOptial in
if let values = valuesOptial {
for value in values {
if !contentArr.contains(value.localizedString){
content += "\n\(value.outPutStr)\n\(value.localizedString) = \(value.localizedString);\n"
}
}
}
})
content += "\n//\(NSDate())\n"
content += "//-------------------objc-------------------"
let objc = DataHandleManager.defaltManager.oc_listNode?.head
DataHandleManager.defaltManager.outPutLinkNode(root: objc, action: { valuesOptial in
if let values = valuesOptial {
for value in values {
if !contentArr.contains(value.localizedString){
content += "\n\(value.outPutStr)\n\(value.localizedString) = \(value.localizedString);\n"
}
}
}
})
content += "\n//\(NSDate())\n"
try? path.write(content, encoding: .utf16)
}
}
func contentRegex(content:String)->[String]{
guard let regex = try? NSRegularExpression(pattern: "\".+?\"", options: []) else {
print("Failed to create regular expression.".red)
return []
}
let matches = regex.matches(in: content, options: [], range: content.fullRange)
return matches.map{NSString(string: content).substring(with: $0.rangeAt(0))}
}
func findAllLocalizable(with path:Path,excluded:[Path]) -> [Path]{
if !path.exists {
print("path is not exists!".yellow)
return []
}
if !path.isWritable {
print("path is not writable!".yellow)
return []
}
let optonalPaths = try? path.recursiveChildren()
guard let paths = optonalPaths else {return []}
var results : [Path] = []
for itemPath in Progress(pathsFilter(paths: paths, except: excluded)){
let strings = itemPath.glob("*.strings")
if strings.count > 0 {
results = results + strings
}
}
return results
}
func pathsFilter(paths:[Path],except:[Path])->[Path]{
if paths.count == 0 {
print("error: the vailable path is covered by your except path.".red)
exit(EX_USAGE)
}
if except.count == 0 {
return paths
}
var excepts = except
excepts.removeLast()
return pathsFilter(paths: paths.filter{!$0.description.contains(except.last!.description)}, except: excepts)
}
func parsePathToContent(with path:Path)->String{
return (try? path.read()) ?? "read error , this path may be empty."
}