[ADD] modern ‘setup’ script

This commit is contained in:
Maxim Khatskevich 2019-07-11 22:57:53 +02:00
parent d609e89b2d
commit e6650c5ea6
9 changed files with 368 additions and 73 deletions

95
.gitignore vendored
View File

@ -1,11 +1,12 @@
# Created by https://www.gitignore.io/api/macos
# ==========
### macOS ### ### macOS ###
*.DS_Store *.DS_Store
.AppleDouble .AppleDouble
.LSOverride .LSOverride
# Icon must end with two \r # Icon must end with two
Icon Icon
# Thumbnails # Thumbnails
@ -27,50 +28,16 @@ Network Trash Folder
Temporary Items Temporary Items
.apdisk .apdisk
# End of https://www.gitignore.io/api/macos ### macOS ###
# =========================== # ==========
# #
# #
# #
# Created by https://www.gitignore.io/api/cocoapods # ==========
### Cocoa ###
### CocoaPods ###
## CocoaPods GitIgnore Template
# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
# - Also handy if you have a lage number of dependant pods
# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGONRE THE LOCK FILE
Pods/
# End of https://www.gitignore.io/api/cocoapods
# ===========================
#
#
#
# Created by https://www.gitignore.io/api/carthage
### Carthage ###
# Carthage
# Add this line if you want to avoid checking in source code from Carthage dependencies.
Carthage/Checkouts
Carthage/Build
# End of https://www.gitignore.io/api/carthage
# ===========================
#
#
#
# Created by https://www.gitignore.io/api/swift
### Swift ###
# Xcode # Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated ## Build generated
build/ build/
@ -102,32 +69,34 @@ xcuserdata/
timeline.xctimeline timeline.xctimeline
playground.xcworkspace playground.xcworkspace
# Swift Package Manager ### Cocoa ###
# ==========
# #
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. #
# Packages/ #
# Package.pins
# ==========
### Swift Package Manager ###
#
Packages/
Package.pins
.build/ .build/
# CocoaPods - Refactored to standalone file ### Swift Package Manager ###
# ==========
# Carthage - Refactored to standalone file
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/README.md
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
# End of https://www.gitignore.io/api/swift
# ===========================
# #
# #
# #
# ==========
### Custom repo-specific ###
# we don't need to store project file,
# as we generate it on-demand
*.xcodeproj
### Custom repo-specific ###
# ==========
#
#
#

