Beispiel #1
0
async def package_go_binary(field_set: GoBinaryFieldSet) -> BuiltPackage:
    main_pkg = await Get(GoBinaryMainPackage, GoBinaryMainPackageRequest(field_set.main))
    built_package = await Get(
        BuiltGoPackage, BuildGoPackageTargetRequest(main_pkg.address, is_main=True)
    )
    main_pkg_a_file_path = built_package.import_paths_to_pkg_a_files["main"]
    import_config = await Get(
        ImportConfig, ImportConfigRequest(built_package.import_paths_to_pkg_a_files)
    )
    input_digest = await Get(Digest, MergeDigests([built_package.digest, import_config.digest]))

    output_filename = PurePath(field_set.output_path.value_or_default(file_ending=None))
    binary = await Get(
        LinkedGoBinary,
        LinkGoBinaryRequest(
            input_digest=input_digest,
            archives=(main_pkg_a_file_path,),
            import_config_path=import_config.CONFIG_PATH,
            output_filename=f"./{output_filename.name}",
            description=f"Link Go binary for {field_set.address}",
        ),
    )

    renamed_output_digest = await Get(Digest, AddPrefix(binary.digest, str(output_filename.parent)))

    artifact = BuiltPackageArtifact(relpath=str(output_filename))
    return BuiltPackage(renamed_output_digest, (artifact,))
Beispiel #2
0
async def inject_go_binary_main_dependency(
    request: InjectGoBinaryMainDependencyRequest, ) -> InjectedDependencies:
    wrapped_tgt = await Get(WrappedTarget, Address,
                            request.dependencies_field.address)
    main_pkg = await Get(
        GoBinaryMainPackage,
        GoBinaryMainPackageRequest(
            wrapped_tgt.target[GoBinaryMainPackageField]),
    )
    return InjectedDependencies([main_pkg.address])
 def get_main(addr: Address) -> Address:
     tgt = rule_runner.get_target(addr)
     main_addr = rule_runner.request(
         GoBinaryMainPackage,
         [GoBinaryMainPackageRequest(tgt[GoBinaryMainPackageField])
          ]).address
     injected_addresses = rule_runner.request(
         InjectedDependencies,
         [InjectGoBinaryMainDependencyRequest(tgt[Dependencies])])
     assert [main_addr] == list(injected_addresses)
     return main_addr
Beispiel #4
0
async def find_putative_go_targets(
        request: PutativeGoTargetsRequest,
        all_owned_sources: AllOwnedSources) -> PutativeTargets:
    putative_targets = []

    # Add `go_mod` targets.
    all_go_mod_files = await Get(Paths, PathGlobs,
                                 request.search_paths.path_globs("go.mod"))
    unowned_go_mod_files = set(all_go_mod_files.files) - set(all_owned_sources)
    for dirname, filenames in group_by_dir(unowned_go_mod_files).items():
        putative_targets.append(
            PutativeTarget.for_target_type(
                GoModTarget,
                path=dirname,
                name=os.path.basename(dirname),
                triggering_sources=sorted(filenames),
            ))

    # Add `go_binary` targets.
    digest_contents = await Get(DigestContents, PathGlobs,
                                request.search_paths.path_globs("*.go"))
    main_package_dirs = [
        os.path.dirname(file_content.path) for file_content in digest_contents
        if has_package_main(file_content.content)
    ]
    existing_targets = await Get(
        UnexpandedTargets,
        AddressSpecs(AscendantAddresses(d) for d in main_package_dirs))
    owned_main_packages = await MultiGet(
        Get(GoBinaryMainPackage,
            GoBinaryMainPackageRequest(t[GoBinaryMainPackageField]))
        for t in existing_targets if t.has_field(GoBinaryMainPackageField))
    unowned_main_package_dirs = set(main_package_dirs) - {
        # We can be confident `go_first_party_package` targets were generated, meaning that the
        # below will get us the full path to the package's directory.
        # TODO: generalize this
        os.path.join(pkg.address.spec_path,
                     pkg.address.generated_name[2:]).rstrip(
                         "/")  # type: ignore[index]
        for pkg in owned_main_packages
    }
    putative_targets.extend(
        PutativeTarget.for_target_type(
            target_type=GoBinaryTarget,
            path=main_pkg_dir,
            name="bin",
            triggering_sources=tuple(),
            kwargs={"name": "bin"},
        ) for main_pkg_dir in unowned_main_package_dirs)

    return PutativeTargets(putative_targets)
Beispiel #5
0
async def inject_go_binary_main_dependency(
    request: InjectGoBinaryMainDependencyRequest,
) -> InjectedDependencies:
    wrapped_tgt = await Get(
        WrappedTarget,
        WrappedTargetRequest(
            request.dependencies_field.address, description_of_origin="<infallible>"
        ),
    )
    main_pkg = await Get(
        GoBinaryMainPackage,
        GoBinaryMainPackageRequest(wrapped_tgt.target[GoBinaryMainPackageField]),
    )
    return InjectedDependencies([main_pkg.address])
