Example #1
0
async def generate_targets_from_go_mod(
    request: GenerateTargetsFromGoModRequest,
    union_membership: UnionMembership,
) -> GeneratedTargets:
    generator_addr = request.generator.address
    go_mod_info = await Get(
        GoModInfo, GoModInfoRequest(request.generator[GoModSourcesField]))
    all_packages = await Get(
        AllThirdPartyPackages,
        AllThirdPartyPackagesRequest(go_mod_info.digest, go_mod_info.mod_path),
    )

    def create_tgt(
            pkg_info: ThirdPartyPkgAnalysis) -> GoThirdPartyPackageTarget:
        return GoThirdPartyPackageTarget(
            {GoImportPathField.alias: pkg_info.import_path},
            # E.g. `src/go:mod#github.com/google/uuid`.
            generator_addr.create_generated(pkg_info.import_path),
            union_membership,
            residence_dir=generator_addr.spec_path,
        )

    return GeneratedTargets(
        request.generator,
        (create_tgt(pkg_info)
         for pkg_info in all_packages.import_paths_to_pkg_info.values()),
    )
Example #2
0
def test_invalid_go_sum(rule_runner: RuleRunner) -> None:
    digest = set_up_go_mod(
        rule_runner,
        dedent("""\
            module example.com/third-party-module
            go 1.17
            require github.com/google/uuid v1.3.0
            """),
        dedent("""\
            github.com/google/uuid v1.3.0 h1:00000gmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
            github.com/google/uuid v1.3.0/go.mod h1:00000e4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
            """),
    )
    with engine_error(ProcessExecutionFailure, contains="SECURITY ERROR"):
        rule_runner.request(AllThirdPartyPackages,
                            [AllThirdPartyPackagesRequest(digest, "go.mod")])
Example #3
0
def test_module_with_no_packages(rule_runner) -> None:
    digest = set_up_go_mod(
        rule_runner,
        dedent("""\
            module example.com/third-party-module
            go 1.17
            require github.com/Azure/go-autorest v13.3.2+incompatible
            """),
        dedent("""\
            github.com/Azure/go-autorest v13.3.2+incompatible h1:VxzPyuhtnlBOzc4IWCZHqpyH2d+QMLQEuy3wREyY4oc=
            github.com/Azure/go-autorest v13.3.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
            """),
    )
    all_packages = rule_runner.request(AllThirdPartyPackages,
                                       [AllThirdPartyPackagesRequest(digest)])
    assert not all_packages.import_paths_to_pkg_info
Example #4
0
def test_missing_go_sum(rule_runner: RuleRunner) -> None:
    digest = set_up_go_mod(
        rule_runner,
        dedent("""\
            module example.com/third-party-module
            go 1.17
            require github.com/google/uuid v1.3.0
            """),
        # `go.sum` is for a different module.
        dedent("""\
            cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
            cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
            """),
    )
    with engine_error(
            contains="github.com/google/[email protected]: missing go.sum entry"):
        rule_runner.request(AllThirdPartyPackages,
                            [AllThirdPartyPackagesRequest(digest, "go.mod")])
Example #5
0
async def generate_targets_from_go_mod(
    request: GenerateTargetsFromGoModRequest,
    union_membership: UnionMembership,
) -> GeneratedTargets:
    generator_addr = request.generator.address
    go_mod_sources = request.generator[GoModSourcesField]
    go_mod_info = await Get(GoModInfo, GoModInfoRequest(go_mod_sources))
    go_mod_snapshot = await Get(Snapshot, Digest, go_mod_info.digest)
    all_packages = await Get(
        AllThirdPartyPackages,
        AllThirdPartyPackagesRequest(go_mod_info.digest, go_mod_info.mod_path),
    )

    def gen_file_tgt(fp: str) -> TargetGeneratorSourcesHelperTarget:
        return TargetGeneratorSourcesHelperTarget(
            {TargetGeneratorSourcesHelperSourcesField.alias: fp},
            generator_addr.create_file(fp),
            union_membership,
        )

    file_tgts = [gen_file_tgt("go.mod")]
    if go_mod_sources.go_sum_path in go_mod_snapshot.files:
        file_tgts.append(gen_file_tgt("go.sum"))

    def create_tgt(pkg_info: ThirdPartyPkgAnalysis) -> GoThirdPartyPackageTarget:
        return GoThirdPartyPackageTarget(
            {
                **request.template,
                GoImportPathField.alias: pkg_info.import_path,
                Dependencies.alias: [t.address.spec for t in file_tgts],
            },
            # E.g. `src/go:mod#github.com/google/uuid`.
            generator_addr.create_generated(pkg_info.import_path),
            union_membership,
            residence_dir=generator_addr.spec_path,
        )

    result = tuple(
        create_tgt(pkg_info) for pkg_info in all_packages.import_paths_to_pkg_info.values()
    ) + tuple(file_tgts)
    return GeneratedTargets(request.generator, result)
