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
3 changes: 1 addition & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ bazel_dep(name = "bazel_skylib", version = "1.8.1")
bazel_dep(name = "stardoc", version = "0.8.0", dev_dependency = True, repo_name = "io_bazel_stardoc")
bazel_dep(name = "rules_rust_mdbook", version = "0.62.0", dev_dependency = True)

powershell = use_extension("//powershell:extensions.bzl", "powershell", dev_dependency = True)
powershell = use_extension("//powershell:extensions.bzl", "powershell")
powershell.toolchain(
name = "powershell_toolchains",
)
use_repo(powershell, "powershell_toolchains")

register_toolchains(
"@powershell_toolchains//:all",
dev_dependency = True,
)
35 changes: 3 additions & 32 deletions MODULE.bazel.lock

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

1 change: 1 addition & 0 deletions powershell/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ load(":utils.bzl", "pwsh_entrypoint")
exports_files([
"entrypoint.bat",
"entrypoint.sh",
"process_wrapper.ps1",
])

pwsh_entrypoint(
Expand Down
10 changes: 6 additions & 4 deletions powershell/private/entrypoint.bat
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ exit /b 0
:slocation_end


call :rlocation "{PWSH_INTERPRETER}" PWSH_INTERPRETER
call :rlocation "{MAIN}" MAIN
call :rlocation "{PWSH_INTERPRETER}" PWSH_INTERPRETER_PATH
call :rlocation "{PROCESS_WRAPPER}" PROCESS_WRAPPER_PATH
call :rlocation "{CONFIG}" RULES_POWERSHELL_CONFIG
call :rlocation "{MAIN}" RULES_POWERSHELL_MAIN

@REM Powershell tries to cache files in the user's `HOME` directory. When running
@REM tests, try to contain this cache to an isolated location.
Expand All @@ -70,6 +72,6 @@ if defined TEST_TMPDIR (
set "USERPROFILE=%TEST_TMPDIR%\powershell"
)

%PWSH_INTERPRETER% ^
%MAIN% ^
%PWSH_INTERPRETER_PATH% ^
%PROCESS_WRAPPER_PATH% ^
%*
13 changes: 11 additions & 2 deletions powershell/private/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@ fi

runfiles_export_envvars

RULES_POWERSHELL_PWSH_INTERPRETER="$(rlocation "{PWSH_INTERPRETER}")"
RULES_POWERSHELL_PROCESS_WRAPPER="$(rlocation "{PROCESS_WRAPPER}")"
RULES_POWERSHELL_CONFIG="$(rlocation "{CONFIG}")"
RULES_POWERSHELL_MAIN="$(rlocation "{MAIN}")"

export RULES_POWERSHELL_CONFIG
export RULES_POWERSHELL_MAIN

# Powershell tries to cache files in the user's `HOME` directory. When running
# tests, try to contain this cache to an isolated location.
if [[ -n "${TEST_TMPDIR}" ]]; then
export HOME="${TEST_TMPDIR}/powershell"
export USERPROFILE="${TEST_TMPDIR}/powershell"
fi

exec \
"$(rlocation "{PWSH_INTERPRETER}")" \
"$(rlocation "{MAIN}")" \
"${RULES_POWERSHELL_PWSH_INTERPRETER}" \
"${RULES_POWERSHELL_PROCESS_WRAPPER}" \
"$@"
44 changes: 41 additions & 3 deletions powershell/private/powershell.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
PwshInfo = provider(
doc = "A provider for Powershell rules.",
fields = {
"imports": "Depset[str]: The list of rlocation paths to module files (.psm1, .psd1) for PSModulePath setup.",
"srcs": "Depset[File]: The list of source files associated with the powershell target.",
},
)
Expand All @@ -20,13 +21,47 @@ This attribute should be used to list other sh_library rules that provide interp
""",
providers = [PwshInfo],
),
}

LIBRARY_ATTRS = COMMON_ATTRS | {
"srcs": attr.label_list(
doc = "The list of source files that are processed to create the target.",
allow_files = [".ps1", ".psm1", ".psd1"],
),
}

EXECUTABLE_SRCS_ATTR = {
"srcs": attr.label_list(
doc = "The list of source (.ps1) files that are processed to create the target.",
allow_files = [".ps1"],
),
}

def _rlocationpath(file, workspace_name):
if file.short_path.startswith("../"):
return file.short_path[len("../"):]
return "{}/{}".format(workspace_name, file.short_path)

def _pwsh_library_impl(ctx):
# Validate that at most one .psd1 file is provided
psd1_files = [f for f in ctx.files.srcs if f.path.endswith(".psd1")]
if len(psd1_files) > 1:
fail("Only one .psd1 manifest file is allowed per pwsh_library, but found {}: {}".format(
len(psd1_files),
", ".join([f.basename for f in psd1_files]),
))

# Collect module files (.psm1 and .psd1) for PSModulePath setup
module_files = [f for f in ctx.files.srcs if f.path.endswith((".psm1", ".psd1"))]

workspace_name = ctx.label.workspace_name
if not workspace_name:
workspace_name = ctx.workspace_name

# Collect import paths from this target and dependencies
direct_imports = [_rlocationpath(f, workspace_name) for f in module_files]
transitive_imports = []

runfiles = ctx.runfiles(files = ctx.files.srcs + ctx.files.data)

for collection in (ctx.attr.data, ctx.attr.deps):
Expand All @@ -36,6 +71,8 @@ def _pwsh_library_impl(ctx):
ctx.runfiles(transitive_files = target[DefaultInfo].files),
target[DefaultInfo].default_runfiles,
])
if PwshInfo in target:
transitive_imports.append(target[PwshInfo].imports)

return [
DefaultInfo(
Expand All @@ -44,21 +81,22 @@ def _pwsh_library_impl(ctx):
),
PwshInfo(
srcs = depset(ctx.files.srcs),
imports = depset(direct_imports, transitive = transitive_imports),
),
coverage_common.instrumented_files_info(
ctx,
dependency_attributes = ["deps"],
extensions = ["py"],
extensions = ["ps1", "psm1", "psd1"],
source_attributes = ["srcs"],
),
]

pwsh_library = rule(
doc = """\
The main use for this rule is to aggregate together a logical
"library" consisting of related scripts.
"library" consisting of related scripts and modules.
""",
implementation = _pwsh_library_impl,
attrs = COMMON_ATTRS,
attrs = LIBRARY_ATTRS,
provides = [PwshInfo],
)
Loading
Loading