Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ If needed, pluralize to `Tasks`, `PRs` or `Authors` and list multiple entries se
### Added
- Added new `repeatIfAutoCorrected` option to `checkFileContents` method to repeat the check if last run did any auto-corrections.
Issue: [#29](https://github.com/Flinesoft/AnyLint/issues/29) | PR: [#31](https://github.com/Flinesoft/AnyLint/pull/31) | Author: [Cihat Gündüz](https://github.com/Jeehut)
- Added new Regex Cheat Sheet section to README including a tip on how to workaround the pointer issue.
Issue: [#3](https://github.com/Flinesoft/AnyLint/issues/3) | PR: [#32](https://github.com/Flinesoft/AnyLint/pull/32) | Author: [Cihat Gündüz](https://github.com/Jeehut)
### Changed
- None.
### Deprecated
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,25 @@ Next, make sure the AnyLint script runs before the steps `Compiling Sources` by

> **_Note_**: There's a [known bug](https://github.com/mxcl/swift-sh/issues/113) when the build script is used in non-macOS platforms targets.

## Regex Cheat Sheet

Refer to the Regex quick reference on [rubular.com](https://rubular.com/) which all apply for Swift as well:
<p align="center">
<img src="https://raw.githubusercontent.com/Flinesoft/AnyLint/main/RubularQuickReference.png"
width=518 />
</p>

In Swift, there are some differences to regexes in Ruby (which rubular.com is based on) – take care when copying regexes:

1. In Ruby, forward slashes (`/`) must be escaped (`\/`), that's not necessary in Swift.
2. In Swift, curly braces (`{` & `}`) must be escaped (`\{` & `\}`), that's not necessary in Ruby.

Here are some advanced Regex features you might want to use or learn more about:

1. Back references can be used within regexes to match previous capture groups. For example, you can make sure that the PR number and link match in `PR: [#100](https://github.com/Flinesoft/AnyLint/pull/100)` by using a capture group (`(\d+)`) and a back reference (`\1`) like in: `\[#(\d+)\]\(https://[^)]+/pull/\1\)`. [Learn more](https://www.regular-expressions.info/backref.html)
2. Negative & positive lookaheads & lookbehinds allow you to specify patterns with some limitations that will be excluded from the matched range. They are specified with `(?=PATTERN)` (positive lookahead), `(?!PATTERN)` (negative lookahead), `(?<=PATTERN)` (positive lookbehind) or `(?<!PATTERN)` (negative lookbehind). For example, you could use the regex `- (?!None\.).*` to match any entry in a `CHANGELOG.md` file except empty ones called `None.`. [Learn more](https://www.regular-expressions.info/lookaround.html)
3. Specifically you can use a lookbehind to make sure that the reported line of a regex spanning multiple lines only reports on the exact line where the developer needs to make a change, instead of one line before. That works because the pattern matched by a lookbehind is not considered part of the matching range. For example, consider a regex violating if there's an empty line after an opening curly brace like so: `{\n\s*\n\s*\S`. This would match the lines of `func do() {\n\n return 5}`, but what you actually want is it to start matching on the empty newline like so: `(?<={\n)\s*\n\s*\S`. (See also [#3](https://github.com/Flinesoft/AnyLint/issues/3))

## Donation

AnyLint was brought to you by [Cihat Gündüz](https://github.com/Jeehut) in his free time. If you want to thank me and support the development of this project, please **make a small donation on [PayPal](https://paypal.me/Dschee/5EUR)**. In case you also like my other [open source contributions](https://github.com/Flinesoft) and [articles](https://medium.com/@Jeehut), please consider motivating me by **becoming a sponsor on [GitHub](https://github.com/sponsors/Jeehut)** or a **patron on [Patreon](https://www.patreon.com/Jeehut)**.
Expand Down
Binary file added RubularQuickReference.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion Sources/AnyLint/Checkers/FileContentsChecker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ extension FileContentsChecker: Checker {
let skipHereRegex = try Regex(#"AnyLint\.skipHere:[^\n]*[, ]\#(checkInfo.id)"#)

for match in regex.matches(in: fileContents).reversed() {
// TODO: [cg_2020-03-13] use capture group named 'pointer' if exists
let locationInfo = fileContents.locationInfo(of: match.range.lowerBound)

log.message("Found violating match at \(locationInfo) ...", level: .debug)
Expand Down
2 changes: 0 additions & 2 deletions Sources/AnyLint/Lint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ public enum Lint {

for example in matchingExamples {
if !regex.matches(example) {
// TODO: [cg_2020-03-14] check position of ↘ is the matching line and char.
log.message(
"Couldn't find a match for regex \(regex) in check '\(checkInfo.id)' within matching example:\n\(example)",
level: .error
Expand All @@ -199,7 +198,6 @@ public enum Lint {

for example in nonMatchingExamples {
if regex.matches(example) {
// TODO: [cg_2020-03-14] check position of ↘ is the matching line and char.
log.message(
"Unexpectedly found a match for regex \(regex) in check '\(checkInfo.id)' within non-matching example:\n\(example)",
level: .error
Expand Down