diff --git a/.gitignore b/.gitignore index c5c9737..996a13e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,67 @@ -/** MacOS **/ + +# Created by https://www.toptal.com/developers/gitignore/api/swiftpm,xcode,macos,cocoapods +# Edit at https://www.toptal.com/developers/gitignore?templates=swiftpm,xcode,macos,cocoapods + +### CocoaPods ### +## CocoaPods GitIgnore Template + +# CocoaPods - Only use to conserve bandwidth / Save time on Pushing +# - Also handy if you have a large number of dependant pods +# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE +Pods/ + +### macOS ### +# General .DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent -/** NPM **/ -*/node_modules -*npm* +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### SwiftPM ### +Packages +.build/ +xcuserdata +DerivedData/ +*.xcodeproj + + +### Xcode ### # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore -## Build generated -build/ -DerivedData/ +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout -## Various settings +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +*.moved-aside *.pbxuser !default.pbxuser *.mode1v3 @@ -22,46 +70,16 @@ DerivedData/ !default.mode2v3 *.perspectivev3 !default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xcuserstate - -## Obj-C/Swift specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts +## Gcc Patch +/*.gcno -Carthage/Build +### Xcode Patch ### +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcworkspace/contents.xcworkspacedata +**/xcshareddata/WorkspaceSettings.xcsettings -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md - -fastlane/report.xml -fastlane/screenshots - -#Code Injection -# -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode +# End of https://www.toptal.com/developers/gitignore/api/swiftpm,xcode,macos,cocoapods -iOSInjectionProject/ \ No newline at end of file diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/EDSemver/EDSemver.h b/EDSemver/EDSemver.h index 9c73e19..c0db7f2 100644 --- a/EDSemver/EDSemver.h +++ b/EDSemver/EDSemver.h @@ -8,36 +8,42 @@ #import +#ifndef EDSEMVER_EDSEMVER_H +#define EDSEMVER_EDSEMVER_H + +/** + `EDSemver` is a helper library for Objective-C based on the 2.0.0 spec of [Semantic Versioning](https://semver.org/). + */ @interface EDSemver : NSObject -/*! +/** * The major version number (API changes) */ @property (readonly) NSInteger major; -/*! +/** * The minor version (functionality added in a backwards compatible manor) */ @property (readonly) NSInteger minor; -/*! +/** * The patch version (bug fixes made in a backwards compatible manor) */ @property (readonly) NSInteger patch; -/*! +/** * The prerelease number, preceded with -, e.g. 1.2.3-alpha1 */ @property (readonly, nullable) NSString *prerelease; -/*! +/** * The build number, preceded with +, e.g. 1.2.3+456 */ @property (readonly, nullable) NSString *build; -/*! +/** * The current semver spec version * * @return The spec version as a string */ + (nonnull NSString *)spec; -/*! +/** * Create a semver object with a version string * * @param aString The version string @@ -46,7 +52,7 @@ */ + (nonnull instancetype)semverWithString:(nonnull NSString *)aString; -/*! +/** * Create a semver object with a version string * * @param aString The version string @@ -55,7 +61,7 @@ */ - (nonnull instancetype)initWithString:(nonnull NSString *)aString; -/*! +/** * Compare semver objects * * @param aVersion The version string @@ -63,7 +69,7 @@ * @return The semver object */ - (NSComparisonResult)compare:(nonnull EDSemver *)aVersion; -/*! +/** * Is version equal to another version * Implemented using `compare:`. Returns NO parameter is nil * @@ -72,7 +78,7 @@ * @return YES if equal, NO otherwise */ - (BOOL)isEqualTo:(nullable id)object; -/*! +/** * Is version less than another version. * Implemented using `compare:`. Returns NO parameter is nil * @@ -81,7 +87,7 @@ * @return YES if less than, NO otherwise */ - (BOOL)isLessThan:(nullable id)object; -/*! +/** * Is version greater than than another version. * Implemented using `compare:`. Returns NO parameter is nil * @@ -91,7 +97,7 @@ */ - (BOOL)isGreaterThan:(nullable id)object; -/*! +/** * Is the semver object valid? * * @return YES if valid, NO otherwise @@ -99,3 +105,5 @@ - (BOOL)isValid; @end + +#endif diff --git a/EDSemver/EDSemver.m b/EDSemver/EDSemver.m index 88b31ed..4c34b6c 100644 --- a/EDSemver/EDSemver.m +++ b/EDSemver/EDSemver.m @@ -101,12 +101,45 @@ - (NSComparisonResult)compare:(EDSemver *)aVersion if (self.prerelease.length > 0 || aVersion.prerelease.length > 0) { if (self.prerelease.length > 0 && aVersion.prerelease.length == 0) return NSOrderedAscending; if (self.prerelease.length == 0 && aVersion.prerelease.length > 0) return NSOrderedDescending; - return [self.prerelease compare:(NSString * _Nonnull)aVersion.prerelease]; + return [self comparePrerelease:aVersion.prerelease]; } return NSOrderedSame; } +- (NSComparisonResult)comparePrerelease:(NSString *)aPrerelease +{ + NSArray *aPr = [self parse:aPrerelease strict:NO]; + NSUInteger minCount = self.pr.count < aPr.count ? self.pr.count : aPr.count; + NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; + NSString *part, *aPart; + NSNumber *numPart, *aNumPart; + NSComparisonResult result; + for (NSUInteger i = 0; i < minCount; i++) { + part = self.pr[i]; + aPart = aPr[i]; + numPart = [nf numberFromString:part]; + aNumPart = [nf numberFromString:aPart]; + + if (numPart && aNumPart) { + result = [numPart compare:aNumPart]; + if (result != NSOrderedSame) { + return result; + } + } else if (!numPart && aNumPart) { + return NSOrderedDescending; + } else if (numPart && !aNumPart) { + return NSOrderedAscending; + } else { + result = [part compare:aPart]; + if (result != NSOrderedSame) { + return result; + } + } + } + + return [@(self.pr.count) compare:@(aPr.count)]; +} - (BOOL)isEqualTo:(id)aVersion { @@ -126,6 +159,10 @@ - (BOOL)isGreaterThan:(id)aVersion return [self compare:(EDSemver * _Nonnull)aVersion] == NSOrderedDescending; } +- (BOOL)isEqual:(id)object { + return [self isEqualTo:object]; +} + - (NSString *)description { return self.original; diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..3551846 --- /dev/null +++ b/Package.swift @@ -0,0 +1,31 @@ +// swift-tools-version:5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "Semver", + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "Semver", + targets: ["Semver"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "Semver", + dependencies: [], + path: "EDSemver", + publicHeadersPath: ".", + cSettings: [ + .headerSearchPath("."), + ] + ) + ] +) diff --git a/Project/semver.xcodeproj/project.pbxproj b/Project/semver.xcodeproj/project.pbxproj index 5aae8b0..1fd3eca 100644 --- a/Project/semver.xcodeproj/project.pbxproj +++ b/Project/semver.xcodeproj/project.pbxproj @@ -381,7 +381,7 @@ attributes = { CLASSPREFIX = ED; LastTestingUpgradeCheck = 0730; - LastUpgradeCheck = 0820; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = "Andrew Sliwinski"; TargetAttributes = { 01DA90111D0ADA5F00D65599 = { @@ -402,7 +402,7 @@ }; buildConfigurationList = C390380B178615E400ECBCAC /* Build configuration list for PBXProject "semver" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -802,11 +802,17 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -843,11 +849,17 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/Project/semver.xcodeproj/xcshareddata/xcschemes/semver-ios.xcscheme b/Project/semver.xcodeproj/xcshareddata/xcschemes/semver-ios.xcscheme index 16b41c7..67c46ba 100644 --- a/Project/semver.xcodeproj/xcshareddata/xcschemes/semver-ios.xcscheme +++ b/Project/semver.xcodeproj/xcshareddata/xcschemes/semver-ios.xcscheme @@ -1,6 +1,6 @@