From 703a3b29115799010f7f1958a47c6e545581df42 Mon Sep 17 00:00:00 2001 From: mflknr Date: Tue, 30 Mar 2021 21:46:10 +0200 Subject: [PATCH 1/2] fix: project --- .../project.xcworkspace/contents.xcworkspacedata | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + From eeb99b55d1ea4700215e18783c5a272ba290cc9a Mon Sep 17 00:00:00 2001 From: mflknr Date: Tue, 30 Mar 2021 21:47:32 +0200 Subject: [PATCH 2/2] Squashed commit of the following: commit d848a533f11350ec4fb80a9b2b11e6121fd37117 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Tue Mar 30 21:43:57 2021 +0200 Update example-project and tests (#8) * feat: update example * fix: correct comparison when checking version core * feat: add string literal conformance to extensions * feat: make init more safe * test: add more test cases * docs: update jazzy * fix: readme * test: add more valid test cases for literal construction * refactor: update alphanumeric regex pattern * fix: exlusion of multiple - symbols in prerelease identifiers * fix: ignoring leading zeros in version identifiers commit 99b270e10b22fe8bb41354d1c8ec75050da6cff6 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Sun Mar 28 22:36:15 2021 +0200 Handle pre-release and build-meta-data for construction and comparison (#7) * feat: add identifier enums * feat: add equatable to prerelease identifier * feat: add hashable to semanticversioncomparable * feat: add buildidentifier * feat: add prerelease identifier * feat: add build as comparison result * refactor: use new build and prerelease identifier * feat: add regex matches for numeric and alphanumeric strings * feat: add prerelease to equatable * feat: update comparison result with build * feat: update comparable protocol with new identifier * feat: add prerelease and build to comparison result * docs: update jazzy file * refactor: documentation style and new accessor * refactor: remove dead code * docs: update docs and accesor level * feat: cleanup * refactor: rename after semver * refactor: further renaming * refactor: rename missing group * refactor: add missing warning * refactor: naming and docs * docs: jazzy * feat: update readme * fix: equality comparison * fix: compare result * docs: update readme and jazzy * fix: merge * fix: missing parts in readme * refactor: add on tag trigger for main release * refactor: rm dead file * Update build.yml * Update build.yml * Update build.yml * Update build.yml * Update main-release.yml * Update build.yml * Update build.yml * refactor: rm gen proj from ci * feat: set test conf to release * Update build.yml * fix: tests commit 3f4dbc692eb357c44e7830c36f1bbfd71600742a Author: mflknr Date: Sun Mar 28 15:52:18 2021 +0200 fix: build yml commit f37bd8e541b3bc823983f8856df2e4b223d06498 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Sun Mar 28 15:51:10 2021 +0200 Update build.yml commit 0e84ca756ca522460365335866d573be882709bb Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Sun Mar 28 15:48:56 2021 +0200 Delete pr-check.yml commit cc82b2bdf8ae36cfb8e51d773289975bc8b5c0d1 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Sun Mar 28 15:48:46 2021 +0200 Update build.yml commit 6882a0567b4b362fba631ece0a858873097828a6 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Sun Mar 28 15:41:45 2021 +0200 Update build.yml commit 99f35d0c25289ac7af505c56960eea545efb04a7 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Mon Jan 18 23:42:09 2021 +0100 Update pr-check.yml commit 2deab7110eae9382f6c3d240174afde3fed08b6e Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Mon Jan 18 22:57:11 2021 +0100 Update pr-check.yml commit 9e3c99744504adfe65c2174a0df9af478ef95595 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Mon Jan 18 00:04:10 2021 +0100 Hashable Conformance (#6) * feat: add hashable protocol conformance * chore: update readme * feat: add version from bundle with bundleversion and shortversion * tests: add fix build number to bundles * fix: readme commit a5a20318efcc01c13512b8e28e084ee0ee41b1fb Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Tue Jan 12 00:20:23 2021 +0100 Add Example (#5) * feat: add example project * feat: add basic example view commit f2eebfff4b2a3c8dee72c6837d10ae2382162315 Merge: 435ae7c e376c5d Author: nihilias Date: Tue Jan 12 00:14:49 2021 +0100 Merge branch 'main' into develop commit 435ae7cab5fe29e8976ece430f88cf9a7d560745 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Mon Jan 11 14:46:03 2021 +0100 Update README.md commit 482d21326c9d83e1526fe21e33d5e684f54ba885 Author: Marius <11645567+mflknr@users.noreply.github.com> Date: Sun Jan 10 21:07:18 2021 +0100 Update README.md commit 9ed04134174ff5f30e32f099df2ecc81c107eedc Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Sat Jan 9 14:09:27 2021 +0100 Update README.md commit ec37b436d08096790d1ef01eb18ea447051adf27 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Sat Jan 9 13:59:30 2021 +0100 Update README.md commit 7f8736318c606b275b2330e89043c51a851b9cca Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Sat Jan 9 13:58:23 2021 +0100 Update README.md commit 0b724e424672921a2bcb2ff7d02f44fe02990bf8 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Sat Jan 9 13:51:05 2021 +0100 Update README.md commit dc592c3b4c3fa9551cb71f442b11cbbd8b896e67 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Sat Jan 9 13:41:46 2021 +0100 Update README.md commit c6062f885b9b8d45f3631542d7d8eeec8a653ed2 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Sat Jan 9 13:40:28 2021 +0100 Update and rename build-check.yml to build.yml commit fc035e4bb821d840cce81b80b6b78fc2663f1d09 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:43:56 2021 +0100 Update main-release.yml commit 630d5e72b28e643c651600057d7365351f34dc78 Author: nihilias Date: Thu Jan 7 22:43:15 2021 +0100 chore: fix workflow commit 1bfe344c55296d339fce14cf175ee6215c1d52fe Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:42:19 2021 +0100 Create main-release.yml commit 01dbd9ede7d1814cceb7ff7a52d2e3dd1a48ed3f Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:36:49 2021 +0100 Update pr-check.yml commit ac6206aa550d334a1ea46cf8d6ee692fee3826ef Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:36:29 2021 +0100 Update build-check.yml commit 14c4f32f9779ddc96da68c8ea22472c9870fc561 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:35:59 2021 +0100 Update and rename build_check.yml to build-check.yml commit 1500ababc1185f7503af87388fc669117634050e Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:35:36 2021 +0100 Create build_check.yml commit b9f641c9945badbae3d03612e5ada6da89e96205 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:29:19 2021 +0100 Update README.md commit 218334b21abd98b057e4409505c664069b00d8b4 Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 22:06:17 2021 +0100 Update pr-check.yml commit e6e1710166806261a23d9453eed94ed68de9fa8f Author: Marius <11645567+nihilias@users.noreply.github.com> Date: Thu Jan 7 21:49:56 2021 +0100 Create pr-check.yml --- .github/workflows/build.yml | 30 ++ .github/workflows/main-release.yml | 22 + .jazzy.yml | 8 +- .../project.pbxproj | 358 +++++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/swiftpm/Package.resolved | 16 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 ++++ .../Assets.xcassets/Contents.json | 6 + .../ContentView.swift | 111 ++++ .../SemanticVersionCompareExample/Info.plist | 50 ++ .../Preview Assets.xcassets/Contents.json | 6 + .../SemanticVersionCompareExampleApp.swift | 17 + README.md | 49 +- .../Helper/Character+Extensions.swift | 16 + .../Helper/String+Regex.swift | 20 +- ...erity.swift => VersionCompareResult.swift} | 9 +- .../BuildMetaData+ExpressibleByLiteral.swift | 20 + .../BuildMetaData/BuildMetaData.swift | 45 ++ .../PrereleaseIdentifier+Equatable.swift | 15 + ...leaseIdentifier+ExpressibleByLiteral.swift | 28 ++ .../PrereleaseIdentifier.swift | 67 +++ ...SemanticVersionComparable+Comparable.swift | 104 ++-- .../SemanticVersionComparable+Equatable.swift | 38 +- .../SemanticVersionComparable+Hashable.swift | 15 + .../SemanticVersionComparable.swift | 187 ++++--- .../SwiftVersionCompare/Version+Bundle.swift | 23 +- .../Version+StringInitializer.swift | 28 +- Sources/SwiftVersionCompare/Version.swift | 278 ++++++---- .../SwiftVersionCompareTests_Info.plist | 41 +- .../SwiftVersionCompare_Info.plist | 2 +- SwiftVersionCompare.xcodeproj/project.pbxproj | 52 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 +- .../SwiftVersionCompare-Package.xcscheme | 3 +- .../SemanticVersionComparableTests.swift | 104 +++- .../VersionTests.swift | 113 ++++- docs/Enums.html | 108 +++- docs/Enums/BuildMetaData.html | 307 ++++++++++++ docs/Enums/PrereleaseIdentifier.html | 474 ++++++++++++++++++ docs/Enums/VersionCompareResult.html | 51 +- docs/Extensions.html | 12 +- docs/Extensions/Bundle.html | 44 +- docs/Extensions/ProcessInfo.html | 12 +- docs/Protocols.html | 35 +- docs/Protocols/SemanticVersionComparable.html | 344 +++++++++++-- docs/Structs.html | 40 +- docs/Structs/Version.html | 258 ++++++---- docs/badge.svg | 16 +- .../Contents/Resources/Documents/Enums.html | 108 +++- .../Documents/Enums/BuildMetaData.html | 307 ++++++++++++ .../Documents/Enums/PrereleaseIdentifier.html | 474 ++++++++++++++++++ .../Documents/Enums/VersionCompareResult.html | 51 +- .../Resources/Documents/Extensions.html | 12 +- .../Documents/Extensions/Bundle.html | 44 +- .../Documents/Extensions/ProcessInfo.html | 12 +- .../Resources/Documents/Protocols.html | 35 +- .../Protocols/SemanticVersionComparable.html | 344 +++++++++++-- .../Contents/Resources/Documents/Structs.html | 40 +- .../Resources/Documents/Structs/Version.html | 258 ++++++---- .../Contents/Resources/Documents/badge.svg | 16 +- .../Contents/Resources/Documents/index.html | 61 +-- .../Contents/Resources/Documents/search.json | 2 +- .../Resources/Documents/undocumented.json | 15 +- .../.docset/Contents/Resources/docSet.dsidx | Bin 28672 -> 28672 bytes docs/docsets/.tgz | Bin 76970 -> 82746 bytes docs/index.html | 61 +-- docs/search.json | 2 +- docs/undocumented.json | 15 +- 68 files changed, 4677 insertions(+), 887 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/main-release.yml create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.pbxproj create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/Contents.json create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/ContentView.swift create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Info.plist create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 Example/SemanticVersionCompareExample/SemanticVersionCompareExample/SemanticVersionCompareExampleApp.swift create mode 100644 Sources/SwiftVersionCompare/Helper/Character+Extensions.swift rename Sources/SwiftVersionCompare/Helper/{UpdateSeverity.swift => VersionCompareResult.swift} (59%) create mode 100644 Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData+ExpressibleByLiteral.swift create mode 100644 Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData.swift create mode 100644 Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+Equatable.swift create mode 100644 Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+ExpressibleByLiteral.swift create mode 100644 Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier.swift create mode 100644 Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Hashable.swift create mode 100644 docs/Enums/BuildMetaData.html create mode 100644 docs/Enums/PrereleaseIdentifier.html create mode 100644 docs/docsets/.docset/Contents/Resources/Documents/Enums/BuildMetaData.html create mode 100644 docs/docsets/.docset/Contents/Resources/Documents/Enums/PrereleaseIdentifier.html diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8e28067 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: build + +on: + push: + branches: + - develop + pull_request: + branches: + - develop + +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - run: swift --version + - run: swift build -v + test: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - run: swift --version + - name: Test + uses: sersoft-gmbh/xcodebuild-action@v1.4 + with: + project: SwiftVersionCompare.xcodeproj + scheme: SwiftVersionCompare-Package + action: test + - name: Codecov + uses: codecov/codecov-action@v1 diff --git a/.github/workflows/main-release.yml b/.github/workflows/main-release.yml new file mode 100644 index 0000000..6976649 --- /dev/null +++ b/.github/workflows/main-release.yml @@ -0,0 +1,22 @@ +name: main-release + +on: + push: + branches: + - main + tags: + - 1.* + +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/create@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + draft: true + prerelease: false diff --git a/.jazzy.yml b/.jazzy.yml index df7e429..2e8b75b 100644 --- a/.jazzy.yml +++ b/.jazzy.yml @@ -1,13 +1,13 @@ module: SwiftVersionCompare -author: nihilias -author_url: https://www.nihilias.de/ -github_url: https://github.com/nihilias/SwiftVersionCompare/ +author: mflknr +author_url: https://www.mflknr.de/ +github_url: https://github.com/mflknr/SwiftVersionCompare/ readme: README.md skip_undocumented: true hide_documentation_coverage: false theme: apple output: docs/ -swift_version: 5.3.1 +swift_version: 5.3.2 clean: true min_acl: public xcodebuild_arguments: diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.pbxproj b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0c8128f --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.pbxproj @@ -0,0 +1,358 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + 24A6A2ED25A7A00300E12D71 /* SemanticVersionCompareExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A2EC25A7A00300E12D71 /* SemanticVersionCompareExampleApp.swift */; }; + 24A6A2EF25A7A00300E12D71 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A2EE25A7A00300E12D71 /* ContentView.swift */; }; + 24A6A2F125A7A00800E12D71 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24A6A2F025A7A00800E12D71 /* Assets.xcassets */; }; + 24A6A2F425A7A00800E12D71 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24A6A2F325A7A00800E12D71 /* Preview Assets.xcassets */; }; + 24A6A2FE25A7A0BE00E12D71 /* SwiftVersionCompare in Frameworks */ = {isa = PBXBuildFile; productRef = 24A6A2FD25A7A0BE00E12D71 /* SwiftVersionCompare */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 24A6A2E925A7A00300E12D71 /* SemanticVersionCompareExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SemanticVersionCompareExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 24A6A2EC25A7A00300E12D71 /* SemanticVersionCompareExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SemanticVersionCompareExampleApp.swift; sourceTree = ""; }; + 24A6A2EE25A7A00300E12D71 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 24A6A2F025A7A00800E12D71 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 24A6A2F325A7A00800E12D71 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 24A6A2F525A7A00800E12D71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 24A6A2E625A7A00300E12D71 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 24A6A2FE25A7A0BE00E12D71 /* SwiftVersionCompare in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 24A6A2E025A7A00300E12D71 = { + isa = PBXGroup; + children = ( + 24A6A2EB25A7A00300E12D71 /* SemanticVersionCompareExample */, + 24A6A2EA25A7A00300E12D71 /* Products */, + ); + sourceTree = ""; + }; + 24A6A2EA25A7A00300E12D71 /* Products */ = { + isa = PBXGroup; + children = ( + 24A6A2E925A7A00300E12D71 /* SemanticVersionCompareExample.app */, + ); + name = Products; + sourceTree = ""; + }; + 24A6A2EB25A7A00300E12D71 /* SemanticVersionCompareExample */ = { + isa = PBXGroup; + children = ( + 24A6A2EC25A7A00300E12D71 /* SemanticVersionCompareExampleApp.swift */, + 24A6A2EE25A7A00300E12D71 /* ContentView.swift */, + 24A6A2F025A7A00800E12D71 /* Assets.xcassets */, + 24A6A2F525A7A00800E12D71 /* Info.plist */, + 24A6A2F225A7A00800E12D71 /* Preview Content */, + ); + path = SemanticVersionCompareExample; + sourceTree = ""; + }; + 24A6A2F225A7A00800E12D71 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 24A6A2F325A7A00800E12D71 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 24A6A2E825A7A00300E12D71 /* SemanticVersionCompareExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 24A6A2F825A7A00800E12D71 /* Build configuration list for PBXNativeTarget "SemanticVersionCompareExample" */; + buildPhases = ( + 24A6A2E525A7A00300E12D71 /* Sources */, + 24A6A2E625A7A00300E12D71 /* Frameworks */, + 24A6A2E725A7A00300E12D71 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SemanticVersionCompareExample; + packageProductDependencies = ( + 24A6A2FD25A7A0BE00E12D71 /* SwiftVersionCompare */, + ); + productName = SemanticVersionCompareExample; + productReference = 24A6A2E925A7A00300E12D71 /* SemanticVersionCompareExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 24A6A2E125A7A00300E12D71 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1230; + LastUpgradeCheck = 1230; + TargetAttributes = { + 24A6A2E825A7A00300E12D71 = { + CreatedOnToolsVersion = 12.3; + }; + }; + }; + buildConfigurationList = 24A6A2E425A7A00300E12D71 /* Build configuration list for PBXProject "SemanticVersionCompareExample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 24A6A2E025A7A00300E12D71; + packageReferences = ( + 24A6A2FC25A7A0BE00E12D71 /* XCRemoteSwiftPackageReference "SwiftVersionCompare" */, + ); + productRefGroup = 24A6A2EA25A7A00300E12D71 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 24A6A2E825A7A00300E12D71 /* SemanticVersionCompareExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 24A6A2E725A7A00300E12D71 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24A6A2F425A7A00800E12D71 /* Preview Assets.xcassets in Resources */, + 24A6A2F125A7A00800E12D71 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 24A6A2E525A7A00300E12D71 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24A6A2EF25A7A00300E12D71 /* ContentView.swift in Sources */, + 24A6A2ED25A7A00300E12D71 /* SemanticVersionCompareExampleApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 24A6A2F625A7A00800E12D71 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.3; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 24A6A2F725A7A00800E12D71 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.3; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 24A6A2F925A7A00800E12D71 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"SemanticVersionCompareExample/Preview Content\""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SemanticVersionCompareExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = de.nihilias.SemanticVersionCompareExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 24A6A2FA25A7A00800E12D71 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"SemanticVersionCompareExample/Preview Content\""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SemanticVersionCompareExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = de.nihilias.SemanticVersionCompareExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 24A6A2E425A7A00300E12D71 /* Build configuration list for PBXProject "SemanticVersionCompareExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24A6A2F625A7A00800E12D71 /* Debug */, + 24A6A2F725A7A00800E12D71 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 24A6A2F825A7A00800E12D71 /* Build configuration list for PBXNativeTarget "SemanticVersionCompareExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24A6A2F925A7A00800E12D71 /* Debug */, + 24A6A2FA25A7A00800E12D71 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 24A6A2FC25A7A0BE00E12D71 /* XCRemoteSwiftPackageReference "SwiftVersionCompare" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/nihilias/SwiftVersionCompare.git"; + requirement = { + branch = develop; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 24A6A2FD25A7A0BE00E12D71 /* SwiftVersionCompare */ = { + isa = XCSwiftPackageProductDependency; + package = 24A6A2FC25A7A0BE00E12D71 /* XCRemoteSwiftPackageReference "SwiftVersionCompare" */; + productName = SwiftVersionCompare; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 24A6A2E125A7A00300E12D71 /* Project object */; +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..acc5f78 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "SwiftVersionCompare", + "repositoryURL": "https://github.com/nihilias/SwiftVersionCompare.git", + "state": { + "branch": "develop", + "revision": "99b270e10b22fe8bb41354d1c8ec75050da6cff6", + "version": null + } + } + ] + }, + "version": 1 +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AccentColor.colorset/Contents.json b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/Contents.json b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/ContentView.swift b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/ContentView.swift new file mode 100644 index 0000000..b996c50 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/ContentView.swift @@ -0,0 +1,111 @@ +// +// ContentView.swift +// SemanticVersionCompareExample +// +// Created by Marius Hötten-Löns on 07.01.21. +// + +import SwiftUI +import SwiftVersionCompare + +struct ContentView: View { + @State var versionAString = "" + @State var versionBString = "" + + var versionCompareResultString: String { + guard + let versionA = Version(versionAString), + let versionB = Version(versionBString) else { + return "Versions are not valid." + } + + if versionA === versionB { + return "Versions are strictly equal." + } else if versionA == versionB { + return "Version are equal." + } else if versionA > versionB { + return "Version A is greater than Version B." + } else if versionA >= versionB { + return "Version A is greater than or equal to Version B." + } else if versionA < versionB { + return "Version A is less than Version B." + } else if versionA <= versionB { + return "Version A is less than or equal to Version B." + } else { + return "Unknown" + } + } + + var severityResultString: String { + guard + let versionA = Version(versionAString), + let versionB = Version(versionBString) else { + return "Versions are not valid." + } + + switch versionA.compare(with: versionB) { + case .major: + return "Version B is a major update to Version A." + case .minor: + return "Version B is a minor update to Version A." + case .patch: + return "Version B is a patch update to Version A." + case .prerelease: + return "Difference in pre-release identifiers." + case .build: + return "Difference in build-meta-datas." + case .noUpdate: + return "No update between the versions detected." + } + } + + var compatibleResultString: String { + guard + let versionA = Version(versionAString), + let versionB = Version(versionBString) else { + return "Versions are not valid." + } + + if versionA.isCompatible(with: versionB) { + return "B is compatible with A." + } else { + return "B is not compatible with A." + } + } + + var body: some View { + NavigationView { + Form { + Section { + TextField("Version A", text: $versionAString) + TextField("Version B", text: $versionBString) + } + + Section( + header: Text("Operator") + ) { + Text("\(versionCompareResultString)") + } + + Section( + header: Text("Severity") + ) { + Text("\(severityResultString)") + } + + Section( + header: Text("Compatible") + ) { + Text("\(compatibleResultString)") + } + } + .navigationTitle("SwiftVersionCompare") + } + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Info.plist b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Info.plist new file mode 100644 index 0000000..efc211a --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UIApplicationSupportsIndirectInputEvents + + UILaunchScreen + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Preview Content/Preview Assets.xcassets/Contents.json b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/SemanticVersionCompareExampleApp.swift b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/SemanticVersionCompareExampleApp.swift new file mode 100644 index 0000000..2b210e2 --- /dev/null +++ b/Example/SemanticVersionCompareExample/SemanticVersionCompareExample/SemanticVersionCompareExampleApp.swift @@ -0,0 +1,17 @@ +// +// SemanticVersionCompareExampleApp.swift +// SemanticVersionCompareExample +// +// Created by Marius Hötten-Löns on 07.01.21. +// + +import SwiftUI + +@main +struct SemanticVersionCompareExampleApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/README.md b/README.md index b1ad77e..85e79b1 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,40 @@ -# SwiftVersionCompare +# SwiftVersionCheck -A small package for comparing and utilizing versions conforming to [SemVer](https://semver.org). +![platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20tvOS%20%7C%20watchOS-lightgrey.svg) +![languages](https://img.shields.io/badge/swift-5.0%20%7C%205.1%20%7C%205.2%20%7C%205.3-orange.svg) +[![build](https://github.com/mflknr/SwiftVersionCompare/workflows/build/badge.svg)](https://github.com/mflknr/SwiftVersionCompare/actions) +[![doccov](https://mflknr.github.io/SwiftVersionCompare/badge.svg?sanitize=true)](https://mflknr.github.io/SwiftVersionCompare/) +[![codecov](https://codecov.io/gh/mflknr/SwiftVersionCompare/branch/develop/graph/badge.svg?token=6EAG2J8DMU)](https://codecov.io/gh/mflknr/SwiftVersionCompare) -Following features are and will be implemented: - -- [x] Create a version from major, minor, patch and extension information. -- [x] Create a version from string using `LosslessStringConvertible` or `ExpressibleByStringLiteral` . -- [x] Compare versions using `Equatable` and `Comparable` with the known operators `==, ===, <, <=, > and >=`. -- [x] Compare versions and get the severity of the update (e. g. major-update). -- [ ] Utilize ranges for a greater variaty of comparisons. -- [x] Extend `Bundle` and `ProcessInfo` for easy usage. -- [x] Open documentation. -- [ ] Extend `Codable` and `Hashable`. +A small package introducing a `Version` object implementing the `SemanticVersionComparable` protocol for comparing versions conforming to [SemVer](https://semver.org). # Installation Swift Package Manager: ```swift -package(url: https://github.com/nihilias/SwiftVersionCompare.git", from: "0.6.0")) +package(url: https://github.com/mflknr/SwiftVersionCompare.git", from: "1.0.0")) ``` # Usage -For detailed implenentation information see auto-generated [documentation](). +For detailed implenentation information see [documentation](https://mflknr.github.io/SwiftVersionCompare/). ```swift -// use the version identifier for initialization +// use the version core identifier for initialization let versionOne = Version(1, 0, 0) let versionTwo = Version( major: 1, minor: 0, - patch: 0 -) + patch: 0, + prerelease: [.alpha], + build: ["1"] +) // -> prints: "1.0.0-alpha+1" // use strings -// use `ExpressibleByStringLiteral` with caution. it's fatal if the string is not a `SemVer` version -let versionThreeA: Version = "1.0.0" -let versionThreeB: Version = Version("1.0.0") - -// using the optional type is safe -let versionFourA: Version? = "1.0.0" -let versionFourB: Version? = Version("1.0.0") +// use `ExpressibleByStringLiteral` with caution, because it's fatal if string is not `SemVer` version +let versionThreeA: Version? = "1.0.0" +let versionThreeB: Version? = Version("1.0.0") // easy initial `0.0.0` version let initialVersion: Version = .initial @@ -54,14 +47,6 @@ let osVersion = ProcessInfo.processInfo.comparableOperatingSystemVersion if Version("1.0.0") > Version("0.4.0") { // ... } - -// compare versions and get update severity -let currentVersion = Version("0.6.0") -let newVersion = Version("1.0.0") - -if currentVersion.severity(to: newVersion) == .major { - // ... -} ``` diff --git a/Sources/SwiftVersionCompare/Helper/Character+Extensions.swift b/Sources/SwiftVersionCompare/Helper/Character+Extensions.swift new file mode 100644 index 0000000..3b5ab74 --- /dev/null +++ b/Sources/SwiftVersionCompare/Helper/Character+Extensions.swift @@ -0,0 +1,16 @@ +// +// Character+Extensions.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 30.03.21. +// + +internal extension Character { + var isZero: Bool { + if self == "0" { + return true + } else { + return false + } + } +} diff --git a/Sources/SwiftVersionCompare/Helper/String+Regex.swift b/Sources/SwiftVersionCompare/Helper/String+Regex.swift index 16a74da..2b9458c 100644 --- a/Sources/SwiftVersionCompare/Helper/String+Regex.swift +++ b/Sources/SwiftVersionCompare/Helper/String+Regex.swift @@ -5,16 +5,22 @@ // Created by Marius Hötten-Löns on 05.01.21. // -import Foundation - -extension String { +internal extension String { func matches(_ regex: String) -> Bool { - self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil + range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil } func matchesSemVerFormat() -> Bool { - self.matches("^([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)$") || - self.matches("^([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)$") || - self.matches("^([0-9a-zA-Z]+)$") + matches("^([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)$") || + matches("^([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)$") || + matches("^([0-9a-zA-Z]+)$") + } + + var isAlphaNumericString: Bool { + matches("[a-zA-Z-][0-9a-zA-Z-]+") + } + + var isNumericString: Bool { + matches("[0-9]+") } } diff --git a/Sources/SwiftVersionCompare/Helper/UpdateSeverity.swift b/Sources/SwiftVersionCompare/Helper/VersionCompareResult.swift similarity index 59% rename from Sources/SwiftVersionCompare/Helper/UpdateSeverity.swift rename to Sources/SwiftVersionCompare/Helper/VersionCompareResult.swift index 45186f7..60c4fd8 100644 --- a/Sources/SwiftVersionCompare/Helper/UpdateSeverity.swift +++ b/Sources/SwiftVersionCompare/Helper/VersionCompareResult.swift @@ -6,7 +6,10 @@ // /// The severity of an update between versions. -public enum UpdateSeverity { +/// +/// - Note: A difference between build-meta-data of versions are explicitly ignored, since `SemVer` does not considere +/// them to be different ranks. +public enum VersionCompareResult { /// A `MAJOR`update case major /// A `MINOR`update @@ -14,7 +17,9 @@ public enum UpdateSeverity { /// A `PATCH`update case patch /// A pre-release update - case `extension` + case prerelease + /// A build update + case build /// The version is not an update (less or equal) case noUpdate } diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData+ExpressibleByLiteral.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData+ExpressibleByLiteral.swift new file mode 100644 index 0000000..64189fd --- /dev/null +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData+ExpressibleByLiteral.swift @@ -0,0 +1,20 @@ +// +// BuildMetaData+ExpressibleByLiteral.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 12.03.21. +// + +extension BuildMetaData: LosslessStringConvertible { + public init?(_ string: String) { + self.init(private: string) + } + + public var description: String { value } +} + +extension BuildMetaData: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.init(private: value) + } +} diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData.swift new file mode 100644 index 0000000..563eee3 --- /dev/null +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData.swift @@ -0,0 +1,45 @@ +// +// BuildMetaData.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 12.03.21. +// + +/// Typed build-meta-data identifier. +/// +/// - Note: Identifier can be described using alphanumeric letters or digits. +/// +/// - Attention: Strings not conforming to `SemVer` will be handled as `nil`. +public enum BuildMetaData: Comparable { + /// Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9. + case alphaNumeric(_ identifier: String) + + /// Digit identifier are positive numbers and zeros, thus allowing leading zeros. + case digits(_ digits: String) + + /// Unknown identifier are used when string literals do not conform to `SemVer` and are removed. + case unknown + + init(private string: String) { + if let _ = Int(string) { + self = .digits(string) + } else if string.isAlphaNumericString { + self = .alphaNumeric(string) + } else { + self = .unknown + } + } +} + +public extension BuildMetaData { + var value: String { + switch self { + case let .alphaNumeric(identifier): + return identifier + case let .digits(identifier): + return identifier + case .unknown: + return "" + } + } +} diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+Equatable.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+Equatable.swift new file mode 100644 index 0000000..5baf80c --- /dev/null +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+Equatable.swift @@ -0,0 +1,15 @@ +// +// PrereleaseIdentifier+Equatable.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 12.03.21. +// + +extension PrereleaseIdentifier { + /// Compares pre-release identifiers for equality. + /// + /// - Returns: `true` if pre-release identifiers are equal. + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.value == rhs.value + } +} diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+ExpressibleByLiteral.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+ExpressibleByLiteral.swift new file mode 100644 index 0000000..1874796 --- /dev/null +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier+ExpressibleByLiteral.swift @@ -0,0 +1,28 @@ +// +// PrereleaseIdentifier+ExpressibleByLiteral.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 12.03.21. +// + +extension PrereleaseIdentifier: LosslessStringConvertible { + public init?(_ string: String) { + self.init(private: string) + } + + public var description: String { value } +} + +extension PrereleaseIdentifier: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.init(private: value) + } +} + +extension PrereleaseIdentifier: ExpressibleByIntegerLiteral { + public init(integerLiteral value: IntegerLiteralType) { + let absoluteInteger: Int = abs(value) + let unsignedInteger: UInt = UInt(absoluteInteger) + self = .numeric(unsignedInteger) + } +} diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier.swift new file mode 100644 index 0000000..29b0524 --- /dev/null +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier.swift @@ -0,0 +1,67 @@ +// +// PrereleaseIdentifier.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 12.03.21. +// + +/// Typed pre-release identifier. +/// +/// - Note: Identifier can be described using alphanumeric or numeric letters. +/// +/// - Attention: If an identifier does not show conformance for beeing numeric or alphanumeric it is initialized +/// as `nil`. +public enum PrereleaseIdentifier: Comparable, Hashable { + /// Identifier displaying `alpha`. + case alpha + + /// Identifier displaying `beta`. + case beta + + /// Identifier displaying `prerelease`. + case prerelease + + /// Identifier displaying `rc`. + case releaseCandidate + + /// Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9. + case alphaNumeric(_ identifier: String) + + /// Numeric identifier are positive numbers and zeros, yet they do not allow for leading zeros. + case numeric(_ identifier: UInt) + + /// Unknown identifier are used when string literals do not conform to `SemVer` and are removed. + case unknown + + init(private string: String) { + if string.isNumericString, + let numeric = UInt(string) { + self = .numeric(numeric) + } else if string.isAlphaNumericString { + self = .alphaNumeric(string) + } else { + self = .unknown + } + } +} + +public extension PrereleaseIdentifier { + var value: String { + switch self { + case .alpha: + return "alpha" + case .beta: + return "beta" + case .prerelease: + return "prerelease" + case .releaseCandidate: + return "rc" + case let .alphaNumeric(identifier): + return identifier + case let .numeric(identifier): + return String(identifier) + case .unknown: + return "" + } + } +} diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Comparable.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Comparable.swift index a2d6225..7e76e8a 100644 --- a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Comparable.swift +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Comparable.swift @@ -5,64 +5,68 @@ // Created by Marius Hötten-Löns on 05.01.21. // -extension SemanticVersionComparable { - public static func < (lhs: Self, rhs: Self) -> Bool { - guard !(lhs === rhs) else { return false } +public extension SemanticVersionComparable { + static func < (lhs: Self, rhs: Self) -> Bool { + // if versions are identical on major, minor and patch level, compare them lexicographiocally + guard lhs.hasEqualVersionCore(as: rhs) else { + // cast UInt to Int for each identifier to compare ordering lexicographically. missing + // identifier for minor or patch versions (e. g. "1" or "2.0") are handled as zeros. + let lhsAsIntSequence = [Int(lhs.major), Int(lhs.minor ?? 0), Int(lhs.patch ?? 0)] + let rhsAsIntSequence = [Int(rhs.major), Int(rhs.minor ?? 0), Int(rhs.patch ?? 0)] + return lhsAsIntSequence.lexicographicallyPrecedes(rhsAsIntSequence) + } - if lhs.major < rhs.major { - return true - } else if - lhs.major == rhs.major, - lhs.minor ?? 0 < rhs.minor ?? 0 { - return true - } else if - lhs.major == rhs.major, - lhs.minor == rhs.minor, - lhs.patch ?? 0 < rhs.patch ?? 0 { - return true - } else if - lhs.major == rhs.major, - lhs.minor == rhs.minor, - lhs.patch == rhs.patch, - lhs.extensions != nil, - rhs.extensions == nil { - return true - } else { + // non-pre-release lhs version is always >= than rhs version + guard + let lhspr = lhs.prerelease, + lhspr.count > 0 else { return false } - } - public static func <= (lhs: Self, rhs: Self) -> Bool { - lhs === rhs || lhs < rhs - } + // same goes for rhs vise versa + guard + let rhspr = rhs.prerelease, + rhspr.count > 0 else { + return true + } - public static func > (lhs: Self, rhs: Self) -> Bool { - guard !(lhs === rhs) else { return false } + // compare content of pre-release identifier + for (untypedLhs, untypedRhs) in zip(lhspr, rhspr) { + // if both pre-release identifier are equal, skip the now obsolete comparison + if untypedLhs == untypedRhs { continue } - if lhs.major > rhs.major { - return true - } else if - lhs.major == rhs.major, - lhs.minor ?? 0 > rhs.minor ?? 0 { - return true - } else if - lhs.major == rhs.major, - lhs.minor == rhs.minor, - lhs.patch ?? 0 > rhs.patch ?? 0 { - return true - } else if - lhs.major == rhs.major, - lhs.minor == rhs.minor, - lhs.patch == rhs.patch, - lhs.extensions == nil, - rhs.extensions != nil { - return true - } else { - return false + // cast identifiers to int or string as Any + let typedLhs: Any = Int(untypedLhs.value) ?? untypedLhs.value + let typedRhs: Any = Int(untypedRhs.value) ?? untypedRhs.value + + switch (typedLhs, typedRhs) { + case let (intLhs as Int, intRhs as Int): + // numerics are compared numerically + return intLhs < intRhs + case let (stringLhs as String, stringRhs as String): + // strings alphanumerically using ASCII + return stringLhs < stringRhs + case (is Int, is String): + // numeric pre-releases are lesser than string pre-releases + return true + case (is String, is Int): + return false + default: + // since we are relatively type safe at this point, it is save to assume we will never + // enter here. so do nothing + () + } } + + // lastly, if number of identifiers of lhs version is lower than rhs version, it ranks lower + return lhspr.count < rhspr.count + } + + static func <= (lhs: Self, rhs: Self) -> Bool { + lhs == rhs || lhs < rhs } - public static func >= (lhs: Self, rhs: Self) -> Bool { - lhs === rhs || lhs > rhs + static func >= (lhs: Self, rhs: Self) -> Bool { + lhs == rhs || lhs > rhs } } diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Equatable.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Equatable.swift index a069b42..bb2446d 100644 --- a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Equatable.swift +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Equatable.swift @@ -5,27 +5,25 @@ // Created by Marius Hötten-Löns on 05.01.21. // -extension SemanticVersionComparable { - /** - Compares version objects for equality. - - - Returns: `true` if version objects are equal. - */ - public static func == (lhs: Self, rhs: Self) -> Bool { - lhs.major == rhs.major && - lhs.minor ?? 0 == rhs.minor ?? 0 && - lhs.patch ?? 0 == rhs.patch ?? 0 +public extension SemanticVersionComparable { + /// Compares version objects for equality. + /// + /// - Returns: `true` if version objects are equal. + static func == (lhs: Self, rhs: Self) -> Bool { + lhs.major == rhs.major + && lhs.minor ?? 0 == rhs.minor ?? 0 + && lhs.patch ?? 0 == rhs.patch ?? 0 + && lhs.prerelease == rhs.prerelease } - /** - Strictly compares version objects for equality. - - - Returns: `true` if version objects are strictly equal. - */ - public static func === (lhs: Self, rhs: Self) -> Bool { - lhs.major == rhs.major && - lhs.minor ?? 0 == rhs.minor ?? 0 && - lhs.patch ?? 0 == rhs.patch ?? 0 && - lhs.extensions == rhs.extensions + /// Strictly compares version objects for equality. + /// + /// - Returns: `true` if version objects are strictly equal. + static func === (lhs: Self, rhs: Self) -> Bool { + lhs.major == rhs.major + && lhs.minor ?? 0 == rhs.minor ?? 0 + && lhs.patch ?? 0 == rhs.patch ?? 0 + && lhs.prerelease == rhs.prerelease + && lhs.build == rhs.build } } diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Hashable.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Hashable.swift new file mode 100644 index 0000000..4f940de --- /dev/null +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable+Hashable.swift @@ -0,0 +1,15 @@ +// +// SemanticVersionComparable+Hashable.swift +// SwiftVersionCompare +// +// Created by Marius Hötten-Löns on 13.03.21. +// + +extension SemanticVersionComparable { + public func hash(into hasher: inout Hasher) { + hasher.combine(major) + hasher.combine(minor) + hasher.combine(patch) + hasher.combine(prerelease) + } +} diff --git a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable.swift b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable.swift index 66a2afb..e9ba932 100644 --- a/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable.swift +++ b/Sources/SwiftVersionCompare/SemanticVersionComparable/SemanticVersionComparable.swift @@ -5,39 +5,26 @@ // Created by Marius Hötten-Löns on 29.12.20. // -/** - A type that can be expressed as a semantic version conforming to `SemVer` and compared using the relational operators ==, ===, <, <=, >=, and >. - - When comparing two versions their identifier beeing `nil` will be treated as `0`. - - let versionOne = Version(1, 0, 0) - let versionTwo = Version(1) - - versionOne == versionTwo // <- this statement is `true` - - You can choose between a loosly or strictly comparison considering if you want to compare the extensions a - the version - - let versionOne = Version(1, 0, 0) - let versionTwo = Version(1, 0, 0, ["alpha"]) - - versionOne == versionTwo // `true` - versionOne === versionTwo // `false` - - When comparing versions for greater- or lesser-to, the extensions will solely be seen as an indicator for having extensions or not. They will be parsed or interpreted. - - let versionOne = Version(1, 0, 0) - let versionTwo = Version(1, 0, 0, ["alpha"]) - - versionOne > versionTwo // `true` - - let versionThree = Version(1, 0, 0, ["alpha"]) - let versionFour = Version(1, 0, 0, ["pre-release"]) - - versionThree > versionFour // `false` - - - Remark: See `https://semver.org` for detailed information. - */ +/// A type that can be expressed as a semantic version conforming to `SemVer`. +/// +/// Additionally to the ranking rules, when comparing two versions, if their version core identifiers are `nil` they +/// will be treated as `0`. +/// +/// let versionOne = Version(1, 0, 0) +/// let versionTwo = Version(1) +/// +/// versionOne == versionTwo // <- this statement is `true` +/// +/// You can choose between a loosly or strictly comparison considering if you want to compare the build-meta-data of +/// the version +/// +/// let versionOne = Version(1, 0, 0, [.alpha]) +/// let versionTwo = Version(1, 0, 0, [.alpha], ["exp"]) +/// +/// versionOne == versionTwo // `true` +/// versionOne === versionTwo // `false` +/// +/// - Remark: See `https://semver.org` for detailed information. public protocol SemanticVersionComparable: Comparable, Hashable { /// The `MAJOR` identifier of a version. var major: UInt { get } @@ -46,54 +33,124 @@ public protocol SemanticVersionComparable: Comparable, Hashable { /// The `PATCH` identifer of a verion. var patch: UInt? { get } - /// Contains strings with pre-release information. - var extensions: [String]? { get } + /// Pre-release identifier of a version. + var prerelease: [PrereleaseIdentifier]? { get } + /// Build-meta-data of a version. + var build: [BuildMetaData]? { get } } // MARK: - -extension SemanticVersionComparable { - /** - A Boolean value indicating the compatibility of two versions. - - - Parameter version: An object that conforms to the `SemanticVersionComparable`protocol. - - - Returns: `true` if both objects have equal major versions. - */ - public func isCompatible(with version: Self) -> Bool { - self.major == version.major +public extension SemanticVersionComparable { + /// A Boolean value indicating the compatibility of two versions. + /// + /// - Parameter version: An object that conforms to the `SemanticVersionComparable`protocol. + /// + /// - Returns: `true` if both objects have equal major versions. + func isCompatible(with version: Self) -> Bool { + major == version.major } - /** - Compare versions for their update severity. - - - Parameter version: The version you want to compare to another version. + /// Compare versions for their update severity. + /// + /// - Parameter version: The version you want to compare to another version. + /// + /// - Returns: The severity of the update the version inherits. + func compare(with version: Self) -> VersionCompareResult { + let lhs = self + let rhs = version + + guard !lhs.hasEqualVersionCore(as: rhs) else { + if lhs < rhs { + return .prerelease + } + if lhs.build != rhs.build && + lhs.prereleaseIdentifierString == rhs.prereleaseIdentifierString { + return .build + } - - Returns: The severity of the update the version inherits. - */ - public func severity(to newVersion: Self) -> UpdateSeverity { - guard self != newVersion || self > newVersion else { return .noUpdate } + return .noUpdate + } if - self.major == newVersion.major, - self.minor == newVersion.minor, - self.patch == newVersion.patch, - self.extensions != newVersion.extensions { - return .extension - } else if - self.major == newVersion.major, - self.minor == newVersion.minor, - self.patch ?? 0 < newVersion.patch ?? 0 { + lhs.major == rhs.major, + lhs.minor == rhs.minor, + lhs.patch ?? 0 < rhs.patch ?? 0 { return .patch } else if - self.major == newVersion.major, - self.minor ?? 0 < newVersion.minor ?? 0 { + lhs.major == rhs.major, + lhs.minor ?? 0 < rhs.minor ?? 0 { return .minor } else if - self.major < newVersion.major { + lhs.major < rhs.major { return .major } else { return .noUpdate } } + + /// Check if a version has an equal version core as another version. + /// + /// - Parameter version: The other version you want to check with. + /// + /// - Returns: `true` if the respective version cores are equal. + func hasEqualVersionCore(as version: Self) -> Bool { + let lhsAsIntSequence = [Int(major), Int(minor ?? 0), Int(patch ?? 0)] + let rhsAsIntSequence = [Int(version.major), Int(version.minor ?? 0), Int(version.patch ?? 0)] + return lhsAsIntSequence.elementsEqual(rhsAsIntSequence) + } +} + +// MARK: - Accessors + +public extension SemanticVersionComparable { + /// The absolute string of the version. + var absoluteString: String { + var versionString = coreString + if let pr = prereleaseIdentifierString { + versionString = [versionString, pr].joined(separator: "-") + } + + if let build = buildMetaDataString { + versionString = [versionString, build].joined(separator: "+") + } + + return versionString + } + + /// The string of the version representing `MAJOR.MINOR.PATCH`. + var coreString: String { + [major, minor, patch] + .compactMap { $0 } + .map(String.init) + .joined(separator: ".") + } + + /// The string of the version representing the pre-release identifier and build-meta-data. + var extensionString: String? { + var extensionsString: String? = prereleaseIdentifierString + if let build = buildMetaDataString { + if let ext = extensionsString { + extensionsString = [ext, build].joined(separator: "+") + } else { + extensionsString = build + } + } + + return extensionsString + } + + /// The pre-release identifier as a string if available. + var prereleaseIdentifierString: String? { + prerelease? + .compactMap { $0.value } + .joined(separator: ".") + } + + /// The build meta data as a string if available. + var buildMetaDataString: String? { + build? + .compactMap { $0.value } + .joined(separator: ".") + } } diff --git a/Sources/SwiftVersionCompare/Version+Bundle.swift b/Sources/SwiftVersionCompare/Version+Bundle.swift index 6adfcac..286d374 100644 --- a/Sources/SwiftVersionCompare/Version+Bundle.swift +++ b/Sources/SwiftVersionCompare/Version+Bundle.swift @@ -8,15 +8,28 @@ import Foundation public extension Bundle { - /** - The version of the current bundle. - - - Note: Uses the key `CFBundleShortVersionString` for retrieving version values. - */ + /// The version of the current bundle. + /// + /// - Note: Uses the key `CFBundleShortVersionString` for retrieving version values. var shortVersion: Version? { guard let versionString: String = infoDictionary?["CFBundleShortVersionString"] as? String else { return nil } let version: Version? = Version(versionString) return version } + + /// The full version of the current bundle. + /// + /// - Note: Uses the key `CFBundleShortVersionString` and `CFBundleVersion` for retrieving version values. + var version: Version? { + guard + let versionString: String = infoDictionary?["CFBundleShortVersionString"] as? String, + let buildString: String = infoDictionary?["CFBundleVersion"] as? String else { + return nil + } + let fullVersionString: String = "\(versionString)+\(buildString)" + let version: Version? = Version(fullVersionString) + + return version + } } diff --git a/Sources/SwiftVersionCompare/Version+StringInitializer.swift b/Sources/SwiftVersionCompare/Version+StringInitializer.swift index 46600f7..8fcc5e7 100644 --- a/Sources/SwiftVersionCompare/Version+StringInitializer.swift +++ b/Sources/SwiftVersionCompare/Version+StringInitializer.swift @@ -6,13 +6,11 @@ // extension Version: LosslessStringConvertible { - /** - Creates a new version from a string. - - - Parameter string: The string beeing parsed into a version. - - - Returns: A version object or `nil` if string does not conform to `SemVer`. - */ + /// Creates a new version from a string. + /// + /// - Parameter string: The string beeing parsed into a version. + /// + /// - Returns: A version object or `nil` if string does not conform to `SemVer`. public init?(_ string: String) { self.init(private: string) } @@ -21,22 +19,18 @@ extension Version: LosslessStringConvertible { } extension Version: ExpressibleByStringLiteral { - /** - Creates a new version from a string literal. - - - Warning: Usage is not recommended unless the given string conforms to `SemVer`. - */ + /// Creates a new version from a string literal. + /// + /// - Warning: Usage is not recommended unless the given string conforms to `SemVer`. public init(stringLiteral value: StringLiteralType) { self.init(private: value)! } } extension Version: ExpressibleByStringInterpolation { - /** - Creates a new version from a string interpolation. - - - Warning: Usage is not recommended unless the given string conforms to `SemVer`. - */ + /// Creates a new version from a string interpolation. + /// + /// - Warning: Usage is not recommended unless the given string conforms to `SemVer`. public init(stringInterpolation: DefaultStringInterpolation) { self.init(private: String(stringInterpolation: stringInterpolation))! } diff --git a/Sources/SwiftVersionCompare/Version.swift b/Sources/SwiftVersionCompare/Version.swift index 9681d25..e613f93 100644 --- a/Sources/SwiftVersionCompare/Version.swift +++ b/Sources/SwiftVersionCompare/Version.swift @@ -5,149 +5,211 @@ // Created by Marius Hötten-Löns on 29.12.20. // -import Foundation - -/** - A version type conforming to `SemVer`. - - You can create a new version using string, string literals, string interpolation formatted like `MAJOR.MINOR.PATCH-EXTENSIONS` or memberwise properties. - - // from string - let version: Version? = "1.0.0" - let version: Version? = Version("1.0.0") - let version: Version = "1.0.0" // <- will crash if string does not conform to `SemVer` - let version: Version = Version("1.0.0") // <- will also crash if string is not a semantic version - - // from memberwise properties - let version: Version = Version(1, 0, 0) - let version: Version = Version(major: 1, minor: 0, patch: 0) - - Pre-Release or buildmetadata information are handled as strings in extensions. - - let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, extensions: ["alpha"]) - version.absoluteString // -> "1.0.0-alpha" - - let version: Version = Version(2, 32, 16, ["pre-release", "alpha"]) - version.absoluteString // -> "2.32.16-pre-release.alpha" - version.extension // -> "pre-release.alpha" - - - Remark: See `https://semver.org` for detailed information. - */ +/// A version type conforming to `SemVer`. +/// +/// You can create a new version using string, string literals and string interpolation formatted +/// like `MAJOR.MINOR.PATCH-PRERELEASE+BUILD` or memberwise properties. +/// +/// // from string +/// let version: Version? = "1.0.0" +/// let version: Version? = Version("1.0.0-alpha.1+23") +/// let version: Version? = Version("1.0.0.1.2") // <- will be `nil` since it's not `SemVer` +/// +/// let version: Version = "1.0.0" // <- will crash if string does not conform to `SemVer` +/// +/// // from memberwise properties +/// let version: Version = Version(1, 0, 0) +/// let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha, "1"], build: ["exp"]) +/// +/// Pre-release identifier or build-meta-data can be handled as strings or as a few selected enumared case with it +/// associated raw value (see `PrereleaseIdentifier` and `BuildMetaData` for more). +/// +/// let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha"], build: ["500"]) +/// version.absoluteString // -> "1.0.0-alpha+500" +/// +/// let version: Version = Version(2, 32, 16, ["family", .alpha], ["1"]) +/// version.absoluteString // -> "2.32.16-family.alpha+1" +/// version.coreString // -> "2.32.16" +/// version.extensionString // -> "family.alpha+1" +/// version.prereleaseIdentifer // -> "family.alpha" +/// version.buildMetaDataString // -> "1" +/// +/// - Remark: See `https://semver.org` for detailed information. public struct Version: SemanticVersionComparable { public var major: UInt public var minor: UInt? public var patch: UInt? - public var extensions: [String]? - - /// An initial version representing the string `0.0.0`. - public static var initial: Version = Version(major: 0, minor: 0, patch: 0) - - // MARK: - - - /** - Creates a new version. - - - Parameters: - - major: The `MAJOR` identifier of a version. - - minor: The `MINOR` identifier of a version. - - patch: The `PATCH` identifier of a version. - - extensions: Contains strings with pre-release information. - - - Returns: A new version. - - - Note: Unsigned integers are used to provide an straightforward way to make sure that the identifiers - are not negative numbers. - */ + public var prerelease: [PrereleaseIdentifier]? + public var build: [BuildMetaData]? + + // MARK: - Init + + /// Creates a new version. + /// + /// - Parameters: + /// - major: The `MAJOR` identifier of a version. + /// - minor: The `MINOR` identifier of a version. + /// - patch: The `PATCH` identifier of a version. + /// - prerelease: The pre-release identifier of a version. + /// - build: The build-meta-data of a version. + /// + /// - Returns: A new version. + /// + /// - Note: Unsigned integers are used to provide an straightforward way to make sure that the identifiers + /// are not negative numbers. @inlinable - public init(_ major: UInt, _ minor: UInt? = nil, _ patch: UInt? = nil, _ extensions: [String]? = nil) { + public init( + _ major: UInt, + _ minor: UInt? = nil, + _ patch: UInt? = nil, + _ prerelease: [PrereleaseIdentifier]? = nil, + _ build: [BuildMetaData]? = nil + ) { self.major = major self.minor = minor self.patch = patch - self.extensions = extensions + self.prerelease = prerelease + self.build = build } - /** - Creates a new version. - - - Parameters: - - major: The `MAJOR` identifier of a version. - - minor: The `MINOR` identifier of a version. - - patch: The `PATCH` identifier of a version. - - extensions: Contains strings with pre-release information. - - - Note: Unsigned integers are used to provide an straightforward way to make sure that the identifiers - are not negative numbers. - */ + /// Creates a new version. + /// + /// - Parameters: + /// - major: The `MAJOR` identifier of a version. + /// - minor: The `MINOR` identifier of a version. + /// - patch: The `PATCH` identifier of a version. + /// - prerelease: The pre-release identifier of a version. + /// - build: The build-meta-data of a version. + /// + /// - Note: Unsigned integers are used to provide an straightforward way to make sure that the identifiers + /// are not negative numbers. @inlinable - public init(major: UInt, minor: UInt? = nil, patch: UInt? = nil, extensions: [String]? = nil) { - self.init(major, minor, patch, extensions) + public init( + major: UInt, + minor: UInt? = nil, + patch: UInt? = nil, + prerelease: [PrereleaseIdentifier]? = nil, + build: [BuildMetaData]? = nil + ) { + self.init(major, minor, patch, prerelease, build) } - internal init?(private string: String) { - // split string into version and extension substrings - let stringElements = string.split(separator: "-", maxSplits: 1, omittingEmptySubsequences: false) + /// Creates a new version using a string. + /// + /// - Parameter string: The string representing a version. + public init?(private string: String) { + // split string into version with pre-release identifier and build-meta-data substrings + let versionSplitBuild = string.split(separator: "+", omittingEmptySubsequences: false) + + // check if string does not contain only build-meta-data e.g. "+123" or falsely "+123+something" + guard + !versionSplitBuild.isEmpty, + versionSplitBuild.count <= 2, + let versionPrereleaseString = versionSplitBuild.first else { + return nil + } + + // split previously splitted substring into version and pre-release identifier substrings + var versionSplitPrerelease = versionPrereleaseString + .split(separator: "-", omittingEmptySubsequences: false) - // check for non-empty version string e.g. "-alpha" - guard let versionStringElement = stringElements.first, !versionStringElement.isEmpty else { + // check for non-empty or invalid version string e.g. "-alpha" + guard + !versionSplitPrerelease.isEmpty, + let versionStringElement = versionSplitPrerelease.first else { return nil } - // check that the versionString has the correct SemVer format which would be any character (number or letter, - // no symbols!) x in the form of `x`, `x.x`or `x.x.x`. + // check that the version string has the correct SemVer format which are 0 and positive numbers in the form + // of `x`, `x.x`or `x.x.x`. let versionString = String(versionStringElement) - guard versionString.matchesSemVerFormat() else { return nil } - - // extract version elements from validated versionString as unsigned integers, throws and returns nil - // if a substring cannot be casted as UInt - let versionIdentifiers: [UInt]? = try? versionString.split(separator: ".").map(String.init).map { - // since we already checked the format, we can now try to extract an UInt from the string - guard let element = UInt($0) else { - throw Error.invalidVersionIdentifier + guard versionString.matchesSemVerFormat() else { + return nil + } + + // extract version elements from validated version string as unsigned integers, throws and returns nil + // if a substring cannot be casted as UInt, since only positive numbers are allowed + let versionIdentifiers: [UInt]? = try? versionString + .split(separator: ".") + .map(String.init) + .map { + // we already checked the format so we can now try to extract an UInt from the string + guard + let element = UInt($0), + let firstCharacter = $0.first, + !(firstCharacter.isZero && $0.count > 1) else { + throw Error.invalidVersionIdentifier + } + + return element } - return element + guard let safeIdentifiers = versionIdentifiers else { + return nil } - guard let safeIdentifiers = versionIdentifiers else { return nil } - // map valid identifiers to corresponding version identifier self.major = safeIdentifiers[0] self.minor = safeIdentifiers.indices.contains(1) ? safeIdentifiers[1] : nil self.patch = safeIdentifiers.indices.contains(2) ? safeIdentifiers[2] : nil - // if an extension label can be found, extract its content and save it to `extensions` - if stringElements.indices.contains(1), let attachmentString = stringElements.last { - self.extensions = attachmentString.split(separator: ".").map(String.init) + // extract pre-release identifier if available + if versionSplitPrerelease.indices.contains(1) { + versionSplitPrerelease.removeFirst(1) + let prereleaseSubstring = versionSplitPrerelease.joined(separator: "-") + self.prerelease = String(prereleaseSubstring) + .split(separator: ".") + .map(String.init) + .compactMap { + if let asInt = Int($0) { + return PrereleaseIdentifier.init(integerLiteral: asInt) + } else { + return PrereleaseIdentifier.init($0) + } + } + // if a pre-release identifier element is initialized as .unkown, we can savely assume that the given + // string is not a valid `SemVer` version string. + if + let prerelease = self.prerelease, + prerelease.contains(where: { $0 == .unknown }) { + return nil + } } else { - self.extensions = nil + // not pre-release identifier has been found + self.prerelease = nil } - } -} -// MARK: - Accessors - -extension Version { - /// The absolute string of the version. - public var absoluteString: String { - [versionCode, `extension`] - .compactMap { $0 } - .joined(separator: "-") + // extract build-meta-data identifier if available + if + versionSplitBuild.indices.contains(1), + let buildSubstring = versionSplitBuild.last { + self.build = String(buildSubstring) + .split(separator: ".") + .map(String.init) + .compactMap { + BuildMetaData.init($0) + } + // finding an .unkown element means that the given string is not conform to `SemVer` since it is no + // alphaNumeric or a digit + if + let build = self.build, + build.contains(where: { $0 == .unknown }) { + return nil + } + } else { + // no build-meta-data has been found + self.build = nil + } } +} - /// The string of the version representing `MAJOR.MINOR.PATCH`. - public var versionCode: String { - [major, minor, patch] - .compactMap { $0 } - .map(String.init) - .joined(separator: ".") - } +// MARK: - Static Accessors - /// The string of the version containing the extension. - public var `extension`: String? { - extensions?.joined(separator: ".") - } +public extension Version { + /// An initial version representing the string `0.0.0`. + static var initial: Version = Version(major: 0, minor: 0, patch: 0) } extension Version: CustomDebugStringConvertible { diff --git a/SwiftVersionCompare.xcodeproj/SwiftVersionCompareTests_Info.plist b/SwiftVersionCompare.xcodeproj/SwiftVersionCompareTests_Info.plist index 7c23420..95e09f8 100644 --- a/SwiftVersionCompare.xcodeproj/SwiftVersionCompareTests_Info.plist +++ b/SwiftVersionCompare.xcodeproj/SwiftVersionCompareTests_Info.plist @@ -1,25 +1,26 @@ + - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + diff --git a/SwiftVersionCompare.xcodeproj/SwiftVersionCompare_Info.plist b/SwiftVersionCompare.xcodeproj/SwiftVersionCompare_Info.plist index ca23c84..454e6a7 100644 --- a/SwiftVersionCompare.xcodeproj/SwiftVersionCompare_Info.plist +++ b/SwiftVersionCompare.xcodeproj/SwiftVersionCompare_Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - $(CURRENT_PROJECT_VERSION) + 1 NSPrincipalClass diff --git a/SwiftVersionCompare.xcodeproj/project.pbxproj b/SwiftVersionCompare.xcodeproj/project.pbxproj index c751205..39cdbe4 100644 --- a/SwiftVersionCompare.xcodeproj/project.pbxproj +++ b/SwiftVersionCompare.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 24828B622613B4EC00AF8BA2 /* Character+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24828B612613B4EC00AF8BA2 /* Character+Extensions.swift */; }; 24A6A24625A3DD3B00E12D71 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A24525A3DD3B00E12D71 /* Error.swift */; }; 24A6A25925A5198900E12D71 /* String+Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A25825A5198900E12D71 /* String+Regex.swift */; }; 24A6A26425A51A2F00E12D71 /* SemanticVersionComparable+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A26325A51A2F00E12D71 /* SemanticVersionComparable+Equatable.swift */; }; @@ -28,7 +29,13 @@ 24A6A27025A51B5500E12D71 /* Version+StringInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A26F25A51B5500E12D71 /* Version+StringInitializer.swift */; }; 24A6A27E25A51E1900E12D71 /* Version+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A27D25A51E1900E12D71 /* Version+Bundle.swift */; }; 24A6A28825A6002200E12D71 /* Version+OS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A28725A6002200E12D71 /* Version+OS.swift */; }; - 24A6A2A625A64DAC00E12D71 /* UpdateSeverity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6A2A525A64DAC00E12D71 /* UpdateSeverity.swift */; }; + 24B3A1CE261103BB00EDC055 /* VersionCompareResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B3A1CD261103BB00EDC055 /* VersionCompareResult.swift */; }; + 24D6001425FB86FB0003375E /* BuildMetaData+ExpressibleByLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D6001325FB86FB0003375E /* BuildMetaData+ExpressibleByLiteral.swift */; }; + 24D6002425FB8B350003375E /* PrereleaseIdentifier+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D6002325FB8B350003375E /* PrereleaseIdentifier+Equatable.swift */; }; + 24D6003625FCE1F60003375E /* SemanticVersionComparable+Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D6003525FCE1F60003375E /* SemanticVersionComparable+Hashable.swift */; }; + 24D6FFE525FB6FFE0003375E /* PrereleaseIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D6FFE425FB6FFE0003375E /* PrereleaseIdentifier.swift */; }; + 24D6FFEF25FB74CA0003375E /* PrereleaseIdentifier+ExpressibleByLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D6FFEE25FB74CA0003375E /* PrereleaseIdentifier+ExpressibleByLiteral.swift */; }; + 24D6FFF625FB75210003375E /* BuildMetaData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D6FFF525FB75210003375E /* BuildMetaData.swift */; }; OBJ_28 /* SemanticVersionComparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* SemanticVersionComparable.swift */; }; OBJ_29 /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* Version.swift */; }; OBJ_36 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; }; @@ -56,6 +63,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 24828B612613B4EC00AF8BA2 /* Character+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Character+Extensions.swift"; sourceTree = ""; }; 24A6A24525A3DD3B00E12D71 /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; }; 24A6A25825A5198900E12D71 /* String+Regex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Regex.swift"; sourceTree = ""; }; 24A6A26325A51A2F00E12D71 /* SemanticVersionComparable+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SemanticVersionComparable+Equatable.swift"; sourceTree = ""; }; @@ -63,8 +71,14 @@ 24A6A26F25A51B5500E12D71 /* Version+StringInitializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Version+StringInitializer.swift"; sourceTree = ""; }; 24A6A27D25A51E1900E12D71 /* Version+Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Version+Bundle.swift"; sourceTree = ""; }; 24A6A28725A6002200E12D71 /* Version+OS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Version+OS.swift"; sourceTree = ""; }; - 24A6A2A525A64DAC00E12D71 /* UpdateSeverity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateSeverity.swift; sourceTree = ""; }; 24A6A2BB25A67D1200E12D71 /* .jazzy.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .jazzy.yml; sourceTree = ""; }; + 24B3A1CD261103BB00EDC055 /* VersionCompareResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionCompareResult.swift; sourceTree = ""; }; + 24D6001325FB86FB0003375E /* BuildMetaData+ExpressibleByLiteral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BuildMetaData+ExpressibleByLiteral.swift"; sourceTree = ""; }; + 24D6002325FB8B350003375E /* PrereleaseIdentifier+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PrereleaseIdentifier+Equatable.swift"; sourceTree = ""; }; + 24D6003525FCE1F60003375E /* SemanticVersionComparable+Hashable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SemanticVersionComparable+Hashable.swift"; sourceTree = ""; }; + 24D6FFE425FB6FFE0003375E /* PrereleaseIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrereleaseIdentifier.swift; sourceTree = ""; }; + 24D6FFEE25FB74CA0003375E /* PrereleaseIdentifier+ExpressibleByLiteral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PrereleaseIdentifier+ExpressibleByLiteral.swift"; sourceTree = ""; }; + 24D6FFF525FB75210003375E /* BuildMetaData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildMetaData.swift; sourceTree = ""; }; OBJ_10 /* SemanticVersionComparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SemanticVersionComparable.swift; sourceTree = ""; }; OBJ_11 /* Version.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Version.swift; sourceTree = ""; }; OBJ_14 /* SemanticVersionComparableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SemanticVersionComparableTests.swift; sourceTree = ""; }; @@ -99,9 +113,10 @@ 24A6A25725A5196D00E12D71 /* Helper */ = { isa = PBXGroup; children = ( + 24828B612613B4EC00AF8BA2 /* Character+Extensions.swift */, 24A6A24525A3DD3B00E12D71 /* Error.swift */, 24A6A25825A5198900E12D71 /* String+Regex.swift */, - 24A6A2A525A64DAC00E12D71 /* UpdateSeverity.swift */, + 24B3A1CD261103BB00EDC055 /* VersionCompareResult.swift */, ); path = Helper; sourceTree = ""; @@ -109,13 +124,35 @@ 24A6A25E25A519AC00E12D71 /* SemanticVersionComparable */ = { isa = PBXGroup; children = ( + 24D6FFE325FB6FD90003375E /* PrereleaseIdentifier */, + 24D6FFF425FB75050003375E /* BuildMetaData */, OBJ_10 /* SemanticVersionComparable.swift */, 24A6A26925A51A4700E12D71 /* SemanticVersionComparable+Comparable.swift */, 24A6A26325A51A2F00E12D71 /* SemanticVersionComparable+Equatable.swift */, + 24D6003525FCE1F60003375E /* SemanticVersionComparable+Hashable.swift */, ); path = SemanticVersionComparable; sourceTree = ""; }; + 24D6FFE325FB6FD90003375E /* PrereleaseIdentifier */ = { + isa = PBXGroup; + children = ( + 24D6FFE425FB6FFE0003375E /* PrereleaseIdentifier.swift */, + 24D6002325FB8B350003375E /* PrereleaseIdentifier+Equatable.swift */, + 24D6FFEE25FB74CA0003375E /* PrereleaseIdentifier+ExpressibleByLiteral.swift */, + ); + path = PrereleaseIdentifier; + sourceTree = ""; + }; + 24D6FFF425FB75050003375E /* BuildMetaData */ = { + isa = PBXGroup; + children = ( + 24D6FFF525FB75210003375E /* BuildMetaData.swift */, + 24D6001325FB86FB0003375E /* BuildMetaData+ExpressibleByLiteral.swift */, + ); + path = BuildMetaData; + sourceTree = ""; + }; OBJ_12 /* Tests */ = { isa = PBXGroup; children = ( @@ -269,9 +306,16 @@ 24A6A27025A51B5500E12D71 /* Version+StringInitializer.swift in Sources */, 24A6A28825A6002200E12D71 /* Version+OS.swift in Sources */, 24A6A24625A3DD3B00E12D71 /* Error.swift in Sources */, + 24B3A1CE261103BB00EDC055 /* VersionCompareResult.swift in Sources */, + 24D6003625FCE1F60003375E /* SemanticVersionComparable+Hashable.swift in Sources */, + 24D6FFE525FB6FFE0003375E /* PrereleaseIdentifier.swift in Sources */, + 24828B622613B4EC00AF8BA2 /* Character+Extensions.swift in Sources */, 24A6A25925A5198900E12D71 /* String+Regex.swift in Sources */, - 24A6A2A625A64DAC00E12D71 /* UpdateSeverity.swift in Sources */, + 24D6FFF625FB75210003375E /* BuildMetaData.swift in Sources */, + 24D6002425FB8B350003375E /* PrereleaseIdentifier+Equatable.swift in Sources */, 24A6A26A25A51A4700E12D71 /* SemanticVersionComparable+Comparable.swift in Sources */, + 24D6001425FB86FB0003375E /* BuildMetaData+ExpressibleByLiteral.swift in Sources */, + 24D6FFEF25FB74CA0003375E /* PrereleaseIdentifier+ExpressibleByLiteral.swift in Sources */, OBJ_29 /* Version.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/SwiftVersionCompare.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/SwiftVersionCompare.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index a72dc2b..ff23ebc 100644 --- a/SwiftVersionCompare.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/SwiftVersionCompare.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -2,7 +2,9 @@ - IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded - + IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + + PreviewsEnabled + - \ No newline at end of file + diff --git a/SwiftVersionCompare.xcodeproj/xcshareddata/xcschemes/SwiftVersionCompare-Package.xcscheme b/SwiftVersionCompare.xcodeproj/xcshareddata/xcschemes/SwiftVersionCompare-Package.xcscheme index 7b8a7bf..61a61e5 100644 --- a/SwiftVersionCompare.xcodeproj/xcshareddata/xcschemes/SwiftVersionCompare-Package.xcscheme +++ b/SwiftVersionCompare.xcodeproj/xcshareddata/xcschemes/SwiftVersionCompare-Package.xcscheme @@ -27,8 +27,7 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES" - codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "YES"> + codeCoverageEnabled = "YES"> rhs) - XCTAssertFalse(lhs < rhs) + XCTAssertFalse(lhs > rhs, "Expected \(lhs) to be greater than \(rhs)") + XCTAssertFalse(lhs < rhs, "Expected \(lhs) to be lesser than \(rhs)") + } + } + + func testStrictEqualOperator() throws { + let validTestData: [Version: Version] = [ + Version("15.287349.10"): Version("15.287349.10"), + Version("0.1.0"): Version("0.1.0"), + Version("1.0.0"): Version("1"), + Version("15.2"): Version("15.2.0"), + Version("1"): Version("1"), + Version("123.0.0"): Version("123"), + Version("1.2"): Version("1.2.0"), + Version("1.9.0"): Version("1.9"), + Version("1-alpha.1"): Version("1-alpha.1"), + Version("24-beta+1"): Version("24-beta+1"), + Version("1.6.2+exp.1"): Version("1.6.2+exp.1"), + Version("2.0+500"): Version("2.0+500") + ] + + let invalidTestData: [Version: Version] = [ + Version("300.0+master"): Version("300.0+develop") + ] + + validTestData.forEach { lhs, rhs in + XCTAssertTrue(lhs === rhs, "Expected \(lhs) to be equal to \(rhs)") + XCTAssertFalse(lhs > rhs, "Expected \(lhs) to be greater than \(rhs)") + XCTAssertFalse(lhs < rhs, "Expected \(lhs) to be lesser than \(rhs)") + } + + invalidTestData.forEach { lhs, rhs in + XCTAssertFalse(lhs === rhs, "Expected \(lhs) to be equal to \(rhs)") } } @@ -33,32 +73,36 @@ final class SemanticVersionComparableTests: XCTestCase { Version("15.287349.9"): Version("15.287349.10"), Version("0.0.1"): Version("0.1.0"), Version("0"): Version("1.0.0"), - Version("13.9182"): Version("15.2.0"), + Version("13.6"): Version("15.2.0"), Version("2"): Version("25"), Version("777.8987"): Version("777.8988"), - Version("13.9182.0-alpha"): Version("15.2.0"), - Version("13.9182.1-alpha"): Version("13.9182.1") + Version("13.9182.0"): Version("15.2.0"), + Version("13.9182.1-alpha"): Version("13.9182.1"), + Version("13.1.1-alpha"): Version("13.1.1-beta"), + Version("5-h2o4hr"): Version("5"), + Version("5-alpha.1"): Version("5-alpha.2"), + Version("5-alpha.2"): Version("5-alpha.beta") ] testData.forEach { lhs, rhs in // less - XCTAssertTrue(lhs < rhs, "Expected \(lhs) to be less to \(rhs)!") - XCTAssertTrue(lhs <= rhs, "Expected \(lhs) to be less or equal to \(rhs)!") + XCTAssertTrue(lhs < rhs, "Expected \(lhs.absoluteString) to be less to \(rhs.absoluteString)!") + XCTAssertTrue(lhs <= rhs, "Expected \(lhs.absoluteString) to be less or equal to \(rhs.absoluteString)!") XCTAssertTrue(lhs <= lhs) XCTAssertTrue(rhs <= rhs) - XCTAssertFalse(rhs < lhs) + XCTAssertFalse(rhs < lhs, "Expected \(rhs.absoluteString) to be less to \(lhs.absoluteString)!") XCTAssertFalse(lhs < lhs) XCTAssertFalse(rhs < rhs) // greater - XCTAssertTrue(rhs > lhs, "Expected \(lhs) to be greater than \(rhs)!") - XCTAssertTrue(rhs >= lhs, "Expected \(lhs) to be greater than or equal to \(rhs)!") + XCTAssertTrue(rhs > lhs, "Expected \(lhs.absoluteString) to be greater than \(rhs.absoluteString)!") + XCTAssertTrue(rhs >= lhs, "Expected \(lhs.absoluteString) to be greater than or equal to \(rhs.absoluteString)!") XCTAssertTrue(rhs >= rhs) XCTAssertTrue(lhs >= lhs) - XCTAssertFalse(lhs > rhs) + XCTAssertFalse(lhs > rhs, "Expected \(lhs.absoluteString) to be greater to \(rhs.absoluteString)!") XCTAssertFalse(rhs > rhs) XCTAssertFalse(lhs > lhs) } @@ -109,27 +153,41 @@ final class SemanticVersionComparableTests: XCTestCase { } func testCompare() { - let testData: [(Version, Version, UpdateSeverity)] = [ - (Version("1"), Version("2"), UpdateSeverity.major), - (Version("600.123.4"), Version("601.0.1"), UpdateSeverity.major), - (Version("1.3"), Version("1.5"), UpdateSeverity.minor), - (Version("3.230.13"), Version("3.235.1"), UpdateSeverity.minor), - (Version("565.1.123"), Version("565.1.124"), UpdateSeverity.patch), - (Version("1.2"), Version("1.2-alpha"), UpdateSeverity.extension), - (Version("2.235234.1"), Version("1.8967596758.4"), UpdateSeverity.noUpdate), - (Version("2.0.0"), Version("2"), UpdateSeverity.noUpdate) + let testData: [(Version, Version, VersionCompareResult)] = [ + (Version("1"), Version("2"), VersionCompareResult.major), + (Version("600.123.4"), Version("601.0.1"), VersionCompareResult.major), + (Version("1.3"), Version("1.5"), VersionCompareResult.minor), + (Version("3.230.13"), Version("3.235.1"), VersionCompareResult.minor), + (Version("565.1.123"), Version("565.1.124"), VersionCompareResult.patch), + (Version("1.2-alpha"), Version("1.2-beta"), VersionCompareResult.prerelease), + (Version("1.34523"), Version("1.34523+100"), VersionCompareResult.build), + (Version("2.235234.1"), Version("1.8967596758.4"), VersionCompareResult.noUpdate), + (Version("2.0.0"), Version("2"), VersionCompareResult.noUpdate), + (Version("2.0.0"), Version("2+1"), VersionCompareResult.build), + (Version("2.0"), Version("2-alpha.beta.1"), VersionCompareResult.noUpdate), + (Version("2.0-alpha.beta.1"), Version("2"), VersionCompareResult.prerelease), + (Version("2.0-alpha.beta.1"), Version("2+exp.1"), VersionCompareResult.prerelease), + (Version("2.0-alpha.beta.1"), Version("2-alpha.beta.1+exp.1"), VersionCompareResult.build), + (Version("2.0-alpha.beta.1"), Version("2.0.0-alpha.beta.1+exp.1"), VersionCompareResult.build), + (Version("2-alpha.beta.1"), Version("2.0-alpha.beta.1+exp.1"), VersionCompareResult.build), + (Version("2-alpha.beta.1"), Version("2-alpha.beta.1+exp.1"), VersionCompareResult.build), + (Version("2-alpha.beta.1+1"), Version("2-alpha.beta.1+exp.1"), VersionCompareResult.build), + (Version("1.0.0-alpha"), Version("1.0.0+1"), VersionCompareResult.prerelease), + (Version("1.0.0+234"), Version("1.0.0-alpha"), VersionCompareResult.noUpdate), + (Version("1.0.0-alpha+1"), Version("1.0.0"), VersionCompareResult.prerelease) ] testData.forEach { data in let versionOne = data.0 let versionTwo = data.1 - let updateSeverity = versionOne.severity(to: versionTwo) - XCTAssertTrue(updateSeverity == data.2, "Expected result from comparing \(data.0) and \(data.1) to be \(data.2) but is \(updateSeverity)!") + let compareResult = versionOne.compare(with: versionTwo) + XCTAssertTrue(compareResult == data.2, "Expected result from comparing \(data.0.absoluteString) and \(data.1.absoluteString) to be \(data.2) but is \(compareResult)!") } } static var allTests = [ ("testEqualOperator", testEqualOperator), + ("testStrictEqualOperator", testStrictEqualOperator), ("testNonEqualOperators", testNonEqualOperators), ("testCompatibility", testCompatibility), ("testCompare", testCompare) diff --git a/Tests/SwiftVersionCompareTests/VersionTests.swift b/Tests/SwiftVersionCompareTests/VersionTests.swift index 52ad255..e62109d 100644 --- a/Tests/SwiftVersionCompareTests/VersionTests.swift +++ b/Tests/SwiftVersionCompareTests/VersionTests.swift @@ -8,15 +8,57 @@ import XCTest @testable import SwiftVersionCompare +typealias ValidVersionStringLiteral = String +typealias ExpectedVersionString = String +typealias ExpectedExtensionString = String + final class VersionTests: XCTestCase { - private let validVersionData: [(String, String, String?)] = [ + private let validVersionData: [(ValidVersionStringLiteral, ExpectedVersionString, ExpectedExtensionString?)] = [ ("1.0.0", "1.0.0", nil) , ("1.2.3-alpha.1", "1.2.3", "alpha.1"), ("1.0", "1.0" , nil), ("1", "1", nil), ("13434", "13434", nil), ("0.123123.0", "0.123123.0", nil), - ("0.0.127498127947", "0.0.127498127947", nil) + ("0.0.127498127947", "0.0.127498127947", nil), + ("1+1", "1", "1"), + ("1-beta.1+exval30", "1", "beta.1+exval30"), + ("23.400-familyalpha.2.beta+172948712.1", "23.400", "familyalpha.2.beta+172948712.1"), + ("1.5+thomassbuild", "1.5", "thomassbuild"), + ("3.265893.15-alpha.13.beta+exp.sha.315", "3.265893.15", "alpha.13.beta+exp.sha.315"), + ("5", "5", nil), + ("5.3", "5.3", nil), + ("5.3.2", "5.3.2", nil), + ("5.0", "5.0", nil), + ("5.0.0", "5.0.0", nil), + ("5.3.0", "5.3.0", nil), + ("5.3.2", "5.3.2", nil), + ("5+3990", "5", "3990"), + ("5.3+3990", "5.3", "3990"), + ("5.3.2+3990", "5.3.2", "3990"), + ("5.0+3990", "5.0", "3990"), + ("5.0.0+3990", "5.0.0", "3990"), + ("5.3.0+3990", "5.3.0", "3990"), + ("5.3.2+3990", "5.3.2", "3990"), + ("5-rc", "5", "rc"), + ("5.3-rc", "5.3", "rc"), + ("5.3.2-rc", "5.3.2", "rc"), + ("5.0-rc", "5.0", "rc"), + ("5.0.0-rc", "5.0.0", "rc"), + ("5.3.0-rc", "5.3.0", "rc"), + ("5.3.2-rc", "5.3.2", "rc"), + ("5-rc+3990", "5", "rc+3990"), + ("5.3-rc+3990", "5.3", "rc+3990"), + ("5.3.2-rc+3990", "5.3.2", "rc+3990"), + ("5.0-rc+3990", "5.0", "rc+3990"), + ("5.0.0-rc+3990", "5.0.0", "rc+3990"), + ("5.3.0-rc+3990", "5.3.0", "rc+3990"), + ("5.3.2-rc+3990", "5.3.2", "rc+3990"), + ("1-1", "1", "1"), + ("1.2.3-alpha-beta+3", "1.2.3", "alpha-beta+3"), + ("1.0.0-alpha-1skladnk1.1+123", "1.0.0", "alpha-1skladnk1.1+123"), + ("1.0.0-alpha-1skl--------ad---nk1.---+123", "1.0.0", "alpha-1skl--------ad---nk1.---+123"), + ("1.2.3-test+123-123-123-123", "1.2.3", "test+123-123-123-123") ] private let invalidVersionData: [String] = [ @@ -42,19 +84,22 @@ final class VersionTests: XCTestCase { "-pre-build", "sdjflk.ksdjla.123", "asdasd.1.1", - "1.1.4354vdf" + "1.1.4354vdf", + "18+123+something", + "1.2.3-test+123-123-123-123+", + "0000001.00000001.01111" ] func testValidConstruction() { validVersionData.forEach { let version = Version($0.0) XCTAssertNotNil(version, "Expected object from string `\($0.0)` not to be nil!") - XCTAssertTrue(version!.versionCode == $0.1, "Expected versionCode to be \($0.1), is: \(version!.versionCode)") + XCTAssertTrue(version!.coreString == $0.1, "Expected versionCode to be \($0.1), is: \(version!.coreString)") XCTAssertEqual(version!.debugDescription, version!.description) if let expectedExtension = $0.2 { - XCTAssertEqual(version!.extension, $0.2, "Expected extension to be \(expectedExtension), is: \(version!.extension ?? "nil")") + XCTAssertEqual(version!.extensionString, $0.2, "Expected extension to be \(expectedExtension), is: \(version!.extensionString ?? "nil")") } else { - XCTAssertNil(version!.extension, "Expected extension to be nil!") + XCTAssertNil(version!.extensionString, "Expected extension to be nil!") } } @@ -63,12 +108,12 @@ final class VersionTests: XCTestCase { // equivalent to `let version: Version = ""` let version = Version(stringLiteral: $0.0) XCTAssertNotNil(version, "Expected object from string `\($0.0)` not to be nil!") - XCTAssertTrue(version.versionCode == $0.1, "Expected versionCode to be \($0.1), is: \(version.versionCode)") + XCTAssertTrue(version.coreString == $0.1, "Expected versionCode to be \($0.1), is: \(version.coreString)") XCTAssertEqual(version.debugDescription, version.description) if let expectedExtension = $0.2 { - XCTAssertEqual(version.extension, $0.2, "Expected extension to be \(expectedExtension), is: \(version.extension ?? "nil")") + XCTAssertEqual(version.extensionString, $0.2, "Expected extension to be \(expectedExtension), is: \(version.extensionString ?? "nil")") } else { - XCTAssertNil(version.extension, "Expected extension to be nil!") + XCTAssertNil(version.extensionString, "Expected extension to be nil!") } } @@ -77,22 +122,38 @@ final class VersionTests: XCTestCase { // equivalent to `let version: Version = ""` let version: Version = "\($0.0)" XCTAssertNotNil(version, "Expected object from string `\($0.0)` not to be nil!") - XCTAssertTrue(version.versionCode == $0.1, "Expected versionCode to be \($0.1), is: \(version.versionCode)") + XCTAssertTrue(version.coreString == $0.1, "Expected versionCode to be \($0.1), is: \(version.coreString)") XCTAssertEqual(version.debugDescription, version.description) if let expectedExtension = $0.2 { - XCTAssertEqual(version.extension, $0.2, "Expected extension to be \(expectedExtension), is: \(version.extension ?? "nil")") + XCTAssertEqual(version.extensionString, $0.2, "Expected extension to be \(expectedExtension), is: \(version.extensionString ?? "nil")") } else { - XCTAssertNil(version.extension, "Expected extension to be nil!") + XCTAssertNil(version.extensionString, "Expected extension to be nil!") } } } func testMemberwiseConstruction() { - let versionA = Version(major: 1, minor: 2, patch: 3, extensions: ["alpha"]) + let versionA = Version(major: 1, minor: 2, patch: 3, prerelease: [.alpha]) XCTAssertEqual(versionA.absoluteString, "1.2.3-alpha", "Expected version to be `1.2.3-alpha`, is: \(versionA)!") let versionB = Version(major: 125) XCTAssertEqual(versionB, "125.0.0") + + let versionC = Version( + major: 1, + minor: 2, + patch: 3, + prerelease: [.alpha, "release"], + build: [.alphaNumeric("exp"), .digits("300"), "test"]) + XCTAssertEqual(versionC.absoluteString, "1.2.3-alpha.release+exp.300.test", "Expected version to be `1.2.3-alpha.release+exp.300.test`, is: \(versionC)!") + + let versionD = Version( + major: 1, + minor: 2, + patch: 3, + prerelease: [.alphaNumeric("alpha"), .numeric(1), .beta, .releaseCandidate, .prerelease], + build: [.alphaNumeric("exp"), .digits("300"), "test"]) + XCTAssertEqual(versionD.absoluteString, "1.2.3-alpha.1.beta.rc.prerelease+exp.300.test", "Expected version to be `1.2.3-alpha.release+exp.300.test`, is: \(versionD)!") } func testInvalidConstruction() { @@ -101,13 +162,25 @@ final class VersionTests: XCTestCase { } } - func testBundleVersion() { + func testInvalidBundleVersion() { + // the main bundle from test targets is different from actual app targets and will be invalid for use, + // but not for testing + XCTAssertNil(Bundle.main.shortVersion) + XCTAssertNil(Bundle.main.version) + } + + func testValidBundleVersion() { let testBundle = Bundle(for: type(of: self)) - let versionString = testBundle.infoDictionary?["CFBundleShortVersionString"] as? String - let bundleVersion: Version? = testBundle.shortVersion - - XCTAssertNotNil(bundleVersion) - XCTAssertEqual(versionString!, bundleVersion!.absoluteString, "Expected \(bundleVersion!) to be equal to \(versionString!)!") + let shortVersionString = testBundle.infoDictionary?["CFBundleShortVersionString"] as? String + let buildString = testBundle.infoDictionary?["CFBundleVersion"] as? String + let shortVersion: Version? = testBundle.shortVersion + let version: Version? = testBundle.version + + XCTAssertNotNil(shortVersion) + XCTAssertEqual(shortVersionString!, shortVersion!.absoluteString, "Expected \(shortVersion!) to be equal to \(shortVersionString!)!") + + XCTAssertNotNil(version) + XCTAssertEqual("\(shortVersionString!)+\(buildString!)", version!.absoluteString, "Expected \(version!) to be equal to \(buildString!)!") } func testProcessInfoVersion() { @@ -135,7 +208,7 @@ final class VersionTests: XCTestCase { ("testValidConstruction", testValidConstruction), ("testMemberwiseConstruction", testMemberwiseConstruction), ("testInvalidConstruction", testInvalidConstruction), - ("testBundleVersion", testBundleVersion), + ("testBundleVersion", testValidBundleVersion), ("testProcessInfoVersion", testProcessInfoVersion) ] } diff --git a/docs/Enums.html b/docs/Enums.html index 1d7e0f0..40a0f9e 100644 --- a/docs/Enums.html +++ b/docs/Enums.html @@ -17,7 +17,7 @@
-

Docs (100% documented)

+

Docs (97% documented)

@@ -39,7 +39,13 @@ Enumerations @@ -85,9 +91,9 @@

Enumerations

  • @@ -96,14 +102,100 @@

    Enumerations

    The severity of an update between versions.

    +
    +

    Note

    + A difference between build-meta-data of versions are explicitly ignored, since SemVer does not considere + them to be different ranks. + +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum VersionCompareResult
    + +
    +
    + +
    +
  • +
  • +
    + + + + BuildMetaData + +
    +
    +
    +
    +
    +
    +

    Typed build-meta-data identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric letters or digits.

    + +
    +

    Attention

    +

    Strings not conforming to SemVer will be handled as nil.

    + +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum BuildMetaData : Comparable
    +
    extension BuildMetaData: LosslessStringConvertible
    +
    extension BuildMetaData: ExpressibleByStringLiteral
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + PrereleaseIdentifier + +
    +
    +
    +
    +
    +
    +

    Typed pre-release identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric or numeric letters.

    + +
    +

    Attention

    +

    If an identifier does not show conformance for beeing numeric or alphanumeric it is initialized + as nil.

    + +
    - See more + See more

    Declaration

    Swift

    -
    public enum UpdateSeverity
    +
    public enum PrereleaseIdentifier : Comparable, Hashable
    +
    extension PrereleaseIdentifier: LosslessStringConvertible
    +
    extension PrereleaseIdentifier: ExpressibleByStringLiteral
    +
    extension PrereleaseIdentifier: ExpressibleByIntegerLiteral
    @@ -115,7 +207,7 @@

    Declaration

    diff --git a/docs/Enums/BuildMetaData.html b/docs/Enums/BuildMetaData.html new file mode 100644 index 0000000..6f1cc50 --- /dev/null +++ b/docs/Enums/BuildMetaData.html @@ -0,0 +1,307 @@ + + + + BuildMetaData Enumeration Reference + + + + + + + + + + + + + +
    +
    +

    Docs (97% documented)

    +

    + + +

    +

    +
    +
    +
    + +
    +
    + +
    +
    +
    +

    BuildMetaData

    +
    +
    + +
    public enum BuildMetaData : Comparable
    +
    extension BuildMetaData: LosslessStringConvertible
    +
    extension BuildMetaData: ExpressibleByStringLiteral
    + +
    +
    +

    Typed build-meta-data identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric letters or digits.

    + +
    +

    Attention

    +

    Strings not conforming to SemVer will be handled as nil.

    + +
    + +
    +
    +
    +
      +
    • +
      + + + + alphaNumeric(_:) + +
      +
      +
      +
      +
      +
      +

      Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case alphaNumeric(_: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + digits(_:) + +
      +
      +
      +
      +
      +
      +

      Digit identifier are positive numbers and zeros, thus allowing leading zeros.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case digits(_: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + unknown + +
      +
      +
      +
      +
      +
      +

      Unknown identifier are used when string literals do not conform to SemVer and are removed.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case unknown
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(_:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init?(_ string: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + description + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public var description: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(stringLiteral:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init(stringLiteral value: StringLiteralType)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + value + +
      +
      +
      +
      +
      +
      +

      Undocumented

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var value: String { get }
      + +
      +
      +
      +
      +
    • +
    +
    +
    +
    + +
    +
    + +
    + diff --git a/docs/Enums/PrereleaseIdentifier.html b/docs/Enums/PrereleaseIdentifier.html new file mode 100644 index 0000000..82967ac --- /dev/null +++ b/docs/Enums/PrereleaseIdentifier.html @@ -0,0 +1,474 @@ + + + + PrereleaseIdentifier Enumeration Reference + + + + + + + + + + + + + +
    +
    +

    Docs (97% documented)

    +

    +

    + +
    +

    +
    +
    +
    + +
    +
    + +
    +
    +
    +

    PrereleaseIdentifier

    +
    +
    + +
    public enum PrereleaseIdentifier : Comparable, Hashable
    +
    extension PrereleaseIdentifier: LosslessStringConvertible
    +
    extension PrereleaseIdentifier: ExpressibleByStringLiteral
    +
    extension PrereleaseIdentifier: ExpressibleByIntegerLiteral
    + +
    +
    +

    Typed pre-release identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric or numeric letters.

    + +
    +

    Attention

    +

    If an identifier does not show conformance for beeing numeric or alphanumeric it is initialized + as nil.

    + +
    + +
    +
    +
    +
      +
    • +
      + + + + alpha + +
      +
      +
      +
      +
      +
      +

      Identifier displaying alpha.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case alpha
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + beta + +
      +
      +
      +
      +
      +
      +

      Identifier displaying beta.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case beta
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + prerelease + +
      +
      +
      +
      +
      +
      +

      Identifier displaying prerelease.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case prerelease
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + releaseCandidate + +
      +
      +
      +
      +
      +
      +

      Identifier displaying rc.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case releaseCandidate
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + alphaNumeric(_:) + +
      +
      +
      +
      +
      +
      +

      Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case alphaNumeric(_: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + numeric(_:) + +
      +
      +
      +
      +
      +
      +

      Numeric identifier are positive numbers and zeros, yet they do not allow for leading zeros.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case numeric(_: UInt)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + unknown + +
      +
      +
      +
      +
      +
      +

      Unknown identifier are used when string literals do not conform to SemVer and are removed.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case unknown
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + ==(_:_:) + +
      +
      +
      +
      +
      +
      +

      Compares pre-release identifiers for equality.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public static func == (lhs: `Self`, rhs: `Self`) -> Bool
      + +
      +
      +
      +

      Return Value

      +

      true if pre-release identifiers are equal.

      +
      +
      +
      +
    • +
    • +
      + + + + init(_:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init?(_ string: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + description + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public var description: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(stringLiteral:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init(stringLiteral value: StringLiteralType)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(integerLiteral:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init(integerLiteral value: IntegerLiteralType)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + value + +
      +
      +
      +
      +
      +
      +

      Undocumented

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var value: String { get }
      + +
      +
      +
      +
      +
    • +
    +
    +
    +
    + +
    +
    + +
  • + diff --git a/docs/Enums/VersionCompareResult.html b/docs/Enums/VersionCompareResult.html index c36c66c..70a8525 100644 --- a/docs/Enums/VersionCompareResult.html +++ b/docs/Enums/VersionCompareResult.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -38,6 +38,12 @@

    The severity of an update between versions.

    +
    +

    Note

    + A difference between build-meta-data of versions are explicitly ignored, since SemVer does not considere + them to be different ranks. + +
    @@ -173,9 +185,9 @@

    Declaration

  • - - - extensions + + + prerelease
    @@ -190,7 +202,34 @@

    Declaration

    Declaration

    Swift

    -
    case extensions
    +
    case prerelease
    + +
    +
    +
  • + + +
  • +
    + + + + build + +
    +
    +
    +
    +
    +
    +

    A build update

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case build
    @@ -229,7 +268,7 @@

    Declaration

    diff --git a/docs/Extensions.html b/docs/Extensions.html index 623b7e0..54ea378 100644 --- a/docs/Extensions.html +++ b/docs/Extensions.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

  • @@ -141,7 +147,7 @@

    Declaration

    diff --git a/docs/Extensions/Bundle.html b/docs/Extensions/Bundle.html index 6f3b05c..3a8b8b5 100644 --- a/docs/Extensions/Bundle.html +++ b/docs/Extensions/Bundle.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -120,12 +126,44 @@

    Declaration

    +
  • +
    + + + + version + +
    +
    +
    +
    +
    +
    +

    The full version of the current bundle.

    +
    +

    Note

    + Uses the key CFBundleShortVersionString and CFBundleVersion for retrieving version values. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var version: Version? { get }
    + +
    +
    +
    +
    +
  • diff --git a/docs/Extensions/ProcessInfo.html b/docs/Extensions/ProcessInfo.html index eafe7ae..da30dc5 100644 --- a/docs/Extensions/ProcessInfo.html +++ b/docs/Extensions/ProcessInfo.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -121,7 +127,7 @@

    Declaration

    diff --git a/docs/Protocols.html b/docs/Protocols.html index a3ca661..a537a82 100644 --- a/docs/Protocols.html +++ b/docs/Protocols.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -95,35 +101,24 @@

    Protocols

    -

    A type that can be expressed as a semantic version conforming to SemVer and compared using the relational operators ==, ===, <, <=, >=, and >.

    +

    A type that can be expressed as a semantic version conforming to SemVer.

    -

    When comparing two versions their identifier beeing nil will be treated as 0.

    +

    Additionally to the ranking rules, when comparing two versions, if their version core identifiers are nil they +will be treated as 0.

    let versionOne = Version(1, 0, 0)
     let versionTwo = Version(1)
     
     versionOne == versionTwo // <- this statement is `true`
     
    -

    You can choose between a loosly or strictly comparison considering if you want to compare the extensions a +

    You can choose between a loosly or strictly comparison considering if you want to compare the build-meta-data of the version

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    +
    let versionOne = Version(1, 0, 0, [.alpha])
    +let versionTwo = Version(1, 0, 0, [.alpha], ["exp"])
     
     versionOne == versionTwo // `true`
     versionOne === versionTwo // `false`
     
    - -

    When comparing versions for greater- or lesser-to, the extensions will solely be seen as an indicator for having extensions or not. They will be parsed or interpreted.

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    -
    -versionOne > versionTwo // `true`
    -
    -let versionThree = Version(1, 0, 0, ["alpha"])
    -let versionFour = Version(1, 0, 0, ["pre-release"])
    -
    -versionThree > versionFour // `false`
    -

    Remark

    See https://semver.org for detailed information. @@ -148,7 +143,7 @@

    Declaration

    diff --git a/docs/Protocols/SemanticVersionComparable.html b/docs/Protocols/SemanticVersionComparable.html index aca2f59..4250bd3 100644 --- a/docs/Protocols/SemanticVersionComparable.html +++ b/docs/Protocols/SemanticVersionComparable.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -83,35 +89,24 @@

    SemanticVersionComparable

    -

    A type that can be expressed as a semantic version conforming to SemVer and compared using the relational operators ==, ===, <, <=, >=, and >.

    +

    A type that can be expressed as a semantic version conforming to SemVer.

    -

    When comparing two versions their identifier beeing nil will be treated as 0.

    +

    Additionally to the ranking rules, when comparing two versions, if their version core identifiers are nil they +will be treated as 0.

    let versionOne = Version(1, 0, 0)
     let versionTwo = Version(1)
     
     versionOne == versionTwo // <- this statement is `true`
     
    -

    You can choose between a loosly or strictly comparison considering if you want to compare the extensions a +

    You can choose between a loosly or strictly comparison considering if you want to compare the build-meta-data of the version

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    +
    let versionOne = Version(1, 0, 0, [.alpha])
    +let versionTwo = Version(1, 0, 0, [.alpha], ["exp"])
     
     versionOne == versionTwo // `true`
     versionOne === versionTwo // `false`
     
    - -

    When comparing versions for greater- or lesser-to, the extensions will solely be seen as an indicator for having extensions or not. They will be parsed or interpreted.

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    -
    -versionOne > versionTwo // `true`
    -
    -let versionThree = Version(1, 0, 0, ["alpha"])
    -let versionFour = Version(1, 0, 0, ["pre-release"])
    -
    -versionThree > versionFour // `false`
    -

    Remark

    See https://semver.org for detailed information. @@ -206,24 +201,31 @@

    Declaration

  • - - - extensions + + + prerelease + + Default implementation +
    -

    Contains strings with pre-release information.

    +

    Pre-release identifier of a version.

    +
    +

    Default Implementation

    +
    +

    Declaration

    Swift

    -
    var extensions: [String]? { get }
    +
    var prerelease: [PrereleaseIdentifier]? { get }
    @@ -233,12 +235,12 @@

    Declaration

  • - - - <(_:_:) + + + build - Extension method + Default implementation
    @@ -246,13 +248,18 @@

    Declaration

    +

    Build-meta-data of a version.

    + +
    +

    Default Implementation

    +

    Declaration

    Swift

    -
    public static func < (lhs: Self, rhs: Self) -> Bool
    +
    var build: [BuildMetaData]? { get }
    @@ -262,9 +269,9 @@

    Declaration

  • - - - <=(_:_:) + + + <(_:_:) Extension method @@ -281,7 +288,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func <= (lhs: Self, rhs: Self) -> Bool
    +
    static func < (lhs: Self, rhs: Self) -> Bool
    @@ -291,9 +298,9 @@

    Declaration

  • - - - >(_:_:) + + + <=(_:_:) Extension method @@ -310,7 +317,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func > (lhs: Self, rhs: Self) -> Bool
    +
    static func <= (lhs: Self, rhs: Self) -> Bool
    @@ -339,7 +346,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func >= (lhs: Self, rhs: Self) -> Bool
    +
    static func >= (lhs: Self, rhs: Self) -> Bool
  • @@ -369,7 +376,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func == (lhs: Self, rhs: Self) -> Bool
    +
    static func == (lhs: Self, rhs: Self) -> Bool
  • @@ -403,7 +410,7 @@

    Return Value

    Declaration

    Swift

    -
    public static func === (lhs: Self, rhs: Self) -> Bool
    +
    static func === (lhs: Self, rhs: Self) -> Bool
  • @@ -414,6 +421,35 @@

    Return Value

    +
  • +
    + + + + hash(into:) + + + Extension method + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func hash(into hasher: inout Hasher)
    + +
    +
    +
    +
    +
  • @@ -437,7 +473,7 @@

    Return Value

    Declaration

    Swift

    -
    public func isCompatible(with version: Self) -> Bool
    +
    func isCompatible(with version: Self) -> Bool
    @@ -470,9 +506,9 @@

    Return Value

  • - - - severity(to:) + + + compare(with:) Extension method @@ -490,7 +526,7 @@

    Return Value

    Declaration

    Swift

    -
    public func severity(to newVersion: Self) -> UpdateSeverity
    +
    func compare(with version: Self) -> VersionCompareResult
    @@ -520,12 +556,228 @@

    Return Value

  • +
  • +
    + + + + hasEqualVersionCore(as:) + + + Extension method + +
    +
    +
    +
    +
    +
    +

    Check if a version has an equal version core as another version.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func hasEqualVersionCore(as version: Self) -> Bool
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + version + + +
    +

    The other version you want to check with.

    +
    +
    +
    +
    +

    Return Value

    +

    true if the respective version cores are equal.

    +
    +
    +
    +
  • + + +
    +
    + + +
    + +

    Accessors

    +

    +
    +
    +
      +
    • +
      + + + + absoluteString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The absolute string of the version.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var absoluteString: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + coreString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The string of the version representing MAJOR.MINOR.PATCH.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var coreString: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + extensionString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The string of the version representing the pre-release identifier and build-meta-data.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var extensionString: String? { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + prereleaseIdentifierString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The pre-release identifier as a string if available.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var prereleaseIdentifierString: String? { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + buildMetaDataString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The build meta data as a string if available.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var buildMetaDataString: String? { get }
      + +
      +
      +
      +
      +
    diff --git a/docs/Structs.html b/docs/Structs.html index 4f8dae0..c5a0fa8 100644 --- a/docs/Structs.html +++ b/docs/Structs.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -97,25 +103,31 @@

    Structures

    A version type conforming to SemVer.

    -

    You can create a new version using string, string literals, string interpolation formatted like MAJOR.MINOR.PATCH-EXTENSIONS or memberwise properties.

    +

    You can create a new version using string, string literals and string interpolation formatted +like MAJOR.MINOR.PATCH-PRERELEASE+BUILD or memberwise properties.

    // from string
     let version: Version? = "1.0.0"
    -let version: Version? = Version("1.0.0")
    +let version: Version? = Version("1.0.0-alpha.1+23")
    +let version: Version? = Version("1.0.0.1.2") // <- will be `nil` since it's not `SemVer`
    +
     let version: Version = "1.0.0" // <- will crash if string does not conform to `SemVer`
    -let version: Version = Version("1.0.0") // <- will also crash if string is not a semantic version
     
     // from memberwise properties
     let version: Version = Version(1, 0, 0)
    -let version: Version = Version(major: 1, minor: 0, patch: 0)
    -
    +let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha, "1"], build: ["exp"]) +
    -

    Pre-Release or buildmetadata information are handled as strings in extensions.

    -
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, extensions: ["alpha"])
    -version.absoluteString // -> "1.0.0-alpha"
    +

    Pre-release identifier or build-meta-data can be handled as strings or as a few selected enumared case with it +associated raw value (see PrereleaseIdentifier and BuildMetaData for more).

    +
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha"], build: ["500"])
    +version.absoluteString // -> "1.0.0-alpha+500"
     
    -let version: Version = Version(2, 32, 16, ["pre-release", "alpha"])
    -version.absoluteString // -> "2.32.16-pre-release.alpha"
    -version.extension // -> "pre-release.alpha"
    +let version: Version = Version(2, 32, 16, ["family", .alpha], ["1"])
    +version.absoluteString // -> "2.32.16-family.alpha+1"
    +version.coreString // -> "2.32.16"
    +version.extensionString // -> "family.alpha+1"
    +version.prereleaseIdentifer // -> "family.alpha"
    +version.buildMetaDataString // -> "1"
     

    Remark

    @@ -145,7 +157,7 @@

    Declaration

    diff --git a/docs/Structs/Version.html b/docs/Structs/Version.html index 3ff4b3c..d13afc5 100644 --- a/docs/Structs/Version.html +++ b/docs/Structs/Version.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -89,25 +95,31 @@

    Version

    A version type conforming to SemVer.

    -

    You can create a new version using string, string literals, string interpolation formatted like MAJOR.MINOR.PATCH-EXTENSIONS or memberwise properties.

    +

    You can create a new version using string, string literals and string interpolation formatted +like MAJOR.MINOR.PATCH-PRERELEASE+BUILD or memberwise properties.

    // from string
     let version: Version? = "1.0.0"
    -let version: Version? = Version("1.0.0")
    +let version: Version? = Version("1.0.0-alpha.1+23")
    +let version: Version? = Version("1.0.0.1.2") // <- will be `nil` since it's not `SemVer`
    +
     let version: Version = "1.0.0" // <- will crash if string does not conform to `SemVer`
    -let version: Version = Version("1.0.0") // <- will also crash if string is not a semantic version
     
     // from memberwise properties
     let version: Version = Version(1, 0, 0)
    -let version: Version = Version(major: 1, minor: 0, patch: 0)
    -
    - -

    Pre-Release or buildmetadata information are handled as strings in extensions.

    -
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, extensions: ["alpha"])
    -version.absoluteString // -> "1.0.0-alpha"
    -
    -let version: Version = Version(2, 32, 16, ["pre-release", "alpha"])
    -version.absoluteString // -> "2.32.16-pre-release.alpha"
    -version.extension // -> "pre-release.alpha"
    +let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha, "1"], build: ["exp"])
    +
    + +

    Pre-release identifier or build-meta-data can be handled as strings or as a few selected enumared case with it +associated raw value (see PrereleaseIdentifier and BuildMetaData for more).

    +
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha"], build: ["500"])
    +version.absoluteString // -> "1.0.0-alpha+500"
    +
    +let version: Version = Version(2, 32, 16, ["family", .alpha], ["1"])
    +version.absoluteString // -> "2.32.16-family.alpha+1"
    +version.coreString // -> "2.32.16"
    +version.extensionString // -> "family.alpha+1"
    +version.prereleaseIdentifer // -> "family.alpha"
    +version.buildMetaDataString // -> "1"
     

    Remark

    @@ -200,9 +212,9 @@

    Declaration

  • - - - extensions + + + prerelease
    @@ -216,7 +228,7 @@

    Declaration

    Declaration

    Swift

    -
    public var extensions: [String]?
    +
    public var prerelease: [PrereleaseIdentifier]?
    @@ -226,9 +238,9 @@

    Declaration

  • - - - initial + + + build
    @@ -236,26 +248,38 @@

    Declaration

    -

    An initial version representing the string 0.0.0.

    - +

    Declaration

    Swift

    -
    public static var initial: Version
    +
    public var build: [BuildMetaData]?
  • + +
    +
    +
    + + +
    + +

    Init

    +

    +
    +
    +
    • @@ -267,7 +291,7 @@

      Declaration

      Note

      Unsigned integers are used to provide an straightforward way to make sure that the identifiers -are not negative numbers.

      + are not negative numbers.

      @@ -277,7 +301,13 @@

      Declaration

      Swift

      @inlinable
      -public init(_ major: UInt, _ minor: UInt? = nil, _ patch: UInt? = nil, _ extensions: [String]? = nil)
      +public init( + _ major: UInt, + _ minor: UInt? = nil, + _ patch: UInt? = nil, + _ prerelease: [PrereleaseIdentifier]? = nil, + _ build: [BuildMetaData]? = nil +)
    @@ -324,12 +354,24 @@

    Parameters

    - extensions + prerelease + + + +
    +

    The pre-release identifier of a version.

    +
    + + + + + + build
    -

    Contains strings with pre-release information.

    +

    The build-meta-data of a version.

    @@ -346,9 +388,9 @@

    Return Value

  • @@ -360,7 +402,7 @@

    Return Value

    Note

    Unsigned integers are used to provide an straightforward way to make sure that the identifiers -are not negative numbers.

    + are not negative numbers.

    @@ -370,7 +412,13 @@

    Declaration

    Swift

    @inlinable
    -public init(major: UInt, minor: UInt? = nil, patch: UInt? = nil, extensions: [String]? = nil)
    +public init( + major: UInt, + minor: UInt? = nil, + patch: UInt? = nil, + prerelease: [PrereleaseIdentifier]? = nil, + build: [BuildMetaData]? = nil +)
    @@ -417,12 +465,70 @@

    Parameters

    - extensions + prerelease
    -

    Contains strings with pre-release information.

    +

    The pre-release identifier of a version.

    +
    + + + + + + build + + + +
    +

    The build-meta-data of a version.

    +
    + + + + + + + +
  • +
  • +
    + + + + init(private:) + +
    +
    +
    +
    +
    +
    +

    Creates a new version using a string.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init?(private string: String)
    + +
    +
    +
    +

    Parameters

    + + + + + @@ -576,11 +682,11 @@

    Declaration

    - - + +
    - -

    Accessors

    + +

    Static Accessors

    @@ -588,63 +694,9 @@

    Accessors

  • - - - absoluteString - -
    -
    -
    -
    -
    -
    -

    The absolute string of the version.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var absoluteString: String { get }
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - versionCode - -
    -
    -
    -
    -
    -
    -

    The string of the version representing MAJOR.MINOR.PATCH.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var versionCode: String { get }
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - extension + + + initial
    @@ -652,14 +704,14 @@

    Declaration

    -

    The string of the version containing the extension.

    +

    An initial version representing the string 0.0.0.

    Declaration

    Swift

    -
    public var `extension`: String? { get }
    +
    static var initial: Version
    @@ -697,7 +749,7 @@

    Declaration

    diff --git a/docs/badge.svg b/docs/badge.svg index a096fec..5f56a7e 100644 --- a/docs/badge.svg +++ b/docs/badge.svg @@ -1,15 +1,15 @@ - + - + - - + + @@ -18,11 +18,11 @@ documentation - - 100% + + 97% - - 100% + + 97% diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Enums.html b/docs/docsets/.docset/Contents/Resources/Documents/Enums.html index 1d7e0f0..40a0f9e 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Enums.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Enums.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

  • @@ -85,9 +91,9 @@

    Enumerations

  • @@ -96,14 +102,100 @@

    Enumerations

    The severity of an update between versions.

    +
    +

    Note

    + A difference between build-meta-data of versions are explicitly ignored, since SemVer does not considere + them to be different ranks. + +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum VersionCompareResult
    + +
    +
    + +
    +
  • +
  • +
    + + + + BuildMetaData + +
    +
    +
    +
    +
    +
    +

    Typed build-meta-data identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric letters or digits.

    + +
    +

    Attention

    +

    Strings not conforming to SemVer will be handled as nil.

    + +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum BuildMetaData : Comparable
    +
    extension BuildMetaData: LosslessStringConvertible
    +
    extension BuildMetaData: ExpressibleByStringLiteral
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + PrereleaseIdentifier + +
    +
    +
    +
    +
    +
    +

    Typed pre-release identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric or numeric letters.

    + +
    +

    Attention

    +

    If an identifier does not show conformance for beeing numeric or alphanumeric it is initialized + as nil.

    + +
    - See more + See more

    Declaration

    Swift

    -
    public enum UpdateSeverity
    +
    public enum PrereleaseIdentifier : Comparable, Hashable
    +
    extension PrereleaseIdentifier: LosslessStringConvertible
    +
    extension PrereleaseIdentifier: ExpressibleByStringLiteral
    +
    extension PrereleaseIdentifier: ExpressibleByIntegerLiteral
    @@ -115,7 +207,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Enums/BuildMetaData.html b/docs/docsets/.docset/Contents/Resources/Documents/Enums/BuildMetaData.html new file mode 100644 index 0000000..6f1cc50 --- /dev/null +++ b/docs/docsets/.docset/Contents/Resources/Documents/Enums/BuildMetaData.html @@ -0,0 +1,307 @@ + + + + BuildMetaData Enumeration Reference + + + + + + + + + + + + + +
    +
    +

    Docs (97% documented)

    +

    + + + +

    +
    +
    +
    + +
    +
    + +
    +
    +
    +

    BuildMetaData

    +
    +
    + +
    public enum BuildMetaData : Comparable
    +
    extension BuildMetaData: LosslessStringConvertible
    +
    extension BuildMetaData: ExpressibleByStringLiteral
    + +
    +
    +

    Typed build-meta-data identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric letters or digits.

    + +
    +

    Attention

    +

    Strings not conforming to SemVer will be handled as nil.

    + +
    + +
    +
    +
    +
      +
    • +
      + + + + alphaNumeric(_:) + +
      +
      +
      +
      +
      +
      +

      Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case alphaNumeric(_: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + digits(_:) + +
      +
      +
      +
      +
      +
      +

      Digit identifier are positive numbers and zeros, thus allowing leading zeros.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case digits(_: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + unknown + +
      +
      +
      +
      +
      +
      +

      Unknown identifier are used when string literals do not conform to SemVer and are removed.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case unknown
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(_:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init?(_ string: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + description + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public var description: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(stringLiteral:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init(stringLiteral value: StringLiteralType)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + value + +
      +
      +
      +
      +
      +
      +

      Undocumented

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var value: String { get }
      + +
      +
      +
      +
      +
    • +
    +
    +
    +
    + +
    +
    + +
    + diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Enums/PrereleaseIdentifier.html b/docs/docsets/.docset/Contents/Resources/Documents/Enums/PrereleaseIdentifier.html new file mode 100644 index 0000000..82967ac --- /dev/null +++ b/docs/docsets/.docset/Contents/Resources/Documents/Enums/PrereleaseIdentifier.html @@ -0,0 +1,474 @@ + + + + PrereleaseIdentifier Enumeration Reference + + + + + + + + + + + + + +
    +
    +

    Docs (97% documented)

    +

    +
    + + +

    +
    +
    +
    + +
    +
    + +
    +
    +
    +

    PrereleaseIdentifier

    +
    +
    + +
    public enum PrereleaseIdentifier : Comparable, Hashable
    +
    extension PrereleaseIdentifier: LosslessStringConvertible
    +
    extension PrereleaseIdentifier: ExpressibleByStringLiteral
    +
    extension PrereleaseIdentifier: ExpressibleByIntegerLiteral
    + +
    +
    +

    Typed pre-release identifier.

    +
    +

    Note

    +

    Identifier can be described using alphanumeric or numeric letters.

    + +
    +

    Attention

    +

    If an identifier does not show conformance for beeing numeric or alphanumeric it is initialized + as nil.

    + +
    + +
    +
    +
    +
      +
    • +
      + + + + alpha + +
      +
      +
      +
      +
      +
      +

      Identifier displaying alpha.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case alpha
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + beta + +
      +
      +
      +
      +
      +
      +

      Identifier displaying beta.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case beta
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + prerelease + +
      +
      +
      +
      +
      +
      +

      Identifier displaying prerelease.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case prerelease
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + releaseCandidate + +
      +
      +
      +
      +
      +
      +

      Identifier displaying rc.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case releaseCandidate
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + alphaNumeric(_:) + +
      +
      +
      +
      +
      +
      +

      Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case alphaNumeric(_: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + numeric(_:) + +
      +
      +
      +
      +
      +
      +

      Numeric identifier are positive numbers and zeros, yet they do not allow for leading zeros.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case numeric(_: UInt)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + unknown + +
      +
      +
      +
      +
      +
      +

      Unknown identifier are used when string literals do not conform to SemVer and are removed.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      case unknown
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + ==(_:_:) + +
      +
      +
      +
      +
      +
      +

      Compares pre-release identifiers for equality.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public static func == (lhs: `Self`, rhs: `Self`) -> Bool
      + +
      +
      +
      +

      Return Value

      +

      true if pre-release identifiers are equal.

      +
      +
      +
      +
    • +
    • +
      + + + + init(_:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init?(_ string: String)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + description + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public var description: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(stringLiteral:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init(stringLiteral value: StringLiteralType)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + init(integerLiteral:) + +
      +
      +
      +
      +
      +
      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      public init(integerLiteral value: IntegerLiteralType)
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + value + +
      +
      +
      +
      +
      +
      +

      Undocumented

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var value: String { get }
      + +
      +
      +
      +
      +
    • +
    +
    +
    +
    + +
    +
    + +
  • + diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Enums/VersionCompareResult.html b/docs/docsets/.docset/Contents/Resources/Documents/Enums/VersionCompareResult.html index c36c66c..70a8525 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Enums/VersionCompareResult.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Enums/VersionCompareResult.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -38,6 +38,12 @@

    The severity of an update between versions.

    +
    +

    Note

    + A difference between build-meta-data of versions are explicitly ignored, since SemVer does not considere + them to be different ranks. + +
    @@ -173,9 +185,9 @@

    Declaration

  • - - - extensions + + + prerelease
    @@ -190,7 +202,34 @@

    Declaration

    Declaration

    Swift

    -
    case extensions
    +
    case prerelease
    + +
    +
    +
  • + + +
  • +
    + + + + build + +
    +
    +
    +
    +
    +
    +

    A build update

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case build
    @@ -229,7 +268,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Extensions.html b/docs/docsets/.docset/Contents/Resources/Documents/Extensions.html index 623b7e0..54ea378 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Extensions.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Extensions.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

  • @@ -141,7 +147,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Extensions/Bundle.html b/docs/docsets/.docset/Contents/Resources/Documents/Extensions/Bundle.html index 6f3b05c..3a8b8b5 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Extensions/Bundle.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Extensions/Bundle.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -120,12 +126,44 @@

    Declaration

    +
  • +
    + + + + version + +
    +
    +
    +
    +
    +
    +

    The full version of the current bundle.

    +
    +

    Note

    + Uses the key CFBundleShortVersionString and CFBundleVersion for retrieving version values. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var version: Version? { get }
    + +
    +
    +
    +
    +
  • diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Extensions/ProcessInfo.html b/docs/docsets/.docset/Contents/Resources/Documents/Extensions/ProcessInfo.html index eafe7ae..da30dc5 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Extensions/ProcessInfo.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Extensions/ProcessInfo.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -121,7 +127,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Protocols.html b/docs/docsets/.docset/Contents/Resources/Documents/Protocols.html index a3ca661..a537a82 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Protocols.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Protocols.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -95,35 +101,24 @@

    Protocols

    -

    A type that can be expressed as a semantic version conforming to SemVer and compared using the relational operators ==, ===, <, <=, >=, and >.

    +

    A type that can be expressed as a semantic version conforming to SemVer.

    -

    When comparing two versions their identifier beeing nil will be treated as 0.

    +

    Additionally to the ranking rules, when comparing two versions, if their version core identifiers are nil they +will be treated as 0.

    let versionOne = Version(1, 0, 0)
     let versionTwo = Version(1)
     
     versionOne == versionTwo // <- this statement is `true`
     
    -

    You can choose between a loosly or strictly comparison considering if you want to compare the extensions a +

    You can choose between a loosly or strictly comparison considering if you want to compare the build-meta-data of the version

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    +
    let versionOne = Version(1, 0, 0, [.alpha])
    +let versionTwo = Version(1, 0, 0, [.alpha], ["exp"])
     
     versionOne == versionTwo // `true`
     versionOne === versionTwo // `false`
     
    - -

    When comparing versions for greater- or lesser-to, the extensions will solely be seen as an indicator for having extensions or not. They will be parsed or interpreted.

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    -
    -versionOne > versionTwo // `true`
    -
    -let versionThree = Version(1, 0, 0, ["alpha"])
    -let versionFour = Version(1, 0, 0, ["pre-release"])
    -
    -versionThree > versionFour // `false`
    -

    Remark

    See https://semver.org for detailed information. @@ -148,7 +143,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Protocols/SemanticVersionComparable.html b/docs/docsets/.docset/Contents/Resources/Documents/Protocols/SemanticVersionComparable.html index aca2f59..4250bd3 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Protocols/SemanticVersionComparable.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Protocols/SemanticVersionComparable.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -83,35 +89,24 @@

    SemanticVersionComparable

    -

    A type that can be expressed as a semantic version conforming to SemVer and compared using the relational operators ==, ===, <, <=, >=, and >.

    +

    A type that can be expressed as a semantic version conforming to SemVer.

    -

    When comparing two versions their identifier beeing nil will be treated as 0.

    +

    Additionally to the ranking rules, when comparing two versions, if their version core identifiers are nil they +will be treated as 0.

    let versionOne = Version(1, 0, 0)
     let versionTwo = Version(1)
     
     versionOne == versionTwo // <- this statement is `true`
     
    -

    You can choose between a loosly or strictly comparison considering if you want to compare the extensions a +

    You can choose between a loosly or strictly comparison considering if you want to compare the build-meta-data of the version

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    +
    let versionOne = Version(1, 0, 0, [.alpha])
    +let versionTwo = Version(1, 0, 0, [.alpha], ["exp"])
     
     versionOne == versionTwo // `true`
     versionOne === versionTwo // `false`
     
    - -

    When comparing versions for greater- or lesser-to, the extensions will solely be seen as an indicator for having extensions or not. They will be parsed or interpreted.

    -
    let versionOne = Version(1, 0, 0)
    -let versionTwo = Version(1, 0, 0, ["alpha"])
    -
    -versionOne > versionTwo // `true`
    -
    -let versionThree = Version(1, 0, 0, ["alpha"])
    -let versionFour = Version(1, 0, 0, ["pre-release"])
    -
    -versionThree > versionFour // `false`
    -

    Remark

    See https://semver.org for detailed information. @@ -206,24 +201,31 @@

    Declaration

  • - - - extensions + + + prerelease + + Default implementation +
    -

    Contains strings with pre-release information.

    +

    Pre-release identifier of a version.

    +
    +

    Default Implementation

    +
    +

    Declaration

    Swift

    -
    var extensions: [String]? { get }
    +
    var prerelease: [PrereleaseIdentifier]? { get }
    @@ -233,12 +235,12 @@

    Declaration

  • - - - <(_:_:) + + + build - Extension method + Default implementation
    @@ -246,13 +248,18 @@

    Declaration

    +

    Build-meta-data of a version.

    + +
    +

    Default Implementation

    +

    Declaration

    Swift

    -
    public static func < (lhs: Self, rhs: Self) -> Bool
    +
    var build: [BuildMetaData]? { get }
    @@ -262,9 +269,9 @@

    Declaration

  • - - - <=(_:_:) + + + <(_:_:) Extension method @@ -281,7 +288,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func <= (lhs: Self, rhs: Self) -> Bool
    +
    static func < (lhs: Self, rhs: Self) -> Bool
    @@ -291,9 +298,9 @@

    Declaration

  • - - - >(_:_:) + + + <=(_:_:) Extension method @@ -310,7 +317,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func > (lhs: Self, rhs: Self) -> Bool
    +
    static func <= (lhs: Self, rhs: Self) -> Bool
    @@ -339,7 +346,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func >= (lhs: Self, rhs: Self) -> Bool
    +
    static func >= (lhs: Self, rhs: Self) -> Bool
  • @@ -369,7 +376,7 @@

    Declaration

    Declaration

    Swift

    -
    public static func == (lhs: Self, rhs: Self) -> Bool
    +
    static func == (lhs: Self, rhs: Self) -> Bool
  • @@ -403,7 +410,7 @@

    Return Value

    Declaration

    Swift

    -
    public static func === (lhs: Self, rhs: Self) -> Bool
    +
    static func === (lhs: Self, rhs: Self) -> Bool
  • @@ -414,6 +421,35 @@

    Return Value

    +
  • +
    + + + + hash(into:) + + + Extension method + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func hash(into hasher: inout Hasher)
    + +
    +
    +
    +
    +
  • @@ -437,7 +473,7 @@

    Return Value

    Declaration

    Swift

    -
    public func isCompatible(with version: Self) -> Bool
    +
    func isCompatible(with version: Self) -> Bool
    @@ -470,9 +506,9 @@

    Return Value

  • - - - severity(to:) + + + compare(with:) Extension method @@ -490,7 +526,7 @@

    Return Value

    Declaration

    Swift

    -
    public func severity(to newVersion: Self) -> UpdateSeverity
    +
    func compare(with version: Self) -> VersionCompareResult
    @@ -520,12 +556,228 @@

    Return Value

  • +
  • +
    + + + + hasEqualVersionCore(as:) + + + Extension method + +
    +
    +
    +
    +
    +
    +

    Check if a version has an equal version core as another version.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func hasEqualVersionCore(as version: Self) -> Bool
    + +
    +
    +
    +

    Parameters

    +
  • + + string + + +
    +

    The string representing a version.

    + + + + + + +
    + + version + + +
    +

    The other version you want to check with.

    +
    +
    +
    +
    +

    Return Value

    +

    true if the respective version cores are equal.

    +
    +
    +
    +
  • + + +
    +
    + + +
    + +

    Accessors

    +

    +
    +
    +
      +
    • +
      + + + + absoluteString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The absolute string of the version.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var absoluteString: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + coreString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The string of the version representing MAJOR.MINOR.PATCH.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var coreString: String { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + extensionString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The string of the version representing the pre-release identifier and build-meta-data.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var extensionString: String? { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + prereleaseIdentifierString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The pre-release identifier as a string if available.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var prereleaseIdentifierString: String? { get }
      + +
      +
      +
      +
      +
    • +
    • +
      + + + + buildMetaDataString + + + Extension method + +
      +
      +
      +
      +
      +
      +

      The build meta data as a string if available.

      + +
      +
      +

      Declaration

      +
      +

      Swift

      +
      var buildMetaDataString: String? { get }
      + +
      +
      +
      +
      +
    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Structs.html b/docs/docsets/.docset/Contents/Resources/Documents/Structs.html index 4f8dae0..c5a0fa8 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Structs.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Structs.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -97,25 +103,31 @@

    Structures

    A version type conforming to SemVer.

    -

    You can create a new version using string, string literals, string interpolation formatted like MAJOR.MINOR.PATCH-EXTENSIONS or memberwise properties.

    +

    You can create a new version using string, string literals and string interpolation formatted +like MAJOR.MINOR.PATCH-PRERELEASE+BUILD or memberwise properties.

    // from string
     let version: Version? = "1.0.0"
    -let version: Version? = Version("1.0.0")
    +let version: Version? = Version("1.0.0-alpha.1+23")
    +let version: Version? = Version("1.0.0.1.2") // <- will be `nil` since it's not `SemVer`
    +
     let version: Version = "1.0.0" // <- will crash if string does not conform to `SemVer`
    -let version: Version = Version("1.0.0") // <- will also crash if string is not a semantic version
     
     // from memberwise properties
     let version: Version = Version(1, 0, 0)
    -let version: Version = Version(major: 1, minor: 0, patch: 0)
    -
    +let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha, "1"], build: ["exp"]) +
    -

    Pre-Release or buildmetadata information are handled as strings in extensions.

    -
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, extensions: ["alpha"])
    -version.absoluteString // -> "1.0.0-alpha"
    +

    Pre-release identifier or build-meta-data can be handled as strings or as a few selected enumared case with it +associated raw value (see PrereleaseIdentifier and BuildMetaData for more).

    +
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha"], build: ["500"])
    +version.absoluteString // -> "1.0.0-alpha+500"
     
    -let version: Version = Version(2, 32, 16, ["pre-release", "alpha"])
    -version.absoluteString // -> "2.32.16-pre-release.alpha"
    -version.extension // -> "pre-release.alpha"
    +let version: Version = Version(2, 32, 16, ["family", .alpha], ["1"])
    +version.absoluteString // -> "2.32.16-family.alpha+1"
    +version.coreString // -> "2.32.16"
    +version.extensionString // -> "family.alpha+1"
    +version.prereleaseIdentifer // -> "family.alpha"
    +version.buildMetaDataString // -> "1"
     

    Remark

    @@ -145,7 +157,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/Structs/Version.html b/docs/docsets/.docset/Contents/Resources/Documents/Structs/Version.html index 3ff4b3c..d13afc5 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/Structs/Version.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/Structs/Version.html @@ -17,7 +17,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -39,7 +39,13 @@ Enumerations

    @@ -89,25 +95,31 @@

    Version

    A version type conforming to SemVer.

    -

    You can create a new version using string, string literals, string interpolation formatted like MAJOR.MINOR.PATCH-EXTENSIONS or memberwise properties.

    +

    You can create a new version using string, string literals and string interpolation formatted +like MAJOR.MINOR.PATCH-PRERELEASE+BUILD or memberwise properties.

    // from string
     let version: Version? = "1.0.0"
    -let version: Version? = Version("1.0.0")
    +let version: Version? = Version("1.0.0-alpha.1+23")
    +let version: Version? = Version("1.0.0.1.2") // <- will be `nil` since it's not `SemVer`
    +
     let version: Version = "1.0.0" // <- will crash if string does not conform to `SemVer`
    -let version: Version = Version("1.0.0") // <- will also crash if string is not a semantic version
     
     // from memberwise properties
     let version: Version = Version(1, 0, 0)
    -let version: Version = Version(major: 1, minor: 0, patch: 0)
    -
    - -

    Pre-Release or buildmetadata information are handled as strings in extensions.

    -
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, extensions: ["alpha"])
    -version.absoluteString // -> "1.0.0-alpha"
    -
    -let version: Version = Version(2, 32, 16, ["pre-release", "alpha"])
    -version.absoluteString // -> "2.32.16-pre-release.alpha"
    -version.extension // -> "pre-release.alpha"
    +let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha, "1"], build: ["exp"])
    +
    + +

    Pre-release identifier or build-meta-data can be handled as strings or as a few selected enumared case with it +associated raw value (see PrereleaseIdentifier and BuildMetaData for more).

    +
    let version: Version = let version: Version = Version(major: 1, minor: 0, patch: 0, prerelease: ["alpha"], build: ["500"])
    +version.absoluteString // -> "1.0.0-alpha+500"
    +
    +let version: Version = Version(2, 32, 16, ["family", .alpha], ["1"])
    +version.absoluteString // -> "2.32.16-family.alpha+1"
    +version.coreString // -> "2.32.16"
    +version.extensionString // -> "family.alpha+1"
    +version.prereleaseIdentifer // -> "family.alpha"
    +version.buildMetaDataString // -> "1"
     

    Remark

    @@ -200,9 +212,9 @@

    Declaration

  • - - - extensions + + + prerelease
    @@ -216,7 +228,7 @@

    Declaration

    Declaration

    Swift

    -
    public var extensions: [String]?
    +
    public var prerelease: [PrereleaseIdentifier]?
    @@ -226,9 +238,9 @@

    Declaration

  • - - - initial + + + build
    @@ -236,26 +248,38 @@

    Declaration

    -

    An initial version representing the string 0.0.0.

    - +

    Declaration

    Swift

    -
    public static var initial: Version
    +
    public var build: [BuildMetaData]?
  • + +
    +
    +
    + + +
    + +

    Init

    +

    +
    +
    +
    • @@ -267,7 +291,7 @@

      Declaration

      Note

      Unsigned integers are used to provide an straightforward way to make sure that the identifiers -are not negative numbers.

      + are not negative numbers.

      @@ -277,7 +301,13 @@

      Declaration

      Swift

      @inlinable
      -public init(_ major: UInt, _ minor: UInt? = nil, _ patch: UInt? = nil, _ extensions: [String]? = nil)
      +public init( + _ major: UInt, + _ minor: UInt? = nil, + _ patch: UInt? = nil, + _ prerelease: [PrereleaseIdentifier]? = nil, + _ build: [BuildMetaData]? = nil +)
    @@ -324,12 +354,24 @@

    Parameters

    - extensions + prerelease + + + +
    +

    The pre-release identifier of a version.

    +
    + + + + + + build
    -

    Contains strings with pre-release information.

    +

    The build-meta-data of a version.

    @@ -346,9 +388,9 @@

    Return Value

  • @@ -360,7 +402,7 @@

    Return Value

    Note

    Unsigned integers are used to provide an straightforward way to make sure that the identifiers -are not negative numbers.

    + are not negative numbers.

    @@ -370,7 +412,13 @@

    Declaration

    Swift

    @inlinable
    -public init(major: UInt, minor: UInt? = nil, patch: UInt? = nil, extensions: [String]? = nil)
    +public init( + major: UInt, + minor: UInt? = nil, + patch: UInt? = nil, + prerelease: [PrereleaseIdentifier]? = nil, + build: [BuildMetaData]? = nil +)
    @@ -417,12 +465,70 @@

    Parameters

    - extensions + prerelease
    -

    Contains strings with pre-release information.

    +

    The pre-release identifier of a version.

    +
    + + + + + + build + + + +
    +

    The build-meta-data of a version.

    +
    + + + + + + + +
  • +
  • +
    + + + + init(private:) + +
    +
    +
    +
    +
    +
    +

    Creates a new version using a string.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init?(private string: String)
    + +
    +
    +
    +

    Parameters

    + + + + + @@ -576,11 +682,11 @@

    Declaration

    - - + +
    - -

    Accessors

    + +

    Static Accessors

    @@ -588,63 +694,9 @@

    Accessors

  • - - - absoluteString - -
    -
    -
    -
    -
    -
    -

    The absolute string of the version.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var absoluteString: String { get }
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - versionCode - -
    -
    -
    -
    -
    -
    -

    The string of the version representing MAJOR.MINOR.PATCH.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var versionCode: String { get }
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - extension + + + initial
    @@ -652,14 +704,14 @@

    Declaration

    -

    The string of the version containing the extension.

    +

    An initial version representing the string 0.0.0.

    Declaration

    Swift

    -
    public var `extension`: String? { get }
    +
    static var initial: Version
    @@ -697,7 +749,7 @@

    Declaration

    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/badge.svg b/docs/docsets/.docset/Contents/Resources/Documents/badge.svg index a096fec..5f56a7e 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/badge.svg +++ b/docs/docsets/.docset/Contents/Resources/Documents/badge.svg @@ -1,15 +1,15 @@ - + - + - - + + @@ -18,11 +18,11 @@ documentation - - 100% + + 97% - - 100% + + 97% diff --git a/docs/docsets/.docset/Contents/Resources/Documents/index.html b/docs/docsets/.docset/Contents/Resources/Documents/index.html index 37da10d..dc57a0c 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/index.html +++ b/docs/docsets/.docset/Contents/Resources/Documents/index.html @@ -16,7 +16,7 @@
    -

    Docs (100% documented)

    +

    Docs (97% documented)

    @@ -38,7 +38,13 @@ Enumerations

  • @@ -77,44 +83,35 @@

    SwiftVersionCheck

    -

    A small package for comparing and utilizing versions conforming to SemVer.

    - -

    Following features are and will be implemented:

    +

    platforms +languages +build +doccov +codecov

    -
      -
    • [x] Create a version from major, minor, patch and extension information.
    • -
    • [x] Create a version from string using LosslessStringConvertible or ExpressibleByStringLiteral .
    • -
    • [x] Compare versions using Equatable and Comparable with the known operators ==, ===, <, <=, > and >=.
    • -
    • [x] Compare versions and get the severity of the update (e. g. major-update).
    • -
    • [ ] Utilize ranges for a greater variaty of comparisons.
    • -
    • [x] Extend Bundle and ProcessInfo for easy usage.
    • -
    • [x] Open documentation.
    • -
    • [ ] Extend Codable and Hashable.
    • -
    +

    A small package introducing a Version object implementing the SemanticVersionComparable protocol for comparing versions conforming to SemVer.

    Installation

    Swift Package Manager:

    -
    package(url: https://github.com/nihilias/SwiftVersionCompare.git", from: "0.6.0"))
    +
    package(url: https://github.com/nihilias/SwiftVersionCompare.git", from: "1.0.0"))
     

    Usage

    -

    For detailed implenentation information see auto-generated documentation.

    -
    // use the version identifier for initialization
    +

    For detailed implenentation information see documentation.

    +
    // use the version core identifier for initialization
     let versionOne = Version(1, 0, 0)
     let versionTwo = Version(
         major: 1,
         minor: 0,
    -    patch: 0
    -)
    +    patch: 0,
    +    prerelease: [.alpha],
    +    build: ["1"]
    +) // -> prints: "1.0.0-alpha+1"
     
     // use strings
    -// use `ExpressibleByStringLiteral` with caution. it's fatal if the string is not a `SemVer` version
    -let versionThreeA: Version = "1.0.0" 
    -let versionThreeB: Version = Version("1.0.0")
    -
    -// using the optional type is safe
    -let versionFourA: Version? = "1.0.0"
    -let versionFourB: Version? = Version("1.0.0")
    +// use `ExpressibleByStringLiteral` with caution, because it's fatal if string is not `SemVer` version
    +let versionThreeA: Version? = "1.0.0" 
    +let versionThreeB: Version? = Version("1.0.0")
     
     // easy initial `0.0.0` version
     let initialVersion: Version = .initial
    @@ -127,20 +124,12 @@ 

    Usage

    if Version("1.0.0") > Version("0.4.0") { // ... } - -// compare versions and get update severity -let currentVersion = Version("0.6.0") -let newVersion = Version("1.0.0") - -if currentVersion.severity(to: newVersion) == .major { - // ... -}
    diff --git a/docs/docsets/.docset/Contents/Resources/Documents/search.json b/docs/docsets/.docset/Contents/Resources/Documents/search.json index 801d55b..fdbfb8f 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/search.json +++ b/docs/docsets/.docset/Contents/Resources/Documents/search.json @@ -1 +1 @@ -{"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10extensionsSaySSGSgvp":{"name":"extensions","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V7initialACvpZ":{"name":"initial","abstract":"

    An initial version representing the string 0.0.0.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSu_SuSgADSaySSGSgtcfc":{"name":"init(_:_:_:_:)","abstract":"

    Creates a new version.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V5major5minor5patch10extensionsACSu_SuSgAHSaySSGSgtcfc":{"name":"init(major:minor:patch:extensions:)","abstract":"

    Creates a new version.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSgSScfc":{"name":"init(_:)","abstract":"

    Creates a new version from a string.

    ","parent_name":"Version"},"Structs/Version.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V13stringLiteralACSS_tcfc":{"name":"init(stringLiteral:)","abstract":"

    Creates a new version from a string literal.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V19stringInterpolationACs013DefaultStringE0V_tcfc":{"name":"init(stringInterpolation:)","abstract":"

    Creates a new version from a string interpolation.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V14absoluteStringSSvp":{"name":"absoluteString","abstract":"

    The absolute string of the version.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V11versionCodeSSvp":{"name":"versionCode","abstract":"

    The string of the version representing MAJOR.MINOR.PATCH.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V9extensionSSSgvp":{"name":"extension","abstract":"

    The string of the version containing the extension.

    ","parent_name":"Version"},"Structs/Version.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"Version"},"Structs/Version.html":{"name":"Version","abstract":"

    A version type conforming to SemVer.

    "},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","abstract":"

    The MAJOR identifier of a version.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","abstract":"

    The MINOR identifier of a version

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","abstract":"

    The PATCH identifer of a verion.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10extensionsSaySSGSgvp":{"name":"extensions","abstract":"

    Contains strings with pre-release information.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL1loiySbx_xtFZ":{"name":"<(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2leoiySbx_xtFZ":{"name":"<=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL1goiySbx_xtFZ":{"name":">(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2geoiySbx_xtFZ":{"name":">=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE2eeoiySbx_xtFZ":{"name":"==(_:_:)","abstract":"

    Compares version objects for equality.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE3eeeoiySbx_xtFZ":{"name":"===(_:_:)","abstract":"

    Strictly compares version objects for equality.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE12isCompatible4withSbx_tF":{"name":"isCompatible(with:)","abstract":"

    A Boolean value indicating the compatibility of two versions.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE8severity2toAA14UpdateSeverityOx_tF":{"name":"severity(to:)","abstract":"

    Compare versions for their update severity.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html":{"name":"SemanticVersionComparable","abstract":"

    A type that can be expressed as a semantic version conforming to SemVer and compared using the relational operators ==, ===, <, <=, >=, and >.

    "},"Extensions/ProcessInfo.html#/s:So13NSProcessInfoC19SwiftVersionCompareE025comparableOperatingSystemD0AC0D0Vvp":{"name":"comparableOperatingSystemVersion","abstract":"

    The version of the operating system on which the current process is executing.

    ","parent_name":"ProcessInfo"},"Extensions/Bundle.html#/s:So8NSBundleC19SwiftVersionCompareE05shortC0AC0C0VSgvp":{"name":"shortVersion","abstract":"

    The version of the current bundle.

    ","parent_name":"Bundle"},"Extensions/Bundle.html":{"name":"Bundle"},"Extensions/ProcessInfo.html":{"name":"ProcessInfo"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO5majoryA2CmF":{"name":"major","abstract":"

    A MAJORupdate

    ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO5minoryA2CmF":{"name":"minor","abstract":"

    A MINORupdate

    ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO5patchyA2CmF":{"name":"patch","abstract":"

    A PATCHupdate

    ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO9extensionyA2CmF":{"name":"extension","abstract":"

    A pre-release update

    ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO02noD0yA2CmF":{"name":"noUpdate","abstract":"

    The version is not an update (less or equal)

    ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html":{"name":"UpdateSeverity","abstract":"

    The severity of an update between versions.

    "},"Enums.html":{"name":"Enumerations","abstract":"

    The following enumerations are available globally.

    "},"Extensions.html":{"name":"Extensions","abstract":"

    The following extensions are available globally.

    "},"Protocols.html":{"name":"Protocols","abstract":"

    The following protocols are available globally.

    "},"Structs.html":{"name":"Structures","abstract":"

    The following structures are available globally.

    "}} \ No newline at end of file +{"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10prereleaseSayAA20PrereleaseIdentifierOGSgvp":{"name":"prerelease","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5buildSayAA13BuildMetaDataOGSgvp":{"name":"build","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSu_SuSgADSayAA20PrereleaseIdentifierOGSgSayAA13BuildMetaDataOGSgtcfc":{"name":"init(_:_:_:_:_:)","abstract":"

    Creates a new version.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V5major5minor5patch10prerelease5buildACSu_SuSgAISayAA20PrereleaseIdentifierOGSgSayAA13BuildMetaDataOGSgtcfc":{"name":"init(major:minor:patch:prerelease:build:)","abstract":"

    Creates a new version.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V7privateACSgSS_tcfc":{"name":"init(private:)","abstract":"

    Creates a new version using a string.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSgSScfc":{"name":"init(_:)","abstract":"

    Creates a new version from a string.

    ","parent_name":"Version"},"Structs/Version.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V13stringLiteralACSS_tcfc":{"name":"init(stringLiteral:)","abstract":"

    Creates a new version from a string literal.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V19stringInterpolationACs013DefaultStringE0V_tcfc":{"name":"init(stringInterpolation:)","abstract":"

    Creates a new version from a string interpolation.

    ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V7initialACvpZ":{"name":"initial","abstract":"

    An initial version representing the string 0.0.0.

    ","parent_name":"Version"},"Structs/Version.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"Version"},"Structs/Version.html":{"name":"Version","abstract":"

    A version type conforming to SemVer.

    "},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","abstract":"

    The MAJOR identifier of a version.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","abstract":"

    The MINOR identifier of a version

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","abstract":"

    The PATCH identifer of a verion.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10prereleaseSayAA20PrereleaseIdentifierOGSgvp":{"name":"prerelease","abstract":"

    Pre-release identifier of a version.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5buildSayAA13BuildMetaDataOGSgvp":{"name":"build","abstract":"

    Build-meta-data of a version.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL1loiySbx_xtFZ":{"name":"<(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2leoiySbx_xtFZ":{"name":"<=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2geoiySbx_xtFZ":{"name":">=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE2eeoiySbx_xtFZ":{"name":"==(_:_:)","abstract":"

    Compares version objects for equality.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE3eeeoiySbx_xtFZ":{"name":"===(_:_:)","abstract":"

    Strictly compares version objects for equality.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SH4hash4intoys6HasherVz_tF":{"name":"hash(into:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE12isCompatible4withSbx_tF":{"name":"isCompatible(with:)","abstract":"

    A Boolean value indicating the compatibility of two versions.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE7compare4withAA0bC6ResultOx_tF":{"name":"compare(with:)","abstract":"

    Compare versions for their update severity.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE08hasEqualB4Core2asSbx_tF":{"name":"hasEqualVersionCore(as:)","abstract":"

    Check if a version has an equal version core as another version.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE14absoluteStringSSvp":{"name":"absoluteString","abstract":"

    The absolute string of the version.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE10coreStringSSvp":{"name":"coreString","abstract":"

    The string of the version representing MAJOR.MINOR.PATCH.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE15extensionStringSSSgvp":{"name":"extensionString","abstract":"

    The string of the version representing the pre-release identifier and build-meta-data.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE26prereleaseIdentifierStringSSSgvp":{"name":"prereleaseIdentifierString","abstract":"

    The pre-release identifier as a string if available.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE19buildMetaDataStringSSSgvp":{"name":"buildMetaDataString","abstract":"

    The build meta data as a string if available.

    ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html":{"name":"SemanticVersionComparable","abstract":"

    A type that can be expressed as a semantic version conforming to SemVer.

    "},"Extensions/ProcessInfo.html#/s:So13NSProcessInfoC19SwiftVersionCompareE025comparableOperatingSystemD0AC0D0Vvp":{"name":"comparableOperatingSystemVersion","abstract":"

    The version of the operating system on which the current process is executing.

    ","parent_name":"ProcessInfo"},"Extensions/Bundle.html#/s:So8NSBundleC19SwiftVersionCompareE05shortC0AC0C0VSgvp":{"name":"shortVersion","abstract":"

    The version of the current bundle.

    ","parent_name":"Bundle"},"Extensions/Bundle.html#/s:So8NSBundleC19SwiftVersionCompareE7versionAC0C0VSgvp":{"name":"version","abstract":"

    The full version of the current bundle.

    ","parent_name":"Bundle"},"Extensions/Bundle.html":{"name":"Bundle"},"Extensions/ProcessInfo.html":{"name":"ProcessInfo"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO5alphayA2CmF":{"name":"alpha","abstract":"

    Identifier displaying alpha.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO4betayA2CmF":{"name":"beta","abstract":"

    Identifier displaying beta.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO10prereleaseyA2CmF":{"name":"prerelease","abstract":"

    Identifier displaying prerelease.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO16releaseCandidateyA2CmF":{"name":"releaseCandidate","abstract":"

    Identifier displaying rc.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO12alphaNumericyACSScACmF":{"name":"alphaNumeric(_:)","abstract":"

    Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO7numericyACSucACmF":{"name":"numeric(_:)","abstract":"

    Numeric identifier are positive numbers and zeros, yet they do not allow for leading zeros.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO7unknownyA2CmF":{"name":"unknown","abstract":"

    Unknown identifier are used when string literals do not conform to SemVer and are removed.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO2eeoiySbAC_ACtFZ":{"name":"==(_:_:)","abstract":"

    Compares pre-release identifiers for equality.

    ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s25LosslessStringConvertiblePyxSgSScfc":{"name":"init(_:)","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s26ExpressibleByStringLiteralP06stringD0x0cD4TypeQz_tcfc":{"name":"init(stringLiteral:)","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s27ExpressibleByIntegerLiteralP07integerD0x0cD4TypeQz_tcfc":{"name":"init(integerLiteral:)","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO5valueSSvp":{"name":"value","abstract":"

    Undocumented

    ","parent_name":"PrereleaseIdentifier"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO12alphaNumericyACSScACmF":{"name":"alphaNumeric(_:)","abstract":"

    Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

    ","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO6digitsyACSScACmF":{"name":"digits(_:)","abstract":"

    Digit identifier are positive numbers and zeros, thus allowing leading zeros.

    ","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO7unknownyA2CmF":{"name":"unknown","abstract":"

    Unknown identifier are used when string literals do not conform to SemVer and are removed.

    ","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:s25LosslessStringConvertiblePyxSgSScfc":{"name":"init(_:)","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:s26ExpressibleByStringLiteralP06stringD0x0cD4TypeQz_tcfc":{"name":"init(stringLiteral:)","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO5valueSSvp":{"name":"value","abstract":"

    Undocumented

    ","parent_name":"BuildMetaData"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5majoryA2CmF":{"name":"major","abstract":"

    A MAJORupdate

    ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5minoryA2CmF":{"name":"minor","abstract":"

    A MINORupdate

    ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5patchyA2CmF":{"name":"patch","abstract":"

    A PATCHupdate

    ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO10prereleaseyA2CmF":{"name":"prerelease","abstract":"

    A pre-release update

    ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5buildyA2CmF":{"name":"build","abstract":"

    A build update

    ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO8noUpdateyA2CmF":{"name":"noUpdate","abstract":"

    The version is not an update (less or equal)

    ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html":{"name":"VersionCompareResult","abstract":"

    The severity of an update between versions.

    "},"Enums/BuildMetaData.html":{"name":"BuildMetaData","abstract":"

    Typed build-meta-data identifier.

    "},"Enums/PrereleaseIdentifier.html":{"name":"PrereleaseIdentifier","abstract":"

    Typed pre-release identifier.

    "},"Enums.html":{"name":"Enumerations","abstract":"

    The following enumerations are available globally.

    "},"Extensions.html":{"name":"Extensions","abstract":"

    The following extensions are available globally.

    "},"Protocols.html":{"name":"Protocols","abstract":"

    The following protocols are available globally.

    "},"Structs.html":{"name":"Structures","abstract":"

    The following structures are available globally.

    "}} \ No newline at end of file diff --git a/docs/docsets/.docset/Contents/Resources/Documents/undocumented.json b/docs/docsets/.docset/Contents/Resources/Documents/undocumented.json index 4314a61..ac7c16b 100644 --- a/docs/docsets/.docset/Contents/Resources/Documents/undocumented.json +++ b/docs/docsets/.docset/Contents/Resources/Documents/undocumented.json @@ -1,6 +1,19 @@ { "warnings": [ - + { + "file": "/Users/nihilias/Developer/Repositories/SwiftVersionCompare/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData.swift", + "line": 32, + "symbol": "BuildMetaData.value", + "symbol_kind": "source.lang.swift.decl.var.instance", + "warning": "undocumented" + }, + { + "file": "/Users/nihilias/Developer/Repositories/SwiftVersionCompare/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier.swift", + "line": 46, + "symbol": "PrereleaseIdentifier.value", + "symbol_kind": "source.lang.swift.decl.var.instance", + "warning": "undocumented" + } ], "source_directory": "/Users/nihilias/Developer/Repositories/SwiftVersionCompare" } \ No newline at end of file diff --git a/docs/docsets/.docset/Contents/Resources/docSet.dsidx b/docs/docsets/.docset/Contents/Resources/docSet.dsidx index 5e90a51d01722a62a1e8b066c50004d1fe234962..2ca71041bc1757179e1051a9da16a388caf6adf3 100644 GIT binary patch literal 28672 zcmeHPTWlLy8J@8{viKay(F79v7II(dN;aB@{ z!G%Zr54_X5YpcsE)KK!r?eMLubBOBvG`u)J4g(GY4g(GY4g(GY4g(GY4g(GY4g(GY z4g*g-1Gin??m!={Fk)^+*yMBR^?Xqh_+ol}4t?NGUQZ=%q{27n=dRsMh3DpHQm=%` zUEziKukIO!!9Xl^X<0y+nZca)1HO>CXQm=Dp z0}cZY0}cZY0}cZY0}cZY0}cZY0}cZY1AAhC?L|p_x>G<;G30Ge0-T#21{?+)1{?+) z1{?+)1{?+)1{?+)1{?+)1{?--40x0-_H00TixzXD+`lxb{Tp~mkk|7ooLnrWWoh`9 zP?W@cZfIT3X8MMu$>=$5LtK^BkCXXqfiDV?>Bz0EM3O5laV2goF~jj&i9{^2SQLsv zM&Ko3Zbit+;;JYV7iPIN{B?9>x+G>+0F9sFWgdMlr&rUg&;2*5pSt5_KgGt{Z!(|o z{GRz^$E?TY%~4;W-fN*L#WO_RX)XAUxlVdN>p$ZAxbM#$8|<&zf7nih{%mX&HK_b{2PX?gY~l9H1AA zc{!iXXS7=?|Hn67J_UjX>C~nyeo*2;yj!mzy|MWEC9qR_4nWOnH`_ z3Md=&IxnT}m-tL&9Ew6eFHNdTs*&Rrnb5GON0Tr%F<#=9H<#o~Az0=Efk!lq7+$LV z8=}14j24ZnfTIX7k%%lO$F2)fDI+hSWzaOT!%cJP|QS|(lGDC2Amqg@G#fVMOSc0L*-${?p#{xqK+J%D^cuov z=nMPC=dQ-q^gZfUC7ypAi5b1bXBOCCKylOO_e&9XHJZ_J-UaHaJET0MmyyM5xcZJ` z7%L-NE*$Z(RGYfs`k0f!UK$x9p~xdsSg~ZtHsLjPDaUpPl_bq)3hR6-BV@sp?_#+u zEsljx5XZ8&60v0V(mq#Q}n-(N#F1MPmEd9y_GMbgIaU=Vc=h&A*%9^U?(Ar-B zBMDu~t#MnDEM!&Pps~M$EYx}~A03(JbSOzv$0rqu#fhFXL7a&sl98Fnt#aXn5@1I{ z%9~^YXf96^?dLf>C5*ttq8~ra1OsteWrsLI1La#p>fEgb5swo*tN}f%=~fu&Bid+d?;B{? zF77;RhG+s0x1|=U4Lz&|YD`4j4VrORhXRyh_0t%;i)ierp|LKI_|?25L3y^ceYCbV zA=W~qMr9=aN{!L4L%gZdvryuiolhi}5=rnhB3sDly=*jkR%*f&C}I(x>}KFl3HdN{ zx@!uYNL`3o)ewe{@m!f%Mn-OsG}f>vEwzc|^wPPyq@`pfCYI4`3R%yl?X4mTwEk%{ z`7#>k!=}^7N_su>=iEKEH>gDE6>&|JrEMD1T(s$s)-Jss{@eDq{U5r%?U((BT?=jRv_qg1=`k1d>M}rk0Q@?W41kYKw};SOd8WLmiE-Z zrv+pHhH2~+*vb>}Gf>8>TyU$wjsc}%1n7~UQu~KJ5_|iHMUwux)czSz8rMG^@?mhV zKm)X9kvn8_|By(oR4!~F2#z*DG_Z3T>>zJQHbu*ySn3q-<>b1HHRx5U2$ zxi{E+!wo4E#WKWh`vxCZ1wcPxR|m^)QLeE|fk&#pho|o(UOJOl4^37r$>cKH3E4Mx z9LtVl*+lv1buiiGsOJCYcCi{(sR!ojeEp+6N-cf0R?b zEQJhxm7Q8UtEriW=>W*E?{4RnLt&Oe1ptEPQjyu!jMiD?{}oRUOQ8aQYCgUxt*OcX zEB<3Fg$e+Sx%j3u#U%f)1VSt|1&SQfzE4{IUpev|Pz415Pgee4ITBr`Tqw;Sqk=u`Gd;;FLq;m#=iXj;xj~|efj_SE|x+C z0Cwg775@>I0uS>cHo^_pQoE%`lw(gLCH^Q-HGmColipp}#XBe$HlMIvJSjaW%_DJYw={%>QRPSPB&Y)Mo3onPc`0NnhUp+gJ)kL%N1EDj2#0#XhJ2K$o}QeaPz1I4-ne|!M>bot-T~WHQzy^d&%A%L0P|Sn@J`y35a)gDo38mcXAUq+J+?x#1r3RyCr6x>M z0Q=4VD?Sg7QtodzaJJy@$(XIUF%828V`fV;^t*s7E`nk(T=t+~kz^NenZ_uC1|ww? zinb|+;{Sf?XH=)q+10Vp;cx$H`}Yb*Ou^aVhf7eOmQbwyPx*@vT7NhC4IUnCvEddEH>qI6V<3j_jd2pb`=JQZR} zg+S`TP6#BAK-@hK5KvvwsNxFw1?=p_v2~W3Rb0VOV!tnB;`i-b%Td4Yck3MX{SK>c zhwA(7EWMs;v-AWw|F9GrS{EXYPFEirT@372v?D~F7nbu=?wGCRXwp~!`Uvzh( zc+rv2u@Z2RMYjt`J!?;jVDVRs+koW=U!wH@_=ZT+^=4vOatX+~{bk-^H^*9?pLrOiRChZhPJZ?r-9+v=BI zf1ah#IgF+p!^jR`KPHLCyfHo0AEFxVXDB#D1tG;=4pBXSnxWw6WnCvP)2Hwb-9WjK z)nDRCmO|xUO{o4-f+tuCoglM3&ZR~h+U{93@Y;45jTF1td4O!bkD=h8t8M38m7~WY a{RSt}aJXYU7p8Tv5|1{Z$SrDpAnpI@Gz^*m delta 2344 zcmb7`Z%h+s9LJyMXrJrfJBuKkr7cjT{F&Oa7OBi>ts}2vE4q8i*wv-lxZ4S>@ z`}e}~+Y6VtnJx3(Hb{Ih&Lz7ym<5C@OcYsqYy%v^+`{pWPO(m>w4Hag}8z6oY;ed;b6Qb zB#cLMmMJL~p`?-HPi$v{&Iez)db(0hF^|S*~b7 z#}m-U!34dCb9*t5aRtL5!SO zfS-jo8k=zdsv9pFRHVWr9?wP}gXKoS=&)yEimfzeX0k|g0Z%MO$1qH~ZFn7=b%z+X zhgeJ^n|1(0&DMnut~i?#&+~zqNk;2O1Bqx)@d&9ki6vMViA5%+rP{}*g5dyMbeBt3 zoWq&B&hs;qI=u$nPekv*;pRcChKtRIl`4itXA{vk*ZW8D-rE9#N|xAt20f0b^}~H%5iI@tB}OLbun6x>ok&T45|gh&ahhMQ^unIT)#)R ztb19f(7vN>()_IHQ{Pwjs(x23NYzml_7kf~G+;?qvhKYRpFf>pp~JCiQBF?}Z0mTD zMdXN$JFUgBv=(dPk%c3^s-~6y4e^M_lP8?np?FIfbnd^6*TWqT$K>it7F%ncjVn2o zDWO&QiODF|<8UNp`55Jz^PJfm!jV1pl(TAZ9Jq}Op=0-2f#ln|l8{K*TETGemm0$e zDUriTGUR{9;!2vO{8hr8gTJbj%x z#}NIydbRF~u1EWu)~Cgq_ci;~H`Sl0pHY3KYNfBzVY-a`KweP(r97cnQtU0bUvQMV zLw!NLM%nN;SU?ZZ8OdGxvfGqMf=g~MR2Ui$wR1wb-pJxlQ*DL+|CNv z7jofpI2o#=f)-%H$7wS`GBeZ2JV{JSw9_;IosAr{JMBecX&FKCB(4lzY7otj9z8-89d%+cO^|#- zc;W+sD_fiYI3SD?DKhDcNtgdZzczz@UI}zBUl>y)EAGvDO{I_|f4W@q`6Ri~UHX2| sjdcok0 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
    uOtV`3nVUVTS7 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 Wr=L$hpMG}y`TqbyVY|)%R0aS~0m?Q2 diff --git a/docs/index.html b/docs/index.html index 37da10d..dc57a0c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -16,7 +16,7 @@
      -

      Docs (100% documented)

      +

      Docs (97% documented)

      @@ -38,7 +38,13 @@ Enumerations

      @@ -77,44 +83,35 @@

      SwiftVersionCheck

      -

      A small package for comparing and utilizing versions conforming to SemVer.

      - -

      Following features are and will be implemented:

      +

      platforms +languages +build +doccov +codecov

      -
        -
      • [x] Create a version from major, minor, patch and extension information.
      • -
      • [x] Create a version from string using LosslessStringConvertible or ExpressibleByStringLiteral .
      • -
      • [x] Compare versions using Equatable and Comparable with the known operators ==, ===, <, <=, > and >=.
      • -
      • [x] Compare versions and get the severity of the update (e. g. major-update).
      • -
      • [ ] Utilize ranges for a greater variaty of comparisons.
      • -
      • [x] Extend Bundle and ProcessInfo for easy usage.
      • -
      • [x] Open documentation.
      • -
      • [ ] Extend Codable and Hashable.
      • -
      +

      A small package introducing a Version object implementing the SemanticVersionComparable protocol for comparing versions conforming to SemVer.

      Installation

      Swift Package Manager:

      -
      package(url: https://github.com/nihilias/SwiftVersionCompare.git", from: "0.6.0"))
      +
      package(url: https://github.com/nihilias/SwiftVersionCompare.git", from: "1.0.0"))
       

      Usage

      -

      For detailed implenentation information see auto-generated documentation.

      -
      // use the version identifier for initialization
      +

      For detailed implenentation information see documentation.

      +
      // use the version core identifier for initialization
       let versionOne = Version(1, 0, 0)
       let versionTwo = Version(
           major: 1,
           minor: 0,
      -    patch: 0
      -)
      +    patch: 0,
      +    prerelease: [.alpha],
      +    build: ["1"]
      +) // -> prints: "1.0.0-alpha+1"
       
       // use strings
      -// use `ExpressibleByStringLiteral` with caution. it's fatal if the string is not a `SemVer` version
      -let versionThreeA: Version = "1.0.0" 
      -let versionThreeB: Version = Version("1.0.0")
      -
      -// using the optional type is safe
      -let versionFourA: Version? = "1.0.0"
      -let versionFourB: Version? = Version("1.0.0")
      +// use `ExpressibleByStringLiteral` with caution, because it's fatal if string is not `SemVer` version
      +let versionThreeA: Version? = "1.0.0" 
      +let versionThreeB: Version? = Version("1.0.0")
       
       // easy initial `0.0.0` version
       let initialVersion: Version = .initial
      @@ -127,20 +124,12 @@ 

      Usage

      if Version("1.0.0") > Version("0.4.0") { // ... } - -// compare versions and get update severity -let currentVersion = Version("0.6.0") -let newVersion = Version("1.0.0") - -if currentVersion.severity(to: newVersion) == .major { - // ... -}
      diff --git a/docs/search.json b/docs/search.json index 801d55b..fdbfb8f 100644 --- a/docs/search.json +++ b/docs/search.json @@ -1 +1 @@ -{"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10extensionsSaySSGSgvp":{"name":"extensions","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V7initialACvpZ":{"name":"initial","abstract":"

      An initial version representing the string 0.0.0.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSu_SuSgADSaySSGSgtcfc":{"name":"init(_:_:_:_:)","abstract":"

      Creates a new version.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V5major5minor5patch10extensionsACSu_SuSgAHSaySSGSgtcfc":{"name":"init(major:minor:patch:extensions:)","abstract":"

      Creates a new version.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSgSScfc":{"name":"init(_:)","abstract":"

      Creates a new version from a string.

      ","parent_name":"Version"},"Structs/Version.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V13stringLiteralACSS_tcfc":{"name":"init(stringLiteral:)","abstract":"

      Creates a new version from a string literal.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V19stringInterpolationACs013DefaultStringE0V_tcfc":{"name":"init(stringInterpolation:)","abstract":"

      Creates a new version from a string interpolation.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V14absoluteStringSSvp":{"name":"absoluteString","abstract":"

      The absolute string of the version.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V11versionCodeSSvp":{"name":"versionCode","abstract":"

      The string of the version representing MAJOR.MINOR.PATCH.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V9extensionSSSgvp":{"name":"extension","abstract":"

      The string of the version containing the extension.

      ","parent_name":"Version"},"Structs/Version.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"Version"},"Structs/Version.html":{"name":"Version","abstract":"

      A version type conforming to SemVer.

      "},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","abstract":"

      The MAJOR identifier of a version.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","abstract":"

      The MINOR identifier of a version

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","abstract":"

      The PATCH identifer of a verion.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10extensionsSaySSGSgvp":{"name":"extensions","abstract":"

      Contains strings with pre-release information.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL1loiySbx_xtFZ":{"name":"<(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2leoiySbx_xtFZ":{"name":"<=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL1goiySbx_xtFZ":{"name":">(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2geoiySbx_xtFZ":{"name":">=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE2eeoiySbx_xtFZ":{"name":"==(_:_:)","abstract":"

      Compares version objects for equality.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE3eeeoiySbx_xtFZ":{"name":"===(_:_:)","abstract":"

      Strictly compares version objects for equality.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE12isCompatible4withSbx_tF":{"name":"isCompatible(with:)","abstract":"

      A Boolean value indicating the compatibility of two versions.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE8severity2toAA14UpdateSeverityOx_tF":{"name":"severity(to:)","abstract":"

      Compare versions for their update severity.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html":{"name":"SemanticVersionComparable","abstract":"

      A type that can be expressed as a semantic version conforming to SemVer and compared using the relational operators ==, ===, <, <=, >=, and >.

      "},"Extensions/ProcessInfo.html#/s:So13NSProcessInfoC19SwiftVersionCompareE025comparableOperatingSystemD0AC0D0Vvp":{"name":"comparableOperatingSystemVersion","abstract":"

      The version of the operating system on which the current process is executing.

      ","parent_name":"ProcessInfo"},"Extensions/Bundle.html#/s:So8NSBundleC19SwiftVersionCompareE05shortC0AC0C0VSgvp":{"name":"shortVersion","abstract":"

      The version of the current bundle.

      ","parent_name":"Bundle"},"Extensions/Bundle.html":{"name":"Bundle"},"Extensions/ProcessInfo.html":{"name":"ProcessInfo"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO5majoryA2CmF":{"name":"major","abstract":"

      A MAJORupdate

      ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO5minoryA2CmF":{"name":"minor","abstract":"

      A MINORupdate

      ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO5patchyA2CmF":{"name":"patch","abstract":"

      A PATCHupdate

      ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO9extensionyA2CmF":{"name":"extension","abstract":"

      A pre-release update

      ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html#/s:19SwiftVersionCompare14UpdateSeverityO02noD0yA2CmF":{"name":"noUpdate","abstract":"

      The version is not an update (less or equal)

      ","parent_name":"UpdateSeverity"},"Enums/UpdateSeverity.html":{"name":"UpdateSeverity","abstract":"

      The severity of an update between versions.

      "},"Enums.html":{"name":"Enumerations","abstract":"

      The following enumerations are available globally.

      "},"Extensions.html":{"name":"Extensions","abstract":"

      The following extensions are available globally.

      "},"Protocols.html":{"name":"Protocols","abstract":"

      The following protocols are available globally.

      "},"Structs.html":{"name":"Structures","abstract":"

      The following structures are available globally.

      "}} \ No newline at end of file +{"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10prereleaseSayAA20PrereleaseIdentifierOGSgvp":{"name":"prerelease","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5buildSayAA13BuildMetaDataOGSgvp":{"name":"build","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSu_SuSgADSayAA20PrereleaseIdentifierOGSgSayAA13BuildMetaDataOGSgtcfc":{"name":"init(_:_:_:_:_:)","abstract":"

      Creates a new version.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V5major5minor5patch10prerelease5buildACSu_SuSgAISayAA20PrereleaseIdentifierOGSgSayAA13BuildMetaDataOGSgtcfc":{"name":"init(major:minor:patch:prerelease:build:)","abstract":"

      Creates a new version.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V7privateACSgSS_tcfc":{"name":"init(private:)","abstract":"

      Creates a new version using a string.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0VyACSgSScfc":{"name":"init(_:)","abstract":"

      Creates a new version from a string.

      ","parent_name":"Version"},"Structs/Version.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V13stringLiteralACSS_tcfc":{"name":"init(stringLiteral:)","abstract":"

      Creates a new version from a string literal.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V19stringInterpolationACs013DefaultStringE0V_tcfc":{"name":"init(stringInterpolation:)","abstract":"

      Creates a new version from a string interpolation.

      ","parent_name":"Version"},"Structs/Version.html#/s:19SwiftVersionCompare0B0V7initialACvpZ":{"name":"initial","abstract":"

      An initial version representing the string 0.0.0.

      ","parent_name":"Version"},"Structs/Version.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"Version"},"Structs/Version.html":{"name":"Version","abstract":"

      A version type conforming to SemVer.

      "},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5majorSuvp":{"name":"major","abstract":"

      The MAJOR identifier of a version.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5minorSuSgvp":{"name":"minor","abstract":"

      The MINOR identifier of a version

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5patchSuSgvp":{"name":"patch","abstract":"

      The PATCH identifer of a verion.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP10prereleaseSayAA20PrereleaseIdentifierOGSgvp":{"name":"prerelease","abstract":"

      Pre-release identifier of a version.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparableP5buildSayAA13BuildMetaDataOGSgvp":{"name":"build","abstract":"

      Build-meta-data of a version.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL1loiySbx_xtFZ":{"name":"<(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2leoiySbx_xtFZ":{"name":"<=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SL2geoiySbx_xtFZ":{"name":">=(_:_:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE2eeoiySbx_xtFZ":{"name":"==(_:_:)","abstract":"

      Compares version objects for equality.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE3eeeoiySbx_xtFZ":{"name":"===(_:_:)","abstract":"

      Strictly compares version objects for equality.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:SH4hash4intoys6HasherVz_tF":{"name":"hash(into:)","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE12isCompatible4withSbx_tF":{"name":"isCompatible(with:)","abstract":"

      A Boolean value indicating the compatibility of two versions.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE7compare4withAA0bC6ResultOx_tF":{"name":"compare(with:)","abstract":"

      Compare versions for their update severity.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE08hasEqualB4Core2asSbx_tF":{"name":"hasEqualVersionCore(as:)","abstract":"

      Check if a version has an equal version core as another version.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE14absoluteStringSSvp":{"name":"absoluteString","abstract":"

      The absolute string of the version.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE10coreStringSSvp":{"name":"coreString","abstract":"

      The string of the version representing MAJOR.MINOR.PATCH.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE15extensionStringSSSgvp":{"name":"extensionString","abstract":"

      The string of the version representing the pre-release identifier and build-meta-data.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE26prereleaseIdentifierStringSSSgvp":{"name":"prereleaseIdentifierString","abstract":"

      The pre-release identifier as a string if available.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html#/s:19SwiftVersionCompare08SemanticB10ComparablePAAE19buildMetaDataStringSSSgvp":{"name":"buildMetaDataString","abstract":"

      The build meta data as a string if available.

      ","parent_name":"SemanticVersionComparable"},"Protocols/SemanticVersionComparable.html":{"name":"SemanticVersionComparable","abstract":"

      A type that can be expressed as a semantic version conforming to SemVer.

      "},"Extensions/ProcessInfo.html#/s:So13NSProcessInfoC19SwiftVersionCompareE025comparableOperatingSystemD0AC0D0Vvp":{"name":"comparableOperatingSystemVersion","abstract":"

      The version of the operating system on which the current process is executing.

      ","parent_name":"ProcessInfo"},"Extensions/Bundle.html#/s:So8NSBundleC19SwiftVersionCompareE05shortC0AC0C0VSgvp":{"name":"shortVersion","abstract":"

      The version of the current bundle.

      ","parent_name":"Bundle"},"Extensions/Bundle.html#/s:So8NSBundleC19SwiftVersionCompareE7versionAC0C0VSgvp":{"name":"version","abstract":"

      The full version of the current bundle.

      ","parent_name":"Bundle"},"Extensions/Bundle.html":{"name":"Bundle"},"Extensions/ProcessInfo.html":{"name":"ProcessInfo"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO5alphayA2CmF":{"name":"alpha","abstract":"

      Identifier displaying alpha.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO4betayA2CmF":{"name":"beta","abstract":"

      Identifier displaying beta.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO10prereleaseyA2CmF":{"name":"prerelease","abstract":"

      Identifier displaying prerelease.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO16releaseCandidateyA2CmF":{"name":"releaseCandidate","abstract":"

      Identifier displaying rc.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO12alphaNumericyACSScACmF":{"name":"alphaNumeric(_:)","abstract":"

      Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO7numericyACSucACmF":{"name":"numeric(_:)","abstract":"

      Numeric identifier are positive numbers and zeros, yet they do not allow for leading zeros.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO7unknownyA2CmF":{"name":"unknown","abstract":"

      Unknown identifier are used when string literals do not conform to SemVer and are removed.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO2eeoiySbAC_ACtFZ":{"name":"==(_:_:)","abstract":"

      Compares pre-release identifiers for equality.

      ","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s25LosslessStringConvertiblePyxSgSScfc":{"name":"init(_:)","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s26ExpressibleByStringLiteralP06stringD0x0cD4TypeQz_tcfc":{"name":"init(stringLiteral:)","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:s27ExpressibleByIntegerLiteralP07integerD0x0cD4TypeQz_tcfc":{"name":"init(integerLiteral:)","parent_name":"PrereleaseIdentifier"},"Enums/PrereleaseIdentifier.html#/s:19SwiftVersionCompare20PrereleaseIdentifierO5valueSSvp":{"name":"value","abstract":"

      Undocumented

      ","parent_name":"PrereleaseIdentifier"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO12alphaNumericyACSScACmF":{"name":"alphaNumeric(_:)","abstract":"

      Alphanumeric identifier are lower- and uppercased letters and numbers from 0-9.

      ","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO6digitsyACSScACmF":{"name":"digits(_:)","abstract":"

      Digit identifier are positive numbers and zeros, thus allowing leading zeros.

      ","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO7unknownyA2CmF":{"name":"unknown","abstract":"

      Unknown identifier are used when string literals do not conform to SemVer and are removed.

      ","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:s25LosslessStringConvertiblePyxSgSScfc":{"name":"init(_:)","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:s26ExpressibleByStringLiteralP06stringD0x0cD4TypeQz_tcfc":{"name":"init(stringLiteral:)","parent_name":"BuildMetaData"},"Enums/BuildMetaData.html#/s:19SwiftVersionCompare13BuildMetaDataO5valueSSvp":{"name":"value","abstract":"

      Undocumented

      ","parent_name":"BuildMetaData"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5majoryA2CmF":{"name":"major","abstract":"

      A MAJORupdate

      ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5minoryA2CmF":{"name":"minor","abstract":"

      A MINORupdate

      ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5patchyA2CmF":{"name":"patch","abstract":"

      A PATCHupdate

      ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO10prereleaseyA2CmF":{"name":"prerelease","abstract":"

      A pre-release update

      ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO5buildyA2CmF":{"name":"build","abstract":"

      A build update

      ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html#/s:19SwiftVersionCompare0bC6ResultO8noUpdateyA2CmF":{"name":"noUpdate","abstract":"

      The version is not an update (less or equal)

      ","parent_name":"VersionCompareResult"},"Enums/VersionCompareResult.html":{"name":"VersionCompareResult","abstract":"

      The severity of an update between versions.

      "},"Enums/BuildMetaData.html":{"name":"BuildMetaData","abstract":"

      Typed build-meta-data identifier.

      "},"Enums/PrereleaseIdentifier.html":{"name":"PrereleaseIdentifier","abstract":"

      Typed pre-release identifier.

      "},"Enums.html":{"name":"Enumerations","abstract":"

      The following enumerations are available globally.

      "},"Extensions.html":{"name":"Extensions","abstract":"

      The following extensions are available globally.

      "},"Protocols.html":{"name":"Protocols","abstract":"

      The following protocols are available globally.

      "},"Structs.html":{"name":"Structures","abstract":"

      The following structures are available globally.

      "}} \ No newline at end of file diff --git a/docs/undocumented.json b/docs/undocumented.json index 4314a61..77f0725 100644 --- a/docs/undocumented.json +++ b/docs/undocumented.json @@ -1,6 +1,19 @@ { "warnings": [ - + { + "file": "/Users/nihilias/Developer/Repositories/SwiftVersionCompare/Sources/SwiftVersionCompare/SemanticVersionComparable/BuildMetaData/BuildMetaData.swift", + "line": 35, + "symbol": "BuildMetaData.value", + "symbol_kind": "source.lang.swift.decl.var.instance", + "warning": "undocumented" + }, + { + "file": "/Users/nihilias/Developer/Repositories/SwiftVersionCompare/Sources/SwiftVersionCompare/SemanticVersionComparable/PrereleaseIdentifier/PrereleaseIdentifier.swift", + "line": 49, + "symbol": "PrereleaseIdentifier.value", + "symbol_kind": "source.lang.swift.decl.var.instance", + "warning": "undocumented" + } ], "source_directory": "/Users/nihilias/Developer/Repositories/SwiftVersionCompare" } \ No newline at end of file
    + + string + + +
    +

    The string representing a version.