Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed Aug 11, 2024
1 parent 47b2211 commit c3ac898
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 3 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ DerivedData
Tests/Fixtures/.build/

# VSCode
.vscode/*
.vscode/*

# Bazel
bazel-*
/MODULE.bazel.lock
8 changes: 8 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module(
name = "periphery",
version = "0.0.0",
compatibility_level = 1,
)

internal = use_extension("//bazel:extensions.bzl", "internal")
use_repo(internal, "periphery_generated")
64 changes: 64 additions & 0 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions Sources/Frontend/Commands/BazelCommand.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import ArgumentParser
import Foundation
import Shared
import SystemPackage

struct BazelScanCommand: FrontendCommand {
static let configuration = CommandConfiguration(
commandName: "bazel-scan",
abstract: "Scan for unused code (for Bazel projects)"
)

@Option(help: "Bazel top-level targets expression")
var target: String = "//..."

@Option(help: "Path to configuration file. By default Periphery will look for .periphery.yml in the current directory")
var config: FilePath = FilePath(".periphery.yml")

func run() throws {
guard let executablePath = Bundle.main.executablePath else {
// TODO: throw?
return
}

let buildFilePath = FilePath("/var/tmp/periphery_bazel/generated/BUILD")
let fileManager = FileManager.default
try fileManager.createDirectory(at: buildFilePath.removingLastComponent().url, withIntermediateDirectories: true)
try? fileManager.removeItem(at: buildFilePath.url)
defer {
try? fileManager.removeItem(at: buildFilePath.url)
}

let shell = Shell.shared
let query = "kind(\'apple_framework_packaging rule|ios_unit_test rule|ios_ui_test rule|ios_application rule\', rdeps(//..., '\(target)') union deps('\(target)'))"
let output = try shell.exec(["bazel", "query", "--noshow_progress", "--ui_event_filters=-info,-debug,-warning", query])
let deps = output.split(separator: "\n").map { "\"@@\($0)\""}.joined(separator: ",\n")

let buildFileContents = """
load("@periphery//bazel:defs.bzl", "periphery_scan")
periphery_scan(
name = "scan",
testonly = True,
config = "\(FilePath.makeAbsolute(config))",
periphery_binary = "\(executablePath)",
visibility = [
"@periphery//bazel:generated"
],
deps = [
\(deps)
],
)
"""

try buildFileContents.write(to: buildFilePath.url, atomically: true, encoding: .utf8)

let task = Process()
// TODO: Get bazel bin path
task.launchPath = "/opt/homebrew/bin/bazel"
task.arguments = ["run", "@periphery//bazel:scan"]
try task.run()
task.waitUntilExit()
}
}
8 changes: 7 additions & 1 deletion Sources/Frontend/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ Logger.configureBuffering()
struct PeripheryCommand: FrontendCommand {
static let configuration = CommandConfiguration(
commandName: "periphery",
subcommands: [ScanCommand.self, CheckUpdateCommand.self, ClearCacheCommand.self, VersionCommand.self]
subcommands: [
ScanCommand.self,
BazelScanCommand.self,
CheckUpdateCommand.self,
ClearCacheCommand.self,
VersionCommand.self
]
)
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/Shell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ open class Shell {
result[pair.0] = pair.1
}

let preservedKeys = ["PATH", "DEVELOPER_DIR"]
let preservedKeys = ["PATH", "DEVELOPER_DIR", "SSH_AUTH_SOCK"]
preservedKeys.forEach { key in
if let value = environment[key] {
newEnv[key] = value
Expand Down
20 changes: 20 additions & 0 deletions bazel/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package_group(
name = "generated",
includes = [
"@periphery_generated//:package_group"
],
packages = [ # this is incorrect
"//...",
]
)

genrule(
name = "scan",
testonly = True,
srcs = [
"@periphery_generated//generated:scan"
],
cmd = "",
outs = ["scan.sh"],
executable = True
)
60 changes: 60 additions & 0 deletions bazel/defs.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
def _get_template_substitutions(*, periphery_binary, config_path):
"""Returns the template substitutions for this executable."""
subs = {
"periphery_binary": periphery_binary,
"config_path": config_path,
}
return {"%(" + k + ")s": subs[k] for k in subs}

def _periphery_scan_impl(ctx):
print(ctx.attr.config)
print(ctx.attr.periphery_binary)
print(ctx.file._template)

# runfiles = ctx.runfiles(
# files = source_files + indexstore_files + indexstores + [indexstores_file, file_targets_file, filter_files_file, ctx.executable._periphery, ctx.file._config],
# )

ctx.actions.expand_template(
template = ctx.file._template,
output = ctx.outputs.scan,
substitutions = _get_template_substitutions(
periphery_binary = ctx.attr.periphery_binary,
config_path = ctx.attr.config,
),
)

return DefaultInfo(
executable = ctx.outputs.scan,
files = depset(
[ctx.outputs.scan],
),
)

periphery_scan = rule(
attrs = {
"deps": attr.label_list(mandatory = True),
"config": attr.string(),
"periphery_binary": attr.string(),
"_template": attr.label(
allow_single_file = True,
default = "@periphery//bazel/internal:scan_template.sh",
),
},
outputs = {
"scan": "scan.sh",
},
implementation = _periphery_scan_impl,
executable = True,
)

def _foo(ctx):
print("foo")

generated_periphery_scan = rule(
attrs = {
"deps": attr.label_list(mandatory = True),
},
implementation = _foo,
executable = True,
)
23 changes: 23 additions & 0 deletions bazel/extensions.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
def _generated_files_repo_impl(repository_ctx):
repository_ctx.file(
"BUILD",
content = """
package_group(
name = "package_group",
packages = ["//..."],
)
""",
)

# TODO: output_base_hash like rules_xcodeproj?
# TODO: scoped by project?
repository_ctx.symlink(
"/var/tmp/periphery_bazel/generated/BUILD",
"generated/BUILD",
)

generated_files_repo = repository_rule(
implementation = _generated_files_repo_impl,
)

internal = module_extension(implementation = lambda _: generated_files_repo(name = "periphery_generated"))
3 changes: 3 additions & 0 deletions bazel/internal/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports_files([
"scan_template.sh"
])
1 change: 1 addition & 0 deletions bazel/internal/scan_template.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
echo "Hello from scan_template.sh"

0 comments on commit c3ac898

Please sign in to comment.