For larger ant build structures and quite complex projects, I'd like to indent the information output (echo) depending on target call-depth like:
[echo] running build from project/build.xml
[echo] running build from project/sub1/build.xml
[echo] running build from project/sub2/build.xml
[echo] running build from project/sub2/sub21/build.xml
[echo] running build from project/sub2/sub22/build.xml
[echo] running build from project/sub3/build.xml
BUILD SUCCESSFUL
Total time: x seconds
Is there such a tweaking, logging property or whatever?
...maybe xslt/css or event listeners?
Indentation is not the point, but to see the call hierarchy: avoid searching through the build.xml files or adding own echo function in all the targets and macrodefs.
See https://ant.apache.org/manual/listeners.html
The XmlLogger seems helpful there, if a bit too verbose - you can extract the call hierarchy (with echos too) with a bit of scripting:
ant -logger org.apache.tools.ant.XmlLogger build
Also had some success with Log4j:
ant -listener org.apache.tools.ant.listener.Log4jListener -lib ..../logging-log4j-1.2.17/dist/lib/ -lib . build
For this I put a log4j.properties file in the current dir, using the sample contents at the first link above.
This produces a build.log with the following contents:
[ 0] Project : Build started.
[ 908] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 995] Target : Target "build" started.
[ 4312] Echo : com.ohmy: ivy.sorted.modules=thirdparty-plugins#com.sun.jaxb
[ 4529] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 4588] Target : Target "build_empty_unittests_jar_to_fulfill_dependencies" started.
[ 4590] Target : Target "build_empty_unittests_jar_to_fulfill_dependencies" finished.
[ 4591] Target : Target "build_nodeps" started.
[ 4591] Echo : Calling target 'build' for module com.sun.jaxb
[ 4770] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 4846] Target : Target "check_module_targets_file_exists" started.
[ 4847] Target : Target "check_module_targets_file_exists" finished.
[ 4847] Target : Target "check_module_target_exists" started.
[ 4847] Target : Target "check_module_target_exists" finished.
Now I just pipe this into little ruby one liner hack to indent it:
ruby -pe 'BEGIN {$i=0};$i-=1 if /finished\.$/;print " " * $i;$i+=1 if /started\.$/' build.log
which yields
[ 0] Project : Build started.
[ 908] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 995] Target : Target "build" started.
[ 4312] Echo : com.ohmy: ivy.sorted.modules=thirdparty-plugins#com.sun.jaxb, com.ohmy
[ 4529] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 4588] Target : Target "build_empty_unittests_jar_to_fulfill_dependencies" started.
[ 4590] Target : Target "build_empty_unittests_jar_to_fulfill_dependencies" finished.
[ 4591] Target : Target "build_nodeps" started.
[ 4591] Echo : Calling target 'build' for module com.sun.jaxb
[ 4770] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 4846] Target : Target "check_module_targets_file_exists" started.
[ 4847] Target : Target "check_module_targets_file_exists" finished.
[ 4847] Target : Target "check_module_target_exists" started.
[ 4847] Target : Target "check_module_target_exists" finished.
[ 4847] Target : Target "module_target" started.
[ 4847] Target : Target "module_target" finished.
[ 4847] Target : Target "default_target" started.
[ 4849] Target : Target "init" started.
[ 4850] Target : Target "check_module_ivy_file_uptodate" started.
[ 4858] Target : Target "check_module_ivy_file_uptodate" finished.
[ 4858] Target : Target "create_module_ivy_file" started.
[ 4858] Target : Target "create_module_ivy_file" finished.
[ 4859] Target : Target "check_build_file_uptodate" started.
[ 4862] Target : Target "check_build_file_uptodate" finished.
[ 4864] Target : Target "generate_module_build_file" started.
[ 4864] Target : Target "generate_module_build_file" finished.
[ 4865] Target : Target "update_module_build_file" started.
[ 4866] Target : Target "check_module_name" started.
[ 4868] Target : Target "check_module_name" finished.
[ 4869] Target : Target "check_manifest_version" started.
[ 4869] Echo : Calling target 'check_manifest' for module com.sun.jaxb
[ 5041] Taskdef : Could not load definitions from resource checkstyletask.properties. It could not be found.
[ 5065] Target : Target "check_module_targets_file_exists" started.
[ 5065] Target : Target "check_module_targets_file_exists" finished.
[ 5065] Target : Target "check_module_target_exists" started.
[ 5065] Target : Target "check_module_target_exists" finished.
[ 5065] Target : Target "module_target" started.
[ 5065] Target : Target "module_target" finished.
[ 5066] Target : Target "default_target" started.
[ 5066] Target : Target "default_check_manifest" started.
[ 5067] Target : Target "default_check_manifest" finished.
[ 5067] Target : Target "default_target" finished.
[ 5067] Target : Target "module_specific_target" started.
[ 5067] Target : Target "module_specific_target" finished.
[ 5068] Target : Target "check_manifest_version" finished.
[ 5068] Target : Target "update_module_build_file" finished.
[ 5069] Target : Target "ivy_retrieve" started.
[ 5069] Echo : Skipping 'ivy_retrieve' as everything is uptodate for com.sun.jaxb
....
Of course this can be refined but it's good enough for me right now :)
Related
I have managed to run SwiftLint as plugin for my project
struct Linting: BuildToolPlugin {
func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
let swiftLintConfigFile = context.package.directory.appending(".swiftlint.yml")
let genSourcesDir = context.pluginWorkDirectory.appending("output")
return [
.buildCommand(
displayName: "Running SwiftLint for \(target.name)",
executable: try context.tool(named: "swiftlint").path,
arguments: [
"lint",
"--config",
swiftLintConfigFile
],
environment: [:],
outputFiles: [genSourcesDir]
)
]
}
}
everything is working as expected and I can see the errors/warnings of SwiftLint but the problem is That I always get Command PhaseScriptExecution failed with a nonzero exit code
Here is my Package.swift
let package = Package(
name: "APP",
products: [
.library(name: "AppFeature", targets: ["AppFeature"]),
.library(name: "Models", targets: ["Models"]),
.plugin(name: "Linting", targets: ["Linting"])
],
dependencies: [],
targets: [
.target(name: "AppFeature", dependencies: ["Models"], plugins: ["Linting"]),
.target(name: "Models"),
.binaryTarget(name: "SwiftLintBinary", path: "Sources/SwiftLintBinary.artifactbundle"),
.plugin(
name: "Linting",
capability: .buildTool(),
dependencies: [
"SwiftLintBinary"
]
),
.testTarget(name: "AppFeatureTests", dependencies: ["AppFeature"]),
]
)
The Package belong to a Xcode project like the following.
I also have checked what does the Error I am getting means
Error: You don’t have permission to save the file “d42b39293bc4ddcfb20c48bf35251e7209d7ddee87edd739b0bc0bab05584478.plist” in the folder “8FE8CC02-8D70-373F-99BE-864A503CD73A”.
it turned out that the 8FE8CC02-8D70-373F-99BE-864A503CD73A is a folder being used by SwiftLint to cache some findings
.//Library/Caches/SwiftLint/0.49.0/8FE8CC02-8D70-373F-99BE-864A503CD73A
the weird thing is if I run the swiftlint from the Mac terminal it just works using ./Sources/SwiftLintBinary.artifactbundle/swiftlint-0.49.0-macos/bin/swiftlint but from Xcode it doesn't, any help would be appreciated.
I am attempting to create a py_binary in bazel and then copy that to a remote machine. At the moment I was doing a dummy app to make sure the pipeline would work. I cannot use a docker image as I need lower level control of the hardware than docker can provide.
My goal is to do the following:
build the software with bazel
create a tar package that contains the py_binary
copy and run that binary on another computer not connected to bazel
To do this I made a simple binary(that for context just makes some RPC calls to a server I am working on as a side project) and the build files is as follows:
py_binary(
name="rosecore_cli",
srcs=glob([
"src/*.py"
]),
deps = [
"//rosecore/proto:project_py_pb2_grpc",
"//rosecore/proto:project_py_pb2"
]
)
pkg_files(
name = "binary",
srcs = [
":rosecore_cli",
],
prefix = "/usr/share/rosecore/bin",
)
pkg_filegroup(
name = "arch",
srcs = [
":binary",
],
visibility = ["//visibility:public"],
)
pkg_tar(
name = "rosecore_tar",
srcs = [
":arch"
],
include_runfiles=True
)
When I build, copy the tar file and extract it I get the following error:
AssertionError: Cannot find .runfiles directory for ./usr/share/rosecore/bin/rosecore_cli
Any help would be appreciated :)
I have a Bazel executable target (of type fsharp_binary, but I don't think it should matter) that I can run using bazel run.
bazel run //my_app.exe
I would like to use this executable as a test, so that when I call bazel test it gets built and executed, and a non-zero exit code is considered a test failure.
bazel test //...
What I am looking for is something like this:
test_of_executable(
name = "my_test",
executable = "//my_app.exe",
success_codes = [ 0 ],
)
Then:
bazel test //:my_test
How can I achieve this in Bazel?
Just wrap your app as a sh_test. See for example https://github.com/bazelbuild/bazel/issues/1969.
What I use in my codebase is:
BUILD.bazel:
sh_test(
name = "test",
srcs = ["test.sh"],
data = [
"//:some_binary",
],
)
test.sh
some_project/some_subdir/some_binary
See here for an real example.
I have a Package.swift manifest as follows:
// swift-tools-version:5.4
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "long-package-name-ios",
defaultLocalization: "en",
platforms: [
.iOS(.v14),
.macOS(.v10_15)
],
products: [
.library(
name: "PackageName",
targets: ["PackageName"]),
.library(
name: "PackageNameImproved",
targets: ["PackageNameImproved"]),
.library(
name: "PackageNameUI",
targets: ["PackageNameUI"]),
],
dependencies: [
.package(
name: "PackageLib",
url: "ssh://apple.com/packagelib.git",
.upToNextMinor(from: "1.2.3")
)
],
targets: [
.target(
name: "PackageName",
dependencies: [
.product(name: "PackageLib", package: "PackageLib"),
],
path: "PackageName"),
.target(
name: "PackageName",
dependencies: [
"PackageName",
.product(name: "PackageLib", package: "PackageLib"),
],
path: "PackageNameImproved"),
.target(
name: "PackageNameUI",
dependencies: [
"PackageNameImproved",
],
path: "PackageNameUI")
]
)
Package Manifest summary:
3 targets
1 target depends on the other one
Only PackageName is compatible with macOS, the other ones are iOS-only
Build commands
Building long-package-name-ios-Package(builds all targets within the package) for iOS:
swift build -Xswiftc "-sdk" -Xswiftc "$(xcrun --sdk iphonesimulator
--show-sdk-path)" -Xswiftc "-target" -Xswiftc "arm64-apple-ios15.0-simulator"
[137/137] Build complete!
Now trying to build just the PackageName for macOS:
swift build -Xswiftc "-sdk" -Xswiftc "$(xcrun --sdk macosx
--show-sdk-path)" --product "PackageName"
[1/1] Planning buildwarning: '--product' cannot be used with the
automatic product 'PackageName'; building the default target instead
And it proceeds with building the default target long-package-name-ios-Package for the macOS platform which obviously fails due to inability to import, e.g. UIKit or any other iOS-only framework.
Question
How can I specify to build only PackageName for the macOS platform? I'm open to creating an Xcode Package, Schemes and other different configurations, but the end goals should be to:
Integrate long-package-name-ios-Package (all targets) for iOS only
Integrate PackageName for macOS
Edit: While my original answer makes the error go away, it is not possible to actually import the library into the plugin. (It fails to compile with a "no such module" error.) This seems to be intended behavior.
The "automatic product" in the error refers to the fact that the PackageName has no configured library type. If you configure its type (either dynamic or static), the error goes away and the target can be built:
.library(
name: "PackageName",
type: .dynamic,
targets: ["PackageName"]
)
I'm writing some bazel tests where I need to be able to provide the full path to some file.
bazel test //webservice:checkstyle-test --test_arg="path_to_some_file"
My question is how can you parse the input arguments in your bazel test? Is there anything like ctx.arg?
BUILD
load("//:checkstyle.bzl", "checkstyle_test")
checkstyle_test(
name = ""
src = []
config = ""
)
checkstyle.bzl
def _checkstyle_test_impl(ctx):
// How can I get my input parameter here?
checkstyle_test = rule(
implementation = _checkstyle_test_impl,
test = True,
attrs = {
"_classpath": attr.label_list(default=[
Label("#com_puppycrawl_tools_checkstyle//jar")
]),
"config": attr.label(allow_single_file=True, default = "//config:checkstyle"),
"suppressions": attr.label(allow_single_file=True, default = "//config:suppressions"),
"license": attr.label(allow_single_file=True, default = "//config:license"),
"properties": attr.label(allow_single_file=True),
"opts": attr.string_list(),
"string_opts": attr.string_dict(),
"srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(),
},
)
The value of --test_arg is passed to the test executable as program arguments when bazel runs it during bazel test, see https://docs.bazel.build/versions/main/command-line-reference.html#flag--test_arg
For example:
def _impl(ctx):
ctx.actions.write(
output = ctx.outputs.executable,
content = "echo test args: ; echo $#",
)
my_test = rule(
implementation = _impl,
test = True,
)
load(":defs.bzl", "my_test")
my_test(name = "foo")
$ bazel test foo --test_arg=--abc=123 --test_output=streamed
WARNING: Streamed test output requested. All tests will be run locally, without sharding, one at a time
INFO: Analyzed target //:foo (24 packages loaded, 277 targets configured).
INFO: Found 1 test target...
test args:
--abc=123
Target //:foo up-to-date:
bazel-bin/foo
INFO: Elapsed time: 0.559s, Critical Path: 0.13s
INFO: 5 processes: 3 internal, 2 linux-sandbox.
INFO: Build completed successfully, 5 total actions
//:foo PASSED in 0.0s
Executed 1 out of 1 test: 1 test passes.
INFO: Build completed successfully, 5 total actions
I don't think there's currently a way to get the value of --test_arg in a Starlark rule implementation (it's not added under ctx.fragments for example).