Example #6
0
def test_stale_go_mod(rule_runner: RuleRunner) -> None:
    digest = set_up_go_mod(
        rule_runner,
        # Go 1.17+ expects indirect dependencies to be included in the `go.mod`, i.e.
        # `golang.org/x/xerrors `.
        dedent("""\
            module example.com/third-party-module
            go 1.17
            require github.com/google/go-cmp v0.5.6
            """),
        dedent("""\
            github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
            github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
            golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
            golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
            """),
    )
    with engine_error(ProcessExecutionFailure,
                      contains="updates to go.mod needed"):
        rule_runner.request(AllThirdPartyPackages,
                            [AllThirdPartyPackagesRequest(digest, "go.mod")])
Example #7
0
def test_download_and_analyze_all_packages(rule_runner: RuleRunner) -> None:
    input_digest = rule_runner.make_snapshot({
        "go.mod": GO_MOD,
        "go.sum": GO_SUM
    }).digest
    all_packages = rule_runner.request(
        AllThirdPartyPackages,
        [AllThirdPartyPackagesRequest(input_digest, "go.mod")])
    assert set(all_packages.import_paths_to_pkg_info.keys()) == {
        "golang.org/x/text/encoding/japanese",
        "golang.org/x/text/message/catalog",
        "golang.org/x/text/internal/testtext",
        "golang.org/x/text/encoding/ianaindex",
        "golang.org/x/text/cmd/gotext",
        "golang.org/x/text/width",
        "golang.org/x/text/internal/format",
        "rsc.io/sampler",
        "golang.org/x/text/internal/tag",
        "golang.org/x/text/unicode/norm",
        "golang.org/x/text/number",
        "golang.org/x/text/transform",
        "golang.org/x/text/internal",
        "golang.org/x/text/internal/utf8internal",
        "golang.org/x/text/language/display",
        "golang.org/x/text/internal/stringset",
        "golang.org/x/text/encoding/korean",
        "golang.org/x/text/internal/triegen",
        "golang.org/x/text/secure/bidirule",
        "golang.org/x/text/secure/precis",
        "golang.org/x/text/language",
        "golang.org/x/text/encoding/unicode/utf32",
        "golang.org/x/text/internal/colltab",
        "golang.org/x/text/unicode/rangetable",
        "golang.org/x/text/encoding/htmlindex",
        "golang.org/x/text/internal/export/idna",
        "golang.org/x/text/encoding/charmap",
        "golang.org/x/text/unicode/cldr",
        "golang.org/x/text/secure",
        "golang.org/x/text/internal/ucd",
        "golang.org/x/text/feature/plural",
        "golang.org/x/text/unicode",
        "golang.org/x/text/encoding/traditionalchinese",
        "golang.org/x/text/runes",
        "golang.org/x/text/internal/catmsg",
        "rsc.io/quote/buggy",
        "golang.org/x/text/encoding/simplifiedchinese",
        "golang.org/x/text/cases",
        "golang.org/x/text/encoding/internal",
        "github.com/google/uuid",
        "golang.org/x/text/encoding/internal/enctest",
        "golang.org/x/text/collate/build",
        "golang.org/x/text",
        "golang.org/x/text/unicode/bidi",
        "golang.org/x/text/search",
        "golang.org/x/text/unicode/runenames",
        "golang.org/x/text/message",
        "golang.org/x/text/encoding",
        "golang.org/x/text/encoding/unicode",
        "rsc.io/quote",
        "golang.org/x/text/currency",
        "golang.org/x/text/internal/number",
        "golang.org/x/text/collate/tools/colcmp",
        "golang.org/x/text/encoding/internal/identifier",
        "golang.org/x/text/collate",
        "golang.org/x/text/internal/gen",
    }

    def assert_pkg_info(
        import_path: str,
        dir_path: str,
        imports: tuple[str, ...],
        go_files: tuple[str, ...],
        extra_files: tuple[str, ...],
        minimum_go_version: str | None,
    ) -> None:
        assert import_path in all_packages.import_paths_to_pkg_info
        pkg_info = all_packages.import_paths_to_pkg_info[import_path]
        assert pkg_info.import_path == import_path
        assert pkg_info.dir_path == dir_path
        assert pkg_info.imports == imports
        assert pkg_info.go_files == go_files
        assert not pkg_info.s_files
        snapshot = rule_runner.request(Snapshot, [pkg_info.digest])
        assert set(snapshot.files) == {
            os.path.join(dir_path, file_name)
            for file_name in (*go_files, *extra_files)
        }
        assert pkg_info.minimum_go_version == minimum_go_version

    assert_pkg_info(
        import_path="github.com/google/uuid",
        dir_path="gopath/pkg/mod/github.com/google/[email protected]",
        imports=(
            "bytes",
            "crypto/md5",
            "crypto/rand",
            "crypto/sha1",
            "database/sql/driver",
            "encoding/binary",
            "encoding/hex",
            "encoding/json",
            "errors",
            "fmt",
            "hash",
            "io",
            "net",
            "os",
            "strings",
            "sync",
            "time",
        ),
        go_files=(
            "dce.go",
            "doc.go",
            "hash.go",
            "marshal.go",
            "node.go",
            "node_net.go",
            "null.go",
            "sql.go",
            "time.go",
            "util.go",
            "uuid.go",
            "version1.go",
            "version4.go",
        ),
        extra_files=(
            ".travis.yml",
            "CONTRIBUTING.md",
            "CONTRIBUTORS",
            "LICENSE",
            "README.md",
            "go.mod",
            "json_test.go",
            "node_js.go",
            "null_test.go",
            "seq_test.go",
            "sql_test.go",
            "uuid_test.go",
        ),
        minimum_go_version=None,
    )
    assert_pkg_info(
        import_path="golang.org/x/text/unicode/bidi",
        dir_path=
        "gopath/pkg/mod/golang.org/x/[email protected]/unicode/bidi",
        imports=("container/list", "fmt", "log", "sort", "unicode/utf8"),
        go_files=("bidi.go", "bracket.go", "core.go", "prop.go", "tables.go",
                  "trieval.go"),
        extra_files=(
            "core_test.go",
            "gen.go",
            "gen_ranges.go",
            "gen_trieval.go",
            "ranges_test.go",
            "tables_test.go",
        ),
        minimum_go_version=None,
    )
Example #8
0
async def generate_targets_from_go_mod(
    request: GenerateTargetsFromGoModRequest,
    files_not_found_behavior: FilesNotFoundBehavior,
    union_membership: UnionMembership,
) -> GeneratedTargets:
    generator_addr = request.generator.address
    go_mod_info, go_paths = await MultiGet(
        Get(GoModInfo, GoModInfoRequest(generator_addr)),
        Get(
            Paths,
            PathGlobs,
            request.generator[GoModPackageSourcesField].path_globs(
                files_not_found_behavior),
        ),
    )
    all_third_party_packages = await Get(
        AllThirdPartyPackages,
        AllThirdPartyPackagesRequest(go_mod_info.stripped_digest),
    )

    dir_to_filenames = group_by_dir(go_paths.files)
    matched_dirs = [
        dir for dir, filenames in dir_to_filenames.items() if filenames
    ]

    def create_first_party_package_tgt(dir: str) -> GoFirstPartyPackageTarget:
        subpath = fast_relpath(dir, generator_addr.spec_path)
        import_path = f"{go_mod_info.import_path}/{subpath}" if subpath else go_mod_info.import_path

        return GoFirstPartyPackageTarget(
            {
                GoImportPathField.alias:
                import_path,
                GoFirstPartyPackageSubpathField.alias:
                subpath,
                GoFirstPartyPackageSourcesField.alias:
                tuple(
                    sorted(
                        os.path.join(subpath, f)
                        for f in dir_to_filenames[dir])),
            },
            # E.g. `src/go:mod#./subdir`.
            generator_addr.create_generated(f"./{subpath}"),
            union_membership,
            residence_dir=dir,
        )

    first_party_pkgs = (create_first_party_package_tgt(dir)
                        for dir in matched_dirs)

    def create_third_party_package_tgt(
            pkg_info: ThirdPartyPkgInfo) -> GoThirdPartyPackageTarget:
        return GoThirdPartyPackageTarget(
            {GoImportPathField.alias: pkg_info.import_path},
            # E.g. `src/go:mod#github.com/google/uuid`.
            generator_addr.create_generated(pkg_info.import_path),
            union_membership,
            residence_dir=generator_addr.spec_path,
        )

    third_party_pkgs = (create_third_party_package_tgt(pkg_info)
                        for pkg_info in all_third_party_packages.
                        import_paths_to_pkg_info.values())
    return GeneratedTargets(request.generator,
                            (*first_party_pkgs, *third_party_pkgs))