Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

License text in json #117

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
49 changes: 40 additions & 9 deletions rules/gather_licenses_info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,12 @@ def _write_licenses_info_impl(target, ctx):
return [OutputGroupInfo(licenses = depset())]

# Write the output file for the target
name = "%s_licenses_info.json" % ctx.label.name
lic_info, _ = licenses_info_to_json(info)
content = "[\n%s\n]\n" % ",\n".join(lic_info)
out = ctx.actions.declare_file(name)
ctx.actions.write(
output = out,
content = content,
)
outs.append(out)
json_out = ctx.actions.declare_file("%s_licenses_info.json" % ctx.label.name)
licenses_files = write_licenses_info(ctx, target, json_out)
outs.append(json_out)
json_out_full = ctx.actions.declare_file("%s_licenses_info_full.json" % ctx.label.name)
embed_licenses_text(ctx, json_out, licenses_files, json_out_full)
outs.append(json_out_full)

if ctx.attr._trace[TraceInfo].trace:
trace = ctx.actions.declare_file("%s_trace_info.json" % ctx.label.name)
Expand All @@ -100,6 +97,12 @@ gather_licenses_info_and_write = aspect(
attr_aspects = ["*"],
attrs = {
"_trace": attr.label(default = "@rules_license//rules:trace_target"),
"_embed_licenses_text_tool": attr.label(
default = Label("@rules_license//tools:embed_licenses_text"),
executable = True,
allow_files = True,
cfg = "exec",
),
},
provides = [OutputGroupInfo],
requires = [gather_licenses_info],
Expand Down Expand Up @@ -146,6 +149,10 @@ def write_licenses_info(ctx, deps, json_out):
Returns:
A list of License File objects for each of the license paths referenced in the json.
"""

if type(deps) != type([]):
deps = [deps]

licenses_json = []
licenses_files = []
for dep in deps:
Expand All @@ -163,6 +170,30 @@ def write_licenses_info(ctx, deps, json_out):
)
return licenses_files

def embed_licenses_text(ctx, json_in, licenses_files, json_out):
"""Reads the license text from the referenced file and attaches it to the json

Args:
ctx: context of the caller
json_in: input handle to read the JSON info
licenses_files: input handles for all LICENSE files
json_out: output handle to write the JSON info
"""

inputs = [json_in]+licenses_files
outputs = [json_out]
args = ctx.actions.args()
args.add("--licenses_in", json_in.path)
args.add("--licenses_out", json_out.path)
ctx.actions.run(
mnemonic = "EmbedLICENSETexts",
progress_message = "Embedding license texts...",
inputs = inputs,
outputs = outputs,
executable = ctx.executable._embed_licenses_text_tool,
arguments = [args],
)

def licenses_info_to_json(licenses_info):
"""Render a single LicenseInfo provider to JSON

Expand Down
22 changes: 11 additions & 11 deletions rules_gathering/gather_metadata.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,9 @@ def _write_metadata_info_impl(target, ctx):
return [OutputGroupInfo(licenses = depset())]

# Write the output file for the target
name = "%s_metadata_info.json" % ctx.label.name
content = "[\n%s\n]\n" % ",\n".join(metadata_info_to_json(info))
out = ctx.actions.declare_file(name)
ctx.actions.write(
output = out,
content = content,
)
outs.append(out)
json_out = ctx.actions.declare_file("%s_metadata_info.json" % ctx.label.name)
write_metadata_info(ctx, target, json_out)
outs.append(json_out)

if ctx.attr._trace[TraceInfo].trace:
trace = ctx.actions.declare_file("%s_trace_info.json" % ctx.label.name)
Expand Down Expand Up @@ -140,8 +135,8 @@ def write_metadata_info(ctx, deps, json_out):

def _foo_impl(ctx):
...
out = ctx.actions.declare_file("%s_licenses.json" % ctx.label.name)
write_metadata_info(ctx, ctx.attr.deps, metadata_file)
json_file = ctx.actions.declare_file("%s_licenses.json" % ctx.label.name)
write_metadata_info(ctx, ctx.attr.deps, json_file)

Args:
ctx: context of the caller
Expand All @@ -150,10 +145,15 @@ def write_metadata_info(ctx, deps, json_out):
aspect over them
json_out: output handle to write the JSON info
"""

if type(deps) != type([]):
deps = [deps]

licenses = []
for dep in deps:
if TransitiveMetadataInfo in dep:
licenses.extend(metadata_info_to_json(dep[TransitiveMetadataInfo]))
metadata_info = dep[TransitiveMetadataInfo]
licenses.extend(metadata_info_to_json(metadata_info))
ctx.actions.write(
output = json_out,
content = "[\n%s\n]\n" % ",\n".join(licenses),
Expand Down
7 changes: 7 additions & 0 deletions tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ py_binary(
python_version = "PY3",
visibility = ["//visibility:public"],
)

py_binary(
name = "embed_licenses_text",
srcs = ["embed_licenses_text.py"],
python_version = "PY3",
visibility = ["//visibility:public"],
)
30 changes: 30 additions & 0 deletions tools/embed_licenses_text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
import argparse
import codecs
import json


def main():
parser = argparse.ArgumentParser(
description='Demonstraton license compliance checker')

parser.add_argument('--licenses_in', help='path to JSON file containing all license info')
parser.add_argument('--licenses_out', help='path to JSON file where augmented license info should be stored')
args = parser.parse_args()

with codecs.open(args.licenses_in, encoding='utf-8') as inp:
license_data = json.loads(inp.read())

for target in license_data:
for license in target['licenses']:
license_path = license.get('license_text')
if license_path:
with codecs.open(license_path, encoding='utf-8') as license_file:
license['license_text'] = license_file.read()

with codecs.open(args.licenses_out, mode='w', encoding='utf-8') as out:
json.dump(license_data, out, indent=4)


if __name__ == '__main__':
main()