Skip to content

Commit 1f82dd4

Browse files
committed
Verify that files generated with SwiftSyntaxBuilder match the checked-in state
"Currently, we only verify that the gyb-generated files match the checked in source state. As more and more files are being generated using CodeGeneration, we should also verify them in CI. rdar://103023853
1 parent f58faae commit 1f82dd4

File tree

2 files changed

+64
-17
lines changed

2 files changed

+64
-17
lines changed

CodeGeneration/Package.swift

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// swift-tools-version:5.7
22

33
import PackageDescription
4+
import Foundation
45

56
let package = Package(
67
name: "CodeGeneration",
@@ -12,10 +13,6 @@ let package = Package(
1213
.executable(name: "generate-swiftideutils", targets: ["generate-swiftideutils"]),
1314
.executable(name: "generate-swiftsyntaxbuilder", targets: ["generate-swiftsyntaxbuilder"]),
1415
],
15-
dependencies: [
16-
.package(url: "https://github.com/apple/swift-syntax.git", revision: "cdbdcbabb78d14e5e8d4915a115e3d843868ab8d"),
17-
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "1.1.4")),
18-
],
1916
targets: [
2017
.executableTarget(
2118
name: "generate-swiftbasicformat",
@@ -78,3 +75,19 @@ let package = Package(
7875
),
7976
]
8077
)
78+
79+
if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
80+
// Building standalone.
81+
package.dependencies += [
82+
.package(url: "https://github.com/apple/swift-syntax.git", revision: "cdbdcbabb78d14e5e8d4915a115e3d843868ab8d"),
83+
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "1.1.4")),
84+
]
85+
} else {
86+
guard let swiftSyntaxPath = ProcessInfo.processInfo.environment["SWIFTCI_SWIFTSYNTAX_PATH"] else {
87+
fatalError("If SWIFTCI_USE_LOCAL_DEPS is specified, SWIFTCI_SWIFTSYNTAX_PATH must point to a checkout of SwiftSyntax of the same commit that's mentioned in the standalone build")
88+
}
89+
package.dependencies += [
90+
.package(name: "swift-syntax", path: swiftSyntaxPath),
91+
.package(path: "../../swift-argument-parser"),
92+
]
93+
}

build-script.py

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import argparse
44
import os
55
import platform
6+
import re
67
import subprocess
78
import sys
89
import tempfile
@@ -341,10 +342,15 @@ def generate_gyb_files(
341342
print("** Done Generating gyb Files **")
342343

343344

345+
# If swiftsyntax_checkout is specified, a SwiftSyntax checkout with the commit that's
346+
# used for CodeGeneration is assumed at that location, otherwise SwiftSyntax will be
347+
# pulled at the correct commit from the internet. This is useful to verify files
348+
# generated using CodeGeneration in CI that doesn't have internet access.
344349
def run_code_generation(
345350
swiftideutils_destination: str,
346351
swiftbasicformat_destination: str,
347352
swiftsyntaxbuilder_destination: str,
353+
local_swiftsyntax_checkout: Optional[str],
348354
toolchain: str,
349355
verbose: bool
350356
) -> None:
@@ -370,6 +376,9 @@ def run_code_generation(
370376

371377
env = dict(os.environ)
372378
env["SWIFT_BUILD_SCRIPT_ENVIRONMENT"] = "1"
379+
if local_swiftsyntax_checkout:
380+
env["SWIFTCI_USE_LOCAL_DEPS"] = "1"
381+
env["SWIFTCI_SWIFTSYNTAX_PATH"] = local_swiftsyntax_checkout
373382
check_call(swiftpm_call, env=env, verbose=verbose)
374383

375384

@@ -505,6 +514,20 @@ def verify_gyb_generated_files(gyb_exec: str, verbose: bool) -> None:
505514
)
506515

507516

517+
# Parses the package manifest of CodeGeneration to find the SwiftSyntax commit it
518+
# references.
519+
def get_swiftsyntax_commit_for_codegeneration() -> str:
520+
with open(os.path.join(CODE_GENERATION_DIR, 'Package.swift')) as \
521+
codegen_package_manifest:
522+
for line in codegen_package_manifest:
523+
match = re.search(r'.package\(url: "https://github.com/apple/swift-syntax.git", revision: "([0-9a-f]+)"\)', line) # noqa: E501
524+
if match:
525+
return match.group(1)
526+
527+
fatal_error('Could not find commit of SwiftSyntax that CodeGeneration references')
528+
return '' # Make Python's type checker happy
529+
530+
508531
def verify_code_generated_files(
509532
toolchain: str, verbose: bool
510533
) -> None:
@@ -522,19 +545,29 @@ def verify_code_generated_files(
522545
self_swiftbasicformat_generated_dir = tempfile.mkdtemp()
523546
self_swiftsyntaxbuilder_generated_dir = tempfile.mkdtemp()
524547

525-
try:
526-
run_code_generation(
527-
swiftideutils_destination=self_swiftideutils_generated_dir,
528-
swiftbasicformat_destination=self_swiftsyntaxbuilder_generated_dir,
529-
swiftsyntaxbuilder_destination=self_swiftsyntaxbuilder_generated_dir,
530-
toolchain=toolchain,
531-
verbose=verbose
532-
)
533-
except subprocess.CalledProcessError as e:
534-
fail_for_called_process_error(
535-
"Source generation using SwiftSyntaxBuilder failed",
536-
e
537-
)
548+
with tempfile.TemporaryDirectory(dir=os.path.dirname(PACKAGE_DIR)) as \
549+
local_swiftsyntax_checkout:
550+
# Perform a local clone of SwiftSyntax that we can check out at the commit that
551+
# CodeGeneration expects.
552+
check_call(['git', 'clone', PACKAGE_DIR, local_swiftsyntax_checkout],
553+
verbose=verbose)
554+
check_call(['git', 'checkout', get_swiftsyntax_commit_for_codegeneration()],
555+
cwd=local_swiftsyntax_checkout, verbose=verbose)
556+
557+
try:
558+
run_code_generation(
559+
swiftideutils_destination=self_swiftideutils_generated_dir,
560+
swiftbasicformat_destination=self_swiftbasicformat_generated_dir,
561+
swiftsyntaxbuilder_destination=self_swiftsyntaxbuilder_generated_dir,
562+
local_swiftsyntax_checkout=local_swiftsyntax_checkout,
563+
toolchain=toolchain,
564+
verbose=verbose
565+
)
566+
except subprocess.CalledProcessError as e:
567+
fail_for_called_process_error(
568+
"Source generation using SwiftSyntaxBuilder failed",
569+
e
570+
)
538571

539572
print("** Verifing code generated files **")
540573

@@ -729,6 +762,7 @@ def generate_source_code_command(args: argparse.Namespace) -> None:
729762
swiftideutils_destination=swiftideutils_destination,
730763
swiftbasicformat_destination=swiftbasicformat_destination,
731764
swiftsyntaxbuilder_destination=swiftsyntaxbuilder_destination,
765+
local_swiftsyntax_checkout=None,
732766
toolchain=args.toolchain,
733767
verbose=args.verbose
734768
)

0 commit comments

Comments
 (0)