Skip to content

Commit

Permalink
Merge pull request #12 from scottrhoyt/swift3
Browse files Browse the repository at this point in the history
Swift 3.0 Support
  • Loading branch information
scottrhoyt authored Sep 14, 2016
2 parents 0203ebe + a01daba commit 964f692
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 121 deletions.
15 changes: 4 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ matrix:
- script: set -o pipefail && xcodebuild -scheme SwiftyTextTable -project SwiftyTextTable.xcodeproj clean build test | xcpretty
env: JOB=Xcode
os: osx
osx_image: xcode7.3
osx_image: xcode8
language: objective-c
before_install:
- ./scripts/upstall-carthage.sh
Expand All @@ -18,22 +18,15 @@ matrix:
before_deploy:
- carthage build --no-skip-current
- carthage archive $FRAMEWORK_NAME
- script: set -o pipefail && xcodebuild -scheme SwiftyTextTable -project SwiftyTextTable.xcodeproj clean build test | xcpretty
env: JOB=Xcode8
os: osx
osx_image: xcode8
language: objective-c
after_success:
- bash <(curl -s https://codecov.io/bash)
- script:
- TOOLCHAINS=swift swift build
- TOOLCHAINS=swift swift test
env: JOB=SPM
os: osx
osx_image: xcode7.3
osx_image: xcode8
language: objective-c
before_install:
- export SWIFT_SNAPSHOT=swift-DEVELOPMENT-SNAPSHOT-2016-03-24-a
- export SWIFT_SNAPSHOT=swift-DEVELOPMENT-SNAPSHOT-2016-09-07-a
- curl https://swift.org/builds/development/xcode/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-osx.pkg -o swift.pkg
- sudo installer -pkg swift.pkg -target /
- script:
Expand All @@ -47,7 +40,7 @@ matrix:
- wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import -
- cd ..
- gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
- export SWIFT_SNAPSHOT=swift-DEVELOPMENT-SNAPSHOT-2016-03-24-a
- export SWIFT_SNAPSHOT=swift-DEVELOPMENT-SNAPSHOT-2016-09-07-a
- export SWIFT_URL=https://swift.org/builds/development/ubuntu1404/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-ubuntu14.04.tar.gz
- wget $SWIFT_URL
- wget $SWIFT_URL.sig
Expand Down
21 changes: 19 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,29 @@

##### Breaking

* `SwiftyTextTable` adopts the new Swift 3.0 convention of explicit first
parameter labels for functions.
* Linux support for dealing with console formatting escape sequences has been
removed for the time being due to regular expression portability problems.

##### Enhancements

* Swift 3.0 support!

##### Bug Fixes

* None

## 0.3.1: Swift 2.3 Support

##### Breaking

* None

##### Enhancements

* SwiftyTextTable is now compatible with both Swift 2.2 and Swift 3.0 on OS X
and Linux thanks to the great work of [Norio Nomura](https://github.com/norio-nomura).
* SwiftyTextTable is now compatible with Swift 2.3 on OS X and Linux thanks to
the great work of [Norio Nomura](https://github.com/norio-nomura).

##### Bug Fixes

Expand Down
23 changes: 11 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,12 @@ A lightweight Swift library for generating text tables.
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)
![Platform OS X + Linux](https://img.shields.io/badge/Platform-OS%20X%20%2B%20Linux-blue.svg)
[![Language Swift 2.3](https://img.shields.io/badge/Language-Swift%202.3-orange.svg)](https://swift.org)
[![Language Swift 3.0](https://img.shields.io/badge/Language-Swift%203.0-orange.svg)](https://swift.org)

## Swift 3.0
## Swift Language Support

Currently Swift 3.0 support is a work in progress. The library is stable under
OS X using Xcode 8 or SPM, but not Linux. To access Swift 3.0 support use the
branch `swift3`.

The Swift 3.0 implementation is not backwards compatible with Swift < 3.0 and
introduces breaking changes due to explicit first parameter labels for
functions.

SwiftyTextTable 0.4.0 will introduce Swift 3.0 support. To prevent problems in
codebases not yet updated to Swift 3.0, pin your version to `0.3.1`.
`SwiftyTextTable` is now Swift 3.0 compatible! The last release to support Swift
2.3 was [0.3.1](https://github.com/scottrhoyt/SwiftyTextTable/releases/tag/0.3.1).

## Installation

Expand Down Expand Up @@ -142,6 +134,13 @@ print(tableString)
*/
```

#### Console Formatting Support
*Not currently available in Linux.*

`SwiftyTextTable` will recognize many console escape sequences used to format
output (e.g. [Rainbow](https://github.com/onevcat/Rainbow)) and account for them
in constructing the table.

### Creating Tables from Arrays of Objects with `TextTableObject`

Let's say you have an array of objects that looks this:
Expand Down
110 changes: 39 additions & 71 deletions Source/SwiftyTextTable/TextTable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,35 @@
import Foundation

// MARK: Console Escape Stripping
private let strippingPattern = "(?:\u{001B}\\[(?:[0-9]|;)+m)*(.*?)(?:\u{001B}\\[0m)+"

// We can safely force try this regex because the pattern has be tested to work.
// swiftlint:disable:next force_try
private let strippingRegex = try! NSRegularExpression(pattern: strippingPattern, options: [])

// MARK: - TextTable Protocols

public protocol TextTableObject {
static var tableHeaders: [String] { get }
var tableValues: [CustomStringConvertible] { get }
}

extension String: CustomStringConvertible {
public var description: String {
return self
// Because of an error using the Linux implementation of Foundation's RegularExpression,
// escape stripping is only available on Apple platforms
#if os(Linux)
private extension String {
func stripped() -> String {
return self
}
}
}
#else
private let strippingPattern = "(?:\u{001B}\\[(?:[0-9]|;)+m)*(.*?)(?:\u{001B}\\[0m)+"

// We can safely force try this regex because the pattern has be tested to work.
// swiftlint:disable:next force_try
private let strippingRegex = try! NSRegularExpression(pattern: strippingPattern, options: [])

private extension String {
func stripped() -> String {
let matches = strippingRegex
.matches(in: self, options: [], range: NSRange(location: 0, length: self.characters.count))
.map {
NSString(string: self).substring(with: $0.rangeAt(1))
}
return matches.isEmpty ? self : matches.joined(separator: "")
}
}
#endif

private extension String {
private func withPadding(count: Int) -> String {
func withPadding(count: Int) -> String {
let length = characters.count
if length < count {
return self +
Expand All @@ -38,27 +46,25 @@ private extension String {
return self
}

func stripped() -> String {
let matches = strippingRegex
.matches(in: self, options: [], range: NSRange(location: 0, length: self.characters.count))
.map {
NSString(string: self).substring(with: $0.range(at: 1))
}
return matches.isEmpty ? self : matches.joined(separator: "")
}

func strippedLength() -> Int {
return stripped().characters.count
}
}

// MARK: - TextTable Protocols

public protocol TextTableObject {
static var tableHeaders: [String] { get }
var tableValues: [CustomStringConvertible] { get }
}

private func fence(strings: [String], separator: String) -> String {
return separator + strings.joined(separator: separator) + separator
}

public struct TextTableColumn {
public var header: String
private var values: [String] = []
fileprivate var values: [String] = []

public init(header: String) {
self.header = header
Expand All @@ -80,8 +86,8 @@ public struct TextTable {
}

public init<T: TextTableObject>(objects: [T]) {
columns = objects.isEmpty ? [] : objects[0].dynamicType.tableHeaders.map { TextTableColumn(header: $0) }
objects.forEach { addRow($0.tableValues) }
columns = objects.isEmpty ? [] : type(of: objects[0]).tableHeaders.map { TextTableColumn(header: $0) }
objects.forEach { addRow(values: $0.tableValues) }
}

public mutating func addRow(values: [CustomStringConvertible]) {
Expand All @@ -96,51 +102,13 @@ public struct TextTable {
}

public func render() -> String {
let separator = fence(columns.map({ column in
let separator = fence(strings: columns.map({ column in
return repeatElement(rowFence, count: column.width + 2).joined(separator: "")
}), separator: cornerFence)
let header = fence(columns.map({ " \($0.header.withPadding($0.width)) " }), separator: columnFence)
let header = fence(strings: columns.map({ " \($0.header.withPadding(count: $0.width)) " }), separator: columnFence)
let values = columns.isEmpty ? "" : (0..<columns.first!.values.count).map({ rowIndex in
fence(columns.map({ " \($0.values[rowIndex].withPadding($0.width)) " }), separator: columnFence)
fence(strings: columns.map({ " \($0.values[rowIndex].withPadding(count: $0.width)) " }), separator: columnFence)
}).joined(separator: "\n")
return [separator, header, separator, values, separator].joined(separator: "\n")
}
}

#if !swift(>=3)
internal func repeatElement<T>(element: T, count: Int) -> Repeat<T> {
return Repeat(count: count, repeatedValue: element)
}

extension SequenceType where Generator.Element == String {
internal func joined(separator separator: String) -> String {
return joinWithSeparator(separator)
}
}

extension Array {
internal init(repeating repeatedValue: Element, count: Int) {
self.init(count: count, repeatedValue: repeatedValue)
}
}
#endif

#if !swift(>=3) || os(Linux)
extension NSString {
internal func substring(with range: NSRange) -> String {
return substringWithRange(range)
}
}

extension NSRegularExpression {
internal func matches(in string: String, options: NSMatchingOptions = [], range: NSRange) -> [NSTextCheckingResult] {
return matchesInString(string, options: options, range: range)
}
}

extension NSTextCheckingResult {
internal func range(at idx: Int) -> NSRange {
return rangeAtIndex(idx)
}
}
#endif
13 changes: 8 additions & 5 deletions SwiftyTextTable.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
3B5BDCF51C63133100592068 /* SwiftyTextTableTests.swift */,
);
name = SwiftyTextTableTests;
path = Tests/SwiftyTextTable;
path = Tests/SwiftyTextTableTests;
sourceTree = "<group>";
};
3B5BDD031C631E6200592068 /* Supporting Files */ = {
Expand Down Expand Up @@ -174,6 +174,7 @@
};
3B5BDCEF1C63133100592068 = {
CreatedOnToolsVersion = 7.1.1;
LastSwiftMigration = 0800;
};
};
};
Expand Down Expand Up @@ -301,7 +302,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
Expand Down Expand Up @@ -344,7 +345,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
Expand All @@ -369,6 +370,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -390,14 +392,15 @@
PRODUCT_BUNDLE_IDENTIFIER = com.scotthoyt.SwiftyTextTable;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
3B5BDCFE1C63133100592068 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Tests/SwiftyTextTable/Supporting Files/Info.plist";
INFOPLIST_FILE = "Tests/SwiftyTextTableTests/Supporting Files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.scotthoyt.SwiftyTextTableTests;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -408,7 +411,7 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Tests/SwiftyTextTable/Supporting Files/Info.plist";
INFOPLIST_FILE = "Tests/SwiftyTextTableTests/Supporting Files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.scotthoyt.SwiftyTextTableTests;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
2 changes: 1 addition & 1 deletion Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import XCTest

@testable import SwiftyTextTableTestSuite
@testable import SwiftyTextTableTests

XCTMain([
testCase(SwiftyTextTableTests.allTests),
Expand Down
Loading

0 comments on commit 964f692

Please sign in to comment.