4
.setup/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.DS_Store
/.build
/Packages
/*.xcodeproj

52
.setup/Package.resolved Normal file
View File

@ -0,0 +1,52 @@
{
"object": {
"pins": [
{
"package": "PathKit",
"repositoryURL": "https://github.com/kylef/PathKit",
"state": {
"branch": null,
"revision": "73f8e9dca9b7a3078cb79128217dc8f2e585a511",
"version": "1.0.0"
}
},
{
"package": "XCERepoConfigurator",
"repositoryURL": "https://github.com/XCEssentials/RepoConfigurator",
"state": {
"branch": null,
"revision": "c8635818ec6cb096944d42db855ded210b1b1cbe",
"version": "2.7.3"
}
},
{
"package": "Spectre",
"repositoryURL": "https://github.com/kylef/Spectre.git",
"state": {
"branch": null,
"revision": "f14ff47f45642aa5703900980b014c2e9394b6e5",
"version": "0.9.0"
}
},
{
"package": "SwiftHamcrest",
"repositoryURL": "https://github.com/nschum/SwiftHamcrest",
"state": {
"branch": null,
"revision": "034159ba9ac342372e3af119e7d80f38b5014782",
"version": "2.1.1"
}
},
{
"package": "Version",
"repositoryURL": "https://github.com/mxcl/Version.git",
"state": {
"branch": null,
"revision": "682f0da36005924672506b96fac93269831004b7",
"version": "1.1.1"
}
}
]
},
"version": 1
}

20
.setup/Package.swift Normal file
View File

@ -0,0 +1,20 @@
// swift-tools-version:4.2
// Managed by ice
import PackageDescription
let package = Package(
name: "ValidatableValueSetup",
dependencies: [
.package(url: "https://github.com/kylef/PathKit", from: "1.0.0"),
.package(url: "https://github.com/XCEssentials/RepoConfigurator", from: "2.7.0")
],
targets: [
.target(
name: "ValidatableValueSetup",
dependencies: ["XCERepoConfigurator", "PathKit"],
path: ".",
sources: ["main.swift"]
)
]
)

212
.setup/main.swift Normal file
View File

@ -0,0 +1,212 @@
import PathKit
import XCERepoConfigurator
// MARK: - PRE-script invocation output
print("\n")
print("--- BEGIN of '\(Executable.name)' script ---")
// MARK: -
// MARK: Parameters
Spec.BuildSettings.swiftVersion.value = "5.0"
let swiftLangVersions = "[.v5]"
let localRepo = try Spec.LocalRepo.current()
let remoteRepo = try Spec.RemoteRepo(
accountName: localRepo.context,
name: localRepo.name
)
let travisCI = (
address: "https://travis-ci.com/\(remoteRepo.accountName)/\(remoteRepo.name)",
branch: "master"
)
let company = (
prefix: "XCE",
name: remoteRepo.accountName
)
let project = (
name: remoteRepo.name,
summary: "Generic value wrapper with built-in validation",
copyrightYear: 2016
)
let productName = company.prefix + project.name
let authors = [
("Maxim Khatskevich", "maxim@khatskevi.ch")
]
typealias PerSubSpec<T> = (
core: T,
tests: T
)
let subSpecs: PerSubSpec = (
"Core",
"AllTests"
)
let targetNames: PerSubSpec = (
productName,
productName + subSpecs.tests
)
let sourcesLocations: PerSubSpec = (
Spec.Locations.sources + subSpecs.core,
Spec.Locations.tests + subSpecs.tests
)
let dummyFiles = [
sourcesLocations.core + "\(subSpecs.core).swift",
sourcesLocations.tests + "\(subSpecs.tests).swift"
]
// MARK: Parameters - Summary
localRepo.report()
remoteRepo.report()
// MARK: -
// MARK: Write - Dummy files
try dummyFiles
.forEach{
try CustomTextFile
.init(
"//"
)
.prepare(
at: $0
)
.writeToFileSystem(
ifFileExists: .skip
)
}
// MARK: Write - ReadMe
try ReadMe()
.addGitHubLicenseBadge(
account: company.name,
repo: project.name
)
.addGitHubTagBadge(
account: company.name,
repo: project.name
)
.addSwiftPMCompatibleBadge()
.addCarthageCompatibleBadge()
.addWrittenInSwiftBadge(
version: Spec.BuildSettings.swiftVersion.value
)
.addStaticShieldsBadge(
"platforms",
status: "macOS | iOS | tvOS | watchOS | Linux",
color: "blue",
title: "Supported platforms",
link: "Package.swift"
)
.add("""
[![Build Status](\(travisCI.address).svg?branch=\(travisCI.branch))](\(travisCI.address))
"""
)
.add("""
# \(project.name)
\(project.summary)
"""
)
.prepare(
removeRepeatingEmptyLines: false
)
.writeToFileSystem(
ifFileExists: .skip
)
// MARK: Write - License
try License
.MIT(
copyrightYear: UInt(project.copyrightYear),
copyrightEntity: authors.map{ $0.0 }.joined(separator: ", ")
)
.prepare()
.writeToFileSystem()
// MARK: Write - GitHub - PagesConfig
try GitHub
.PagesConfig()
.prepare()
.writeToFileSystem()
// MARK: Write - Git - .gitignore
try Git
.RepoIgnore()
.addMacOSSection()
.addCocoaSection()
.addSwiftPackageManagerSection(ignoreSources: true)
.add(
"""
# we don't need to store project file,
# as we generate it on-demand
*.\(Xcode.Project.extension)
"""
)
.prepare()
.writeToFileSystem()
// MARK: Write - Package.swift
try CustomTextFile("""
// swift-tools-version:\(Spec.BuildSettings.swiftVersion.value)
import PackageDescription
let package = Package(
name: "\(productName)",
products: [
.library(
name: "\(productName)",
targets: [
"\(targetNames.core)"
]
)
],
targets: [
.target(
name: "\(targetNames.core)",
path: "\(sourcesLocations.core)"
),
.testTarget(
name: "\(targetNames.tests)",
dependencies: [
"\(targetNames.core)"
],
path: "\(sourcesLocations.tests)"
),
],
swiftLanguageVersions: \(swiftLangVersions)
)
"""
)
.prepare(
at: ["Package.swift"]
)
.writeToFileSystem()
// MARK: - POST-script invocation output
print("--- END of '\(Executable.name)' script ---")

29
Package.swift Normal file
View File

@ -0,0 +1,29 @@
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "XCEValidatableValue",
products: [
.library(
name: "XCEValidatableValue",
targets: [
"XCEValidatableValue"
]
)
],
targets: [
.target(
name: "XCEValidatableValue",
path: "Sources/Core"
),
.testTarget(
name: "XCEValidatableValueAllTests",
dependencies: [
"XCEValidatableValue"
],
path: "Tests/AllTests"
),
],
swiftLanguageVersions: [.v5]
)

View File

@ -1,9 +1,16 @@
[![license](https://img.shields.io/github/license/XCEssentials/ValidatableValue.svg)](https://opensource.org/licenses/MIT) [![GitHub License](https://img.shields.io/github/license/XCEssentials/ValidatableValue.svg?longCache=true)](LICENSE)
[![GitHub tag](https://img.shields.io/github/tag/XCEssentials/ValidatableValue.svg)](https://cocoapods.org/?q=XCERequirement) [![GitHub Tag](https://img.shields.io/github/tag/XCEssentials/ValidatableValue.svg?longCache=true)](https://github.com/XCEssentials/ValidatableValue/tags)
[![CocoaPods](https://img.shields.io/cocoapods/v/XCEValidatableValue.svg)](https://cocoapods.org/?q=XCERequirement) [![Swift Package Manager Compatible](https://img.shields.io/badge/SPM-compatible-brightgreen.svg?longCache=true)](Package.swift)
[![CocoaPods](https://img.shields.io/cocoapods/p/XCEValidatableValue.svg)](https://cocoapods.org/?q=XCEUniFlow) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-brightgreen.svg?longCache=true)](https://github.com/Carthage/Carthage)
[![Written in Swift](https://img.shields.io/badge/Swift-5.0-orange.svg?longCache=true)](https://swift.org)
[![Supported platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20tvOS%20%7C%20watchOS%20%7C%20Linux-blue.svg?longCache=true)](Package.swift)
[![Build Status](https://travis-ci.com/XCEssentials/ValidatableValue.svg?branch=master)](https://travis-ci.com/XCEssentials/ValidatableValue)
# Problem # ValidatableValue
Generic value wrapper with built-in validation
## Problem
Every app has [data model](https://en.wikipedia.org/wiki/Data_model). A data model is usually implemented in the form of a custom composite [data type](https://en.wikipedia.org/wiki/Data_type) that stores one or more [properties](https://en.wikipedia.org/wiki/Property_(programming)). Ideally, the type of each property (no matter if it's atomic or composite) defines desired set of all possible values for this property. Plus, there are might be special rules that may define whatever any given value is acceptable for the property or not. Every app has [data model](https://en.wikipedia.org/wiki/Data_model). A data model is usually implemented in the form of a custom composite [data type](https://en.wikipedia.org/wiki/Data_type) that stores one or more [properties](https://en.wikipedia.org/wiki/Property_(programming)). Ideally, the type of each property (no matter if it's atomic or composite) defines desired set of all possible values for this property. Plus, there are might be special rules that may define whatever any given value is acceptable for the property or not.
@ -11,22 +18,22 @@ Swift has no built-in mechanizm of how to narrow-down set of allowed values with
For example, to limit a vlaue to just integer numbers in the range from 1 to 100 and avoid all odd numbers within this range we usually use just Integer, and then somehow later implement the needed checks before actually put a value in this property. That leads to distribution of single portion of business logic (requirements for this particualr property) across at least two (sometimes more) places in the codebase. For example, to limit a vlaue to just integer numbers in the range from 1 to 100 and avoid all odd numbers within this range we usually use just Integer, and then somehow later implement the needed checks before actually put a value in this property. That leads to distribution of single portion of business logic (requirements for this particualr property) across at least two (sometimes more) places in the codebase.
# Wishlist ## Wishlist
1. concise inline definition of value validation logic; 1. concise inline definition of value validation logic;
2. safe value validation before actually writing it into property; 2. safe value validation before actually writing it into property;
3. combination of several requirements together to create composite requirement that defines custom allowed values set; 3. combination of several requirements together to create composite requirement that defines custom allowed values set;
4. eliminate any side effects by making validation logic to be written as pure function. 4. eliminate any side effects by making validation logic to be written as pure function.
# How to install ## How to install
The recommended way is to install using [CocoaPods](https://cocoapods.org/?q=XCEValidatableValue). The recommended way is to install using [CocoaPods](https://cocoapods.org/?q=XCEValidatableValue).
# How it works ## How it works
The `ValidatableValue` data type represents a value that can be validated against custom rules/requirements. It also relies on `Value` generic type that represents base data type for potential value (one of the standard system data types or any custom one). The validation logic must be supplied as input parameter to the constructor in form of set of [Requirement](https://github.com/XCEssentials/Requirement) instances (might be empty in an edge case when any value of the base type is fine). There are several ways of creating a validatable value, see below. The `ValidatableValue` data type represents a value that can be validated against custom rules/requirements. It also relies on `Value` generic type that represents base data type for potential value (one of the standard system data types or any custom one). The validation logic must be supplied as input parameter to the constructor in form of set of [Requirement](https://github.com/XCEssentials/Requirement) instances (might be empty in an edge case when any value of the base type is fine). There are several ways of creating a validatable value, see below.
# How to use ## How to use
Assume we need to define a basic data model for representing user in our app. Assume we need to define a basic data model for representing user in our app.
@ -131,4 +138,4 @@ let newVal: Any = //...
try u.firstName.setValue(newVal) try u.firstName.setValue(newVal)
``` ```
See full example in [unit tests](https://github.com/XCEssentials/ValidatableValue/tree/master/Tst). See full example in [unit tests](https://github.com/XCEssentials/ValidatableValue/tree/master/Tst).

1
Sources/Core/Core.swift Normal file
View File

@ -0,0 +1 @@
//

View File

@ -0,0 +1 @@
//