Beispiel #6
0
async def find_putative_go_targets(
    request: PutativeGoTargetsRequest,
    all_owned_sources: AllOwnedSources,
    golang_subsystem: GolangSubsystem,
) -> PutativeTargets:
    putative_targets = []
    _all_go_mod_paths = await Get(Paths, PathGlobs,
                                  request.path_globs("go.mod"))
    all_go_mod_files = set(_all_go_mod_paths.files)
    all_go_mod_dirs = {os.path.dirname(fp) for fp in all_go_mod_files}

    if golang_subsystem.tailor_go_mod_targets:
        unowned_go_mod_files = all_go_mod_files - set(all_owned_sources)
        for dirname, filenames in group_by_dir(unowned_go_mod_files).items():
            putative_targets.append(
                PutativeTarget.for_target_type(
                    GoModTarget,
                    path=dirname,
                    name=None,
                    triggering_sources=sorted(filenames),
                ))

    if golang_subsystem.tailor_package_targets:
        all_go_files = await Get(Paths, PathGlobs, request.path_globs("*.go"))
        unowned_go_files = set(all_go_files.files) - set(all_owned_sources)
        for dirname, filenames in group_by_dir(unowned_go_files).items():
            # Ignore paths that have `testdata` or `vendor` in them.
            # From `go help packages`: Note, however, that a directory named vendor that itself
            # contains code is not a vendored package: cmd/vendor would be a command named vendor.
            dirname_parts = PurePath(dirname).parts
            if "testdata" in dirname_parts or "vendor" in dirname_parts[0:-1]:
                continue
            if not has_go_mod_ancestor(dirname, all_go_mod_dirs):
                continue
            putative_targets.append(
                PutativeTarget.for_target_type(
                    GoPackageTarget,
                    path=dirname,
                    name=None,
                    triggering_sources=sorted(filenames),
                ))

    if golang_subsystem.tailor_binary_targets:
        all_go_files_digest_contents = await Get(DigestContents, PathGlobs,
                                                 request.path_globs("*.go"))

        main_package_dirs = []
        for file_content in all_go_files_digest_contents:
            dirname = os.path.dirname(file_content.path)
            if has_package_main(file_content.content) and has_go_mod_ancestor(
                    dirname, all_go_mod_dirs):
                main_package_dirs.append(dirname)

        existing_targets = await Get(
            UnexpandedTargets,
            RawSpecs(
                ancestor_globs=tuple(
                    AncestorGlobSpec(d) for d in main_package_dirs),
                description_of_origin="the `go_binary` tailor rule",
            ),
        )
        owned_main_packages = await MultiGet(
            Get(GoBinaryMainPackage,
                GoBinaryMainPackageRequest(t[GoBinaryMainPackageField]))
            for t in existing_targets if t.has_field(GoBinaryMainPackageField))
        unowned_main_package_dirs = set(main_package_dirs) - {
            # NB: We assume the `go_package` lives in the directory it's defined, which we validate
            # by e.g. banning `**` in its sources field.
            pkg.address.spec_path
            for pkg in owned_main_packages
        }
        putative_targets.extend(
            PutativeTarget.for_target_type(
                GoBinaryTarget,
                path=main_pkg_dir,
                name="bin",
                triggering_sources=tuple(),
            ) for main_pkg_dir in unowned_main_package_dirs)

    return PutativeTargets(putative_targets)
Beispiel #7
0
async def find_putative_go_targets(
    request: PutativeGoTargetsRequest, all_owned_sources: AllOwnedSources
) -> PutativeTargets:
    putative_targets = []

    all_go_mod_files, all_go_files, all_go_files_digest_contents = await MultiGet(
        Get(Paths, PathGlobs, request.search_paths.path_globs("go.mod")),
        Get(Paths, PathGlobs, request.search_paths.path_globs("*.go")),
        Get(DigestContents, PathGlobs, request.search_paths.path_globs("*.go")),
    )

    # Add `go_mod` targets.
    unowned_go_mod_files = set(all_go_mod_files.files) - set(all_owned_sources)
    for dirname, filenames in group_by_dir(unowned_go_mod_files).items():
        putative_targets.append(
            PutativeTarget.for_target_type(
                GoModTarget,
                path=dirname,
                name=None,
                triggering_sources=sorted(filenames),
            )
        )

    # Add `go_package` targets.
    unowned_go_files = set(all_go_files.files) - set(all_owned_sources)
    for dirname, filenames in group_by_dir(unowned_go_files).items():
        # Ignore paths that have `testdata` or `vendor` in them.
        # From `go help packages`: Note, however, that a directory named vendor that itself contains code
        # is not a vendored package: cmd/vendor would be a command named vendor.
        dirname_parts = PurePath(dirname).parts
        if "testdata" in dirname_parts or "vendor" in dirname_parts[0:-1]:
            continue
        putative_targets.append(
            PutativeTarget.for_target_type(
                GoPackageTarget,
                path=dirname,
                name=None,
                triggering_sources=sorted(filenames),
            )
        )

    # Add `go_binary` targets.
    main_package_dirs = [
        os.path.dirname(file_content.path)
        for file_content in all_go_files_digest_contents
        if has_package_main(file_content.content)
    ]
    existing_targets = await Get(
        UnexpandedTargets, AddressSpecs(AscendantAddresses(d) for d in main_package_dirs)
    )
    owned_main_packages = await MultiGet(
        Get(GoBinaryMainPackage, GoBinaryMainPackageRequest(t[GoBinaryMainPackageField]))
        for t in existing_targets
        if t.has_field(GoBinaryMainPackageField)
    )
    unowned_main_package_dirs = set(main_package_dirs) - {
        # NB: We assume the `go_package` lives in the directory it's defined, which we validate
        # by e.g. banning `**` in its sources field.
        pkg.address.spec_path
        for pkg in owned_main_packages
    }
    putative_targets.extend(
        PutativeTarget.for_target_type(
            GoBinaryTarget,
            path=main_pkg_dir,
            name="bin",
            triggering_sources=tuple(),
        )
        for main_pkg_dir in unowned_main_package_dirs
    )

    return PutativeTargets(putative_targets)