Skip to content

Commit

Permalink
Added swiftformat_exclude to the rules_swift helpers and bug fixe…
Browse files Browse the repository at this point in the history
…s. (#19)

Added swiftformat_exclude to swiftformat_library, swiftformat_binary, and swiftformat_test. This allows a Swift file to be included for the build, but not formatted. This is useful for Swift source files that cause SwiftFormat to hang or take a long time to process.
Added missing logic for handling if srcs was not specified for swiftformat_library, swiftformat_binary, or swiftformat_test.
Added exclude_files example which demonstrates the use of the swiftformat_exclude attribute.
Fixed typo in rules_swift_helpers example.
Fixed issue where the name for the formatting targets was not unique.
  • Loading branch information
cgrindel committed Oct 21, 2021
1 parent 1da1fb9 commit 6e4e959
Show file tree
Hide file tree
Showing 25 changed files with 242 additions and 21 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,9 @@ jobs:
run: |
cd examples/rules_swift_helpers
bazelisk test //...
- name: Test File Exclusion Example
shell: bash
run: |
cd examples/exclude_files
bazelisk test //...
12 changes: 6 additions & 6 deletions doc/rules_and_macros_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Copies the formatted Swift sources to the workspace directory.
## swiftformat_binary

<pre>
swiftformat_binary(<a href="#swiftformat_binary-name">name</a>, <a href="#swiftformat_binary-swiftformat_config">swiftformat_config</a>, <a href="#swiftformat_binary-swiftformat_name">swiftformat_name</a>, <a href="#swiftformat_binary-srcs">srcs</a>, <a href="#swiftformat_binary-kwargs">kwargs</a>)
swiftformat_binary(<a href="#swiftformat_binary-name">name</a>, <a href="#swiftformat_binary-swiftformat_config">swiftformat_config</a>, <a href="#swiftformat_binary-swiftformat_exclude">swiftformat_exclude</a>, <a href="#swiftformat_binary-srcs">srcs</a>, <a href="#swiftformat_binary-kwargs">kwargs</a>)
</pre>

Defines a `swift_binary` along with a `swiftformat_pkg`.
Expand All @@ -73,7 +73,7 @@ Defines a `swift_binary` along with a `swiftformat_pkg`.
| :------------- | :------------- | :------------- |
| <a id="swiftformat_binary-name"></a>name | The name for the swift_binary as a <code>string</code>. | none |
| <a id="swiftformat_binary-swiftformat_config"></a>swiftformat_config | A <code>label</code> for the SwiftFormat config file. | <code>None</code> |
| <a id="swiftformat_binary-swiftformat_name"></a>swiftformat_name | Optional. The name for the <code>swiftformat_pkg</code>. | <code>"swiftformat"</code> |
| <a id="swiftformat_binary-swiftformat_exclude"></a>swiftformat_exclude | A <code>list</code> of files or glob patterns that should be ignored for formatting. | <code>[]</code> |
| <a id="swiftformat_binary-srcs"></a>srcs | The Swift sources that should be used by the <code>swift_binary</code> and the <code>swiftformat_pkg</code>. | <code>None</code> |
| <a id="swiftformat_binary-kwargs"></a>kwargs | The attributes for <code>swift_binary</code>. | none |

Expand All @@ -83,7 +83,7 @@ Defines a `swift_binary` along with a `swiftformat_pkg`.
## swiftformat_library

<pre>
swiftformat_library(<a href="#swiftformat_library-name">name</a>, <a href="#swiftformat_library-swiftformat_config">swiftformat_config</a>, <a href="#swiftformat_library-swiftformat_name">swiftformat_name</a>, <a href="#swiftformat_library-srcs">srcs</a>, <a href="#swiftformat_library-kwargs">kwargs</a>)
swiftformat_library(<a href="#swiftformat_library-name">name</a>, <a href="#swiftformat_library-swiftformat_config">swiftformat_config</a>, <a href="#swiftformat_library-swiftformat_exclude">swiftformat_exclude</a>, <a href="#swiftformat_library-srcs">srcs</a>, <a href="#swiftformat_library-kwargs">kwargs</a>)
</pre>

Defines a `swift_library` along with a `swiftformat_pkg`.
Expand All @@ -95,7 +95,7 @@ Defines a `swift_library` along with a `swiftformat_pkg`.
| :------------- | :------------- | :------------- |
| <a id="swiftformat_library-name"></a>name | The name for the swift_library as a <code>string</code>. | none |
| <a id="swiftformat_library-swiftformat_config"></a>swiftformat_config | A <code>label</code> for the SwiftFormat config file. | <code>None</code> |
| <a id="swiftformat_library-swiftformat_name"></a>swiftformat_name | Optional. The name for the <code>swiftformat_pkg</code>. | <code>"swiftformat"</code> |
| <a id="swiftformat_library-swiftformat_exclude"></a>swiftformat_exclude | A <code>list</code> of files or glob patterns that should be ignored for formatting. | <code>[]</code> |
| <a id="swiftformat_library-srcs"></a>srcs | The Swift sources that should be used by the <code>swift_library</code> and the <code>swiftformat_pkg</code>. | <code>None</code> |
| <a id="swiftformat_library-kwargs"></a>kwargs | The attributes for <code>swift_library</code>. | none |

Expand Down Expand Up @@ -125,7 +125,7 @@ Defines targets that will format, test and update the specified Swift sources.
## swiftformat_test

<pre>
swiftformat_test(<a href="#swiftformat_test-name">name</a>, <a href="#swiftformat_test-swiftformat_config">swiftformat_config</a>, <a href="#swiftformat_test-swiftformat_name">swiftformat_name</a>, <a href="#swiftformat_test-srcs">srcs</a>, <a href="#swiftformat_test-kwargs">kwargs</a>)
swiftformat_test(<a href="#swiftformat_test-name">name</a>, <a href="#swiftformat_test-swiftformat_config">swiftformat_config</a>, <a href="#swiftformat_test-swiftformat_exclude">swiftformat_exclude</a>, <a href="#swiftformat_test-srcs">srcs</a>, <a href="#swiftformat_test-kwargs">kwargs</a>)
</pre>

Defines a `swift_test` along with a `swiftformat_pkg`.
Expand All @@ -137,7 +137,7 @@ Defines a `swift_test` along with a `swiftformat_pkg`.
| :------------- | :------------- | :------------- |
| <a id="swiftformat_test-name"></a>name | The name for the swift_test as a <code>string</code>. | none |
| <a id="swiftformat_test-swiftformat_config"></a>swiftformat_config | A <code>label</code> for the SwiftFormat config file. | <code>None</code> |
| <a id="swiftformat_test-swiftformat_name"></a>swiftformat_name | Optional. The name for the <code>swiftformat_pkg</code>. | <code>"swiftformat"</code> |
| <a id="swiftformat_test-swiftformat_exclude"></a>swiftformat_exclude | A <code>list</code> of files or glob patterns that should be ignored for formatting. | <code>[]</code> |
| <a id="swiftformat_test-srcs"></a>srcs | The Swift sources that should be used by the <code>swift_test</code> and the <code>swiftformat_pkg</code>. | <code>None</code> |
| <a id="swiftformat_test-kwargs"></a>kwargs | The attributes for <code>swift_test</code>. | none |

Expand Down
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
[`swiftformat_library`](/doc/rules_and_macros_overview.md#swiftformat_library),
[`swiftformat_binary`](/doc/rules_and_macros_overview.md#swiftformat_binary), and
[`swiftformat_test`](/doc/rules_and_macros_overview.md#swiftformat_test).
- [Exclude Files](exclude_files/) - Demonstrates the use of of the `rules_swift` helpers using
`swiftformat_exclude` attribute.
14 changes: 14 additions & 0 deletions examples/exclude_files/.swiftformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# For information on the rules, see
# https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md

--swiftversion 5.4

--allman false
--indent 2
--semicolons never
--stripunusedargs always
--maxwidth 100
--wraparguments before-first
--wrapparameters before-first
--wrapcollections before-first

16 changes: 16 additions & 0 deletions examples/exclude_files/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
load(
"@cgrindel_rules_swiftformat//swiftformat:swiftformat.bzl",
"swiftformat_update_all",
)

# MARK: - SwiftFormat Targets

# We only need to export this file if there are any other packages that need to
# reference the config file.
exports_files([".swiftformat"])

# Defines a target that will copy all of the formatted Swift source files to
# the workspace directory.
swiftformat_update_all(
name = "update_all",
)
7 changes: 7 additions & 0 deletions examples/exclude_files/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Example Demonstrating `rules_swift` Convenience Macros

This example demonstrates the use of
[`swiftformat_library`](/doc/rules_and_macros_overview.md#swiftformat_library),
[`swiftformat_binary`](/doc/rules_and_macros_overview.md#swiftformat_binary), and
[`swiftformat_test`](/doc/rules_and_macros_overview.md#swiftformat_test)
to define `rules_swift` targets along with `rules_swiftformat` targets.
14 changes: 14 additions & 0 deletions examples/exclude_files/Sources/App/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load(
"@cgrindel_rules_swiftformat//swiftformat:swiftformat.bzl",
"swiftformat_binary",
)

# Defines a swift_binary and swiftformat_pkg.
swiftformat_binary(
name = "simple",
swiftformat_exclude = ["PoorlyFormatted.swift"],
visibility = ["//:__subpackages__"],
deps = [
"//Sources/Foo",
],
)
5 changes: 5 additions & 0 deletions examples/exclude_files/Sources/App/PoorlyFormatted.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file is purposely poorly formatted. It is excluded from formatting in
// the BUILD.bazel file.
struct PoorlyFormatted {
var name = ""
}
9 changes: 9 additions & 0 deletions examples/exclude_files/Sources/App/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foo

var msg = Message()
msg.value = "Hello World!"

var pfmt = PoorlyFormatted()
pfmt.name = "Larry"

Swift.print(msg.value)
11 changes: 11 additions & 0 deletions examples/exclude_files/Sources/Foo/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
load(
"@cgrindel_rules_swiftformat//swiftformat:swiftformat.bzl",
"swiftformat_library",
)

swiftformat_library(
name = "Foo",
module_name = "Foo",
swiftformat_exclude = ["PoorlyFormatted.swift"],
visibility = ["//:__subpackages__"],
)
10 changes: 10 additions & 0 deletions examples/exclude_files/Sources/Foo/Message.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
public struct Message {
public var value: String
var pfmt: PoorlyFormatted

public init(value: String = "") {
self.value = value
pfmt = PoorlyFormatted()
pfmt.name = value
}
}
5 changes: 5 additions & 0 deletions examples/exclude_files/Sources/Foo/PoorlyFormatted.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file is purposely poorly formatted. It is excluded from formatting in
// the BUILD.bazel file.
struct PoorlyFormatted {
var name = ""
}
6 changes: 6 additions & 0 deletions examples/exclude_files/Tests/AppTests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sh_test(
name = "simple_test",
srcs = ["simple_test.sh"],
data = ["//Sources/App:simple"],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
24 changes: 24 additions & 0 deletions examples/exclude_files/Tests/AppTests/simple_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---

err_msg() {
local msg="$1"
echo >&2 "${msg}"
exit 1
}

workspace="${TEST_WORKSPACE}"
binary="$(rlocation "${workspace}/Sources/App/simple")"

expected="Hello World"
"${binary}" | grep "${expected}" || err_msg "Failed to find expected output. ${expected}"
12 changes: 12 additions & 0 deletions examples/exclude_files/Tests/FooTests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load(
"@cgrindel_rules_swiftformat//swiftformat:swiftformat.bzl",
"swiftformat_test",
)

swiftformat_test(
name = "FooTests",
swiftformat_exclude = ["PoorlyFormattedTests.swift"],
deps = [
"//Sources/Foo",
],
)
10 changes: 10 additions & 0 deletions examples/exclude_files/Tests/FooTests/MessageTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@testable import Foo
import XCTest

class MessageTests: XCTestCase {
func test_init() throws {
let value = "hello"
let msg = Message(value: value)
XCTAssertEqual(msg.value, value)
}
}
12 changes: 12 additions & 0 deletions examples/exclude_files/Tests/FooTests/PoorlyFormattedTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@testable import Foo
import XCTest

// Purposely poorly formatted.
class PoorlyFormattedTests: XCTestCase {
func test_init() throws {
let value = "hello"
var pfmt = PoorlyFormatted()
pfmt.name = value
XCTAssertEqual(pfmt.name, value)
}
}
35 changes: 35 additions & 0 deletions examples/exclude_files/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
workspace(name = "exclude_files_example")

local_repository(
name = "cgrindel_rules_swiftformat",
path = "../..",
)

load("@cgrindel_rules_swiftformat//swiftformat:deps.bzl", "swiftformat_rules_dependencies")

swiftformat_rules_dependencies()

load(
"@cgrindel_rules_spm//spm:deps.bzl",
"spm_rules_dependencies",
)

spm_rules_dependencies()

load(
"@build_bazel_rules_swift//swift:repositories.bzl",
"swift_rules_dependencies",
)

swift_rules_dependencies()

load(
"@build_bazel_rules_swift//swift:extras.bzl",
"swift_rules_extra_dependencies",
)

swift_rules_extra_dependencies()

load("@cgrindel_rules_swiftformat//swiftformat:load_package.bzl", "swiftformat_load_package")

swiftformat_load_package()
4 changes: 2 additions & 2 deletions examples/rules_swift_helpers/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Example Demonstrating `rules_swift` Convenience Macros
# Example Demonstrating Exclusion of Select Files from Formatting

This example demonstrates the use of
[`swiftformat_library`](/doc/rules_and_macros_overview.md#swiftformat_library),
[`swiftformat_binary`](/doc/rules_and_macros_overview.md#swiftformat_binary), and
[`swiftformat_test`](/doc/rules_and_macros_overview.md#swiftformat_test)
to define `rules_swift` targets along with `rules_swiftformat` targets.
using `swiftformat_exclude` to skip the formatting of select files.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import XCTest
class MessageTests: XCTestCase {
func test_init() throws {
let value = "hello"
let msg = Messsage(value = value)
let msg = Message(value: value)
XCTAssertEqual(msg.value, value)
}
}
10 changes: 7 additions & 3 deletions swiftformat/internal/swiftformat_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ load(":swiftformat_pkg.bzl", "swiftformat_pkg")
def swiftformat_binary(
name,
swiftformat_config = None,
swiftformat_name = "swiftformat",
swiftformat_exclude = [],
srcs = None,
**kwargs):
"""Defines a `swift_binary` along with a `swiftformat_pkg`.
Args:
name: The name for the swift_binary as a `string`.
swiftformat_config: A `label` for the SwiftFormat config file.
swiftformat_name: Optional. The name for the `swiftformat_pkg`.
swiftformat_exclude: A `list` of files or glob patterns that should
be ignored for formatting.
srcs: The Swift sources that should be used by the `swift_binary` and the `swiftformat_pkg`.
**kwargs: The attributes for `swift_binary`.
Returns:
None.
"""
if srcs == None:
srcs = native.glob(["*.swift"])

# Define the swift binary
swift_binary(
Expand All @@ -28,8 +31,9 @@ def swiftformat_binary(
)

# Define the swiftformat stuff
swiftformat_name = name + "_swiftformat"
swiftformat_pkg(
name = swiftformat_name,
srcs = srcs,
srcs = native.glob(srcs, exclude = swiftformat_exclude),
config = swiftformat_config,
)
10 changes: 7 additions & 3 deletions swiftformat/internal/swiftformat_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ load(":swiftformat_pkg.bzl", "swiftformat_pkg")
def swiftformat_library(
name,
swiftformat_config = None,
swiftformat_name = "swiftformat",
swiftformat_exclude = [],
srcs = None,
**kwargs):
"""Defines a `swift_library` along with a `swiftformat_pkg`.
Args:
name: The name for the swift_library as a `string`.
swiftformat_config: A `label` for the SwiftFormat config file.
swiftformat_name: Optional. The name for the `swiftformat_pkg`.
swiftformat_exclude: A `list` of files or glob patterns that should
be ignored for formatting.
srcs: The Swift sources that should be used by the `swift_library` and the `swiftformat_pkg`.
**kwargs: The attributes for `swift_library`.
Returns:
None.
"""
if srcs == None:
srcs = native.glob(["*.swift"])

# Define the swift library
swift_library(
Expand All @@ -28,8 +31,9 @@ def swiftformat_library(
)

# Define the swiftformat stuff
swiftformat_name = name + "_swiftformat"
swiftformat_pkg(
name = swiftformat_name,
srcs = srcs,
srcs = native.glob(srcs, exclude = swiftformat_exclude),
config = swiftformat_config,
)
13 changes: 11 additions & 2 deletions swiftformat/internal/swiftformat_pkg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
they are formatted and copies them to the workspace directory.
"""

def _is_label(src):
return src.find(":") > -1

def _is_path(src):
return not _is_label(src)

def swiftformat_pkg(name, srcs = None, config = None):
"""Defines targets that will format, test and update the specified Swift sources.
Expand All @@ -20,9 +26,12 @@ def swiftformat_pkg(name, srcs = None, config = None):
if srcs == None:
srcs = native.glob(["*.swift"])

# Only process paths; ignore labels
src_paths = [src for src in srcs if _is_path(src)]

format_names = []
for src in srcs:
src_name = src.replace("/", "_")
for src in src_paths:
src_name = src.replace("/", "_").replace(":", "")
format_name = name + "_fmt_" + src_name
format_names.append(":" + format_name)

Expand Down
Loading

0 comments on commit 6e4e959

Please sign in to comment.