From 2af45bb78922394f7301f0e92a39df888f55594b Mon Sep 17 00:00:00 2001 From: Igor Zhalkin Date: Wed, 7 Aug 2024 11:01:34 +0300 Subject: [PATCH] Implement 'BuildDependencyTree' for Conan --- .github/workflows/test.yml | 2 + commands/audit/sca/conan/conan.go | 143 +++ commands/audit/sca/conan/conan_test.go | 58 + tests/testdata/other/conan/dependencies.json | 1015 +++++++++++++++++ .../package-managers/conan/conanfile.txt | 4 + utils/techutils/techutils.go | 7 + 6 files changed, 1229 insertions(+) create mode 100644 commands/audit/sca/conan/conan.go create mode 100644 commands/audit/sca/conan/conan_test.go create mode 100644 tests/testdata/other/conan/dependencies.json create mode 100644 tests/testdata/projects/package-managers/conan/conanfile.txt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec140b5e..7e0a0cc4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -60,6 +60,8 @@ jobs: run: python -m pip install pipenv - name: Setup Poetry run: python -m pip install poetry + - name: Setup Conan + run: python -m pip install conan - name: Setup Gradle uses: gradle/gradle-build-action@v2 with: diff --git a/commands/audit/sca/conan/conan.go b/commands/audit/sca/conan/conan.go new file mode 100644 index 00000000..22c80b80 --- /dev/null +++ b/commands/audit/sca/conan/conan.go @@ -0,0 +1,143 @@ +package conan + +import ( + "encoding/json" + "errors" + "fmt" + "os/exec" + + "github.com/jfrog/gofrog/io" + "github.com/jfrog/jfrog-client-go/utils/errorutils" + xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils" + + "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" + + "github.com/jfrog/jfrog-client-go/utils/log" + + "github.com/jfrog/jfrog-cli-security/utils" +) + +const ( + PackageTypeIdentifier = "conan://" +) + +func BuildDependencyTree(params utils.AuditParams) (dependencyTrees []*xrayUtils.GraphNode, uniqueDeps []string, err error) { + // Prepare + currentDir, err := coreutils.GetWorkingDirectory() + if err != nil { + return + } + conanExecPath, err := getConanExecPath() + if err != nil { + return + } + // Build + return calculateDependencies(conanExecPath, currentDir, params) +} + +func getConanExecPath() (conanExecPath string, err error) { + if conanExecPath, err = exec.LookPath("conan"); errorutils.CheckError(err) != nil { + return + } + if conanExecPath == "" { + err = errors.New("could not find the 'conan' executable in the system PATH") + return + } + log.Debug("Using Conan executable:", conanExecPath) + // Validate conan version command + version, err := getConanCmd(conanExecPath, "", "--version").RunWithOutput() + if errorutils.CheckError(err) != nil { + return + } + log.Debug("Conan version:", string(version)) + return +} + +func getConanCmd(conanExecPath, workingDir, cmd string, args ...string) *io.Command { + command := io.NewCommand(conanExecPath, cmd, args) + command.Dir = workingDir + return command +} + +type conanDep struct { + Ref string `json:"ref"` + Direct bool `json:"direct"` +} + +type conanRef struct { + Ref string `json:"ref"` + Name string `json:"name"` + Version string `json:"version"` + Dependencies map[string]conanDep `json:"dependencies"` + node *xrayUtils.GraphNode +} + +func (cr *conanRef) Node() *xrayUtils.GraphNode { + if cr.node == nil { + cr.node = &xrayUtils.GraphNode{Id: cr.NodeName()} + } + return cr.node +} + +func (cr *conanRef) NodeName() string { + return PackageTypeIdentifier + cr.Name + ":" + cr.Version +} + +type conanGraphOutput struct { + Graph struct { + Nodes map[string]conanRef `json:"nodes"` + } `json:"graph"` +} + +func calculateDependencies(executablePath, workingDir string, params utils.AuditParams) (dependencyTrees []*xrayUtils.GraphNode, uniqueDeps []string, err error) { + graphInfo := append([]string{"info", ".", "--format=json"}, params.Args()...) + conanGraphInfoContent, err := getConanCmd(executablePath, workingDir, "graph", graphInfo...).RunWithOutput() + if err != nil { + return + } + + log.Debug("Conan 'graph info' command output:\n", string(conanGraphInfoContent)) + var output conanGraphOutput + if err = json.Unmarshal(conanGraphInfoContent, &output); err != nil { + return + } + + rootNode, err := parseConanDependencyGraph("0", output.Graph.Nodes) + if err != nil { + return + } + dependencyTrees = append(dependencyTrees, rootNode) + + for id, dep := range output.Graph.Nodes { + if id == "0" { + continue + } + uniqueDeps = append(uniqueDeps, dep.NodeName()) + } + + return +} + +func parseConanDependencyGraph(id string, graph map[string]conanRef) (*xrayUtils.GraphNode, error) { + var childrenNodes []*xrayUtils.GraphNode + node, ok := graph[id] + if !ok { + return nil, errors.New(fmt.Sprintf("got non-existant node id %s", id)) + } + for key, dep := range node.Dependencies { + if !dep.Direct { + continue + } + r, err := parseConanDependencyGraph(key, graph) + if err != nil { + return nil, err + } + childrenNodes = append(childrenNodes, r) + } + if id == "0" { + return &xrayUtils.GraphNode{Id: "root", Nodes: childrenNodes}, nil + } else { + node.Node().Nodes = childrenNodes + return node.Node(), nil + } +} diff --git a/commands/audit/sca/conan/conan_test.go b/commands/audit/sca/conan/conan_test.go new file mode 100644 index 00000000..36e7d102 --- /dev/null +++ b/commands/audit/sca/conan/conan_test.go @@ -0,0 +1,58 @@ +package conan + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "testing" + + xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils" + "github.com/stretchr/testify/assert" + + "github.com/jfrog/jfrog-cli-core/v2/utils/tests" + "github.com/jfrog/jfrog-cli-security/commands/audit/sca" + "github.com/jfrog/jfrog-cli-security/utils" +) + +var expectedResult = &xrayUtils.GraphNode{ + Id: "root", + Nodes: []*xrayUtils.GraphNode{ + {Id: "conan://zlib:1.3.1"}, + {Id: "conan://openssl:3.0.9", Nodes: []*xrayUtils.GraphNode{{Id: "conan://zlib:1.3.1"}}}, + {Id: "conan://meson:1.4.1", Nodes: []*xrayUtils.GraphNode{{Id: "conan://ninja:1.11.1"}}}, + }, +} + +func TestParseConanDependencyTree(t *testing.T) { + _, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("other", "conan")) + defer cleanUp() + dependenciesJson, err := os.ReadFile("dependencies.json") + assert.NoError(t, err) + output := struct { + Graph struct { + Nodes map[string]conanRef `json:"nodes"` + } `json:"graph"` + }{} + + err = json.Unmarshal(dependenciesJson, &output) + + graph, err := parseConanDependencyGraph("0", output.Graph.Nodes) + assert.NoError(t, err) + if !tests.CompareTree(expectedResult, graph) { + t.Error(fmt.Sprintf("expected %+v, got: %+v", expectedResult.Nodes, graph)) + } +} + +func TestBuildDependencyTree(t *testing.T) { + _, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "conan")) + defer cleanUp() + expectedUniqueDeps := []string{"conan://openssl:3.0.9", "conan://zlib:1.3.1", "conan://meson:1.4.1", "conan://ninja:1.11.1"} + params := &utils.AuditBasicParams{} + graph, uniqueDeps, err := BuildDependencyTree(params) + assert.NoError(t, err) + if !tests.CompareTree(expectedResult, graph[0]) { + t.Error(fmt.Sprintf("expected %+v, got: %+v", expectedResult.Nodes, graph)) + } + assert.ElementsMatch(t, uniqueDeps, expectedUniqueDeps, "First is actual, Second is Expected") +} diff --git a/tests/testdata/other/conan/dependencies.json b/tests/testdata/other/conan/dependencies.json new file mode 100644 index 00000000..307119d6 --- /dev/null +++ b/tests/testdata/other/conan/dependencies.json @@ -0,0 +1,1015 @@ +{ + "graph": { + "nodes": { + "0": { + "ref": "conanfile", + "id": "0", + "recipe": "Consumer", + "package_id": null, + "prev": null, + "rrev": null, + "rrev_timestamp": null, + "prev_timestamp": null, + "remote": null, + "binary_remote": null, + "build_id": null, + "binary": null, + "invalid_build": false, + "info_invalid": null, + "name": null, + "user": null, + "channel": null, + "url": null, + "license": null, + "author": null, + "description": null, + "homepage": null, + "build_policy": null, + "upload_policy": null, + "revision_mode": "hash", + "provides": null, + "deprecated": null, + "win_bash": null, + "win_bash_run": null, + "default_options": null, + "options_description": null, + "version": null, + "topics": null, + "package_type": "unknown", + "settings": { + "os": "Linux", + "arch": "x86_64", + "compiler": "gcc", + "compiler.cppstd": "gnu17", + "compiler.libcxx": "libstdc++11", + "compiler.version": "11", + "build_type": "Release" + }, + "options": {}, + "options_definitions": {}, + "generators": [], + "python_requires": null, + "system_requires": {}, + "recipe_folder": null, + "source_folder": null, + "build_folder": null, + "generators_folder": null, + "package_folder": null, + "cpp_info": { + "root": { + "includedirs": [ + "include" + ], + "srcdirs": null, + "libdirs": [ + "lib" + ], + "resdirs": null, + "bindirs": [ + "bin" + ], + "builddirs": null, + "frameworkdirs": null, + "system_libs": null, + "frameworks": null, + "libs": null, + "defines": null, + "cflags": null, + "cxxflags": null, + "sharedlinkflags": null, + "exelinkflags": null, + "objects": null, + "sysroot": null, + "requires": null, + "properties": null + } + }, + "conf_info": {}, + "label": "conanfile.txt", + "dependencies": { + "2": { + "ref": "openssl/3.0.9", + "run": false, + "libs": true, + "skip": false, + "test": false, + "force": false, + "direct": true, + "build": false, + "transitive_headers": null, + "transitive_libs": null, + "headers": true, + "package_id_mode": null, + "visible": true + }, + "1": { + "ref": "zlib/1.3.1", + "run": false, + "libs": true, + "skip": false, + "test": false, + "force": false, + "direct": true, + "build": false, + "transitive_headers": null, + "transitive_libs": null, + "headers": true, + "package_id_mode": null, + "visible": true + }, + "3": { + "ref": "meson/1.4.1", + "run": true, + "libs": false, + "skip": false, + "test": false, + "force": false, + "direct": true, + "build": false, + "transitive_headers": null, + "transitive_libs": null, + "headers": false, + "package_id_mode": null, + "visible": true + }, + "4": { + "ref": "ninja/1.11.1", + "run": true, + "libs": false, + "skip": false, + "test": false, + "force": false, + "direct": false, + "build": false, + "transitive_headers": null, + "transitive_libs": null, + "headers": false, + "package_id_mode": null, + "visible": true + } + }, + "context": "host", + "test": false + }, + "1": { + "ref": "zlib/1.3.1#f52e03ae3d251dec704634230cd806a2", + "id": "1", + "recipe": "Cache", + "package_id": "b647c43bfefae3f830561ca202b6cfd935b56205", + "prev": "6b307bbcbae23635c4006543ffdbf3ef", + "rrev": "f52e03ae3d251dec704634230cd806a2", + "rrev_timestamp": 1708593606.497, + "prev_timestamp": 1708593932.513, + "remote": null, + "binary_remote": null, + "build_id": null, + "binary": "Cache", + "invalid_build": false, + "info_invalid": null, + "name": "zlib", + "user": null, + "channel": null, + "url": "https://github.com/conan-io/conan-center-index", + "license": "Zlib", + "author": null, + "description": "A Massively Spiffy Yet Delicately Unobtrusive Compression Library (Also Free, Not to Mention Unencumbered by Patents)", + "homepage": "https://zlib.net", + "build_policy": null, + "upload_policy": null, + "revision_mode": "hash", + "provides": null, + "deprecated": null, + "win_bash": null, + "win_bash_run": null, + "default_options": { + "shared": false, + "fPIC": true + }, + "options_description": null, + "version": "1.3.1", + "topics": [ + "zlib", + "compression" + ], + "package_type": "static-library", + "settings": { + "os": "Linux", + "arch": "x86_64", + "compiler": "gcc", + "compiler.version": "11", + "build_type": "Release" + }, + "options": { + "fPIC": "True", + "shared": "False" + }, + "options_definitions": { + "shared": [ + "True", + "False" + ], + "fPIC": [ + "True", + "False" + ] + }, + "generators": [], + "python_requires": null, + "system_requires": {}, + "recipe_folder": "/home/igorz/.conan2/p/zlib41bd3946e7341/e", + "source_folder": null, + "build_folder": null, + "generators_folder": null, + "package_folder": null, + "cpp_info": { + "root": { + "includedirs": [ + "include" + ], + "srcdirs": null, + "libdirs": [ + "lib" + ], + "resdirs": null, + "bindirs": [ + "bin" + ], + "builddirs": null, + "frameworkdirs": null, + "system_libs": null, + "frameworks": null, + "libs": null, + "defines": null, + "cflags": null, + "cxxflags": null, + "sharedlinkflags": null, + "exelinkflags": null, + "objects": null, + "sysroot": null, + "requires": null, + "properties": null + } + }, + "conf_info": {}, + "label": "zlib/1.3.1", + "info": { + "settings": { + "os": "Linux", + "arch": "x86_64", + "compiler": "gcc", + "compiler.version": "11", + "build_type": "Release" + }, + "options": { + "fPIC": "True", + "shared": "False" + } + }, + "dependencies": {}, + "context": "host", + "test": false + }, + "2": { + "ref": "openssl/3.0.9#c0aed0c748042543804c1068b15af8be", + "id": "2", + "recipe": "Cache", + "package_id": "fe4d597c52cdcc27f4287fc64eff4cd5145db56e", + "prev": "140c7350081c24b72abe8a50e9381e46", + "rrev": "c0aed0c748042543804c1068b15af8be", + "rrev_timestamp": 1696808387.467, + "prev_timestamp": 1696832245.358, + "remote": null, + "binary_remote": null, + "build_id": null, + "binary": "Cache", + "invalid_build": false, + "info_invalid": null, + "name": "openssl", + "user": null, + "channel": null, + "url": "https://github.com/conan-io/conan-center-index", + "license": "Apache-2.0", + "author": null, + "description": "A toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols", + "homepage": "https://github.com/openssl/openssl", + "build_policy": null, + "upload_policy": null, + "revision_mode": "hash", + "provides": null, + "deprecated": null, + "win_bash": null, + "win_bash_run": null, + "default_options": { + "shared": false, + "fPIC": true, + "enable_weak_ssl_ciphers": false, + "386": false, + "capieng_dialog": false, + "enable_capieng": false, + "no_aria": false, + "no_asm": false, + "no_async": false, + "no_blake2": false, + "no_bf": false, + "no_camellia": false, + "no_chacha": false, + "no_cms": false, + "no_comp": false, + "no_ct": false, + "no_cast": false, + "no_deprecated": false, + "no_des": false, + "no_dgram": false, + "no_dh": false, + "no_dsa": false, + "no_dso": false, + "no_ec": false, + "no_ecdh": false, + "no_ecdsa": false, + "no_engine": false, + "no_filenames": false, + "no_fips": false, + "no_gost": false, + "no_idea": false, + "no_legacy": false, + "no_md2": true, + "no_md4": false, + "no_mdc2": false, + "no_module": false, + "no_ocsp": false, + "no_pinshared": false, + "no_rc2": false, + "no_rc4": false, + "no_rc5": false, + "no_rfc3779": false, + "no_rmd160": false, + "no_sm2": false, + "no_sm3": false, + "no_sm4": false, + "no_srp": false, + "no_srtp": false, + "no_sse2": false, + "no_ssl": false, + "no_stdio": false, + "no_seed": false, + "no_sock": false, + "no_ssl3": false, + "no_threads": false, + "no_tls1": false, + "no_ts": false, + "no_whirlpool": false, + "no_zlib": false, + "openssldir": null + }, + "options_description": null, + "version": "3.0.9", + "topics": [ + "ssl", + "tls", + "encryption", + "security" + ], + "package_type": "static-library", + "settings": { + "os": "Linux", + "arch": "x86_64", + "compiler": "gcc", + "compiler.version": "11", + "build_type": "Release" + }, + "options": { + "386": "False", + "enable_weak_ssl_ciphers": "False", + "fPIC": "True", + "no_aria": "False", + "no_asm": "False", + "no_async": "False", + "no_bf": "False", + "no_blake2": "False", + "no_camellia": "False", + "no_cast": "False", + "no_chacha": "False", + "no_cms": "False", + "no_comp": "False", + "no_ct": "False", + "no_deprecated": "False", + "no_des": "False", + "no_dgram": "False", + "no_dh": "False", + "no_dsa": "False", + "no_dso": "False", + "no_ec": "False", + "no_ecdh": "False", + "no_ecdsa": "False", + "no_engine": "False", + "no_filenames": "False", + "no_fips": "False", + "no_gost": "False", + "no_idea": "False", + "no_legacy": "False", + "no_md2": "True", + "no_md4": "False", + "no_mdc2": "False", + "no_module": "False", + "no_ocsp": "False", + "no_pinshared": "False", + "no_rc2": "False", + "no_rc4": "False", + "no_rc5": "False", + "no_rfc3779": "False", + "no_rmd160": "False", + "no_seed": "False", + "no_sm2": "False", + "no_sm3": "False", + "no_sm4": "False", + "no_sock": "False", + "no_srp": "False", + "no_srtp": "False", + "no_sse2": "False", + "no_ssl": "False", + "no_ssl3": "False", + "no_stdio": "False", + "no_threads": "False", + "no_tls1": "False", + "no_ts": "False", + "no_whirlpool": "False", + "no_zlib": "False", + "openssldir": null, + "shared": "False" + }, + "options_definitions": { + "shared": [ + "True", + "False" + ], + "fPIC": [ + "True", + "False" + ], + "enable_weak_ssl_ciphers": [ + "True", + "False" + ], + "386": [ + "True", + "False" + ], + "no_aria": [ + "True", + "False" + ], + "no_asm": [ + "True", + "False" + ], + "no_async": [ + "True", + "False" + ], + "no_blake2": [ + "True", + "False" + ], + "no_bf": [ + "True", + "False" + ], + "no_camellia": [ + "True", + "False" + ], + "no_chacha": [ + "True", + "False" + ], + "no_cms": [ + "True", + "False" + ], + "no_comp": [ + "True", + "False" + ], + "no_ct": [ + "True", + "False" + ], + "no_cast": [ + "True", + "False" + ], + "no_deprecated": [ + "True", + "False" + ], + "no_des": [ + "True", + "False" + ], + "no_dgram": [ + "True", + "False" + ], + "no_dh": [ + "True", + "False" + ], + "no_dsa": [ + "True", + "False" + ], + "no_dso": [ + "True", + "False" + ], + "no_ec": [ + "True", + "False" + ], + "no_ecdh": [ + "True", + "False" + ], + "no_ecdsa": [ + "True", + "False" + ], + "no_engine": [ + "True", + "False" + ], + "no_filenames": [ + "True", + "False" + ], + "no_fips": [ + "True", + "False" + ], + "no_gost": [ + "True", + "False" + ], + "no_idea": [ + "True", + "False" + ], + "no_legacy": [ + "True", + "False" + ], + "no_md2": [ + "True", + "False" + ], + "no_md4": [ + "True", + "False" + ], + "no_mdc2": [ + "True", + "False" + ], + "no_module": [ + "True", + "False" + ], + "no_ocsp": [ + "True", + "False" + ], + "no_pinshared": [ + "True", + "False" + ], + "no_rc2": [ + "True", + "False" + ], + "no_rc4": [ + "True", + "False" + ], + "no_rc5": [ + "True", + "False" + ], + "no_rfc3779": [ + "True", + "False" + ], + "no_rmd160": [ + "True", + "False" + ], + "no_sm2": [ + "True", + "False" + ], + "no_sm3": [ + "True", + "False" + ], + "no_sm4": [ + "True", + "False" + ], + "no_srp": [ + "True", + "False" + ], + "no_srtp": [ + "True", + "False" + ], + "no_sse2": [ + "True", + "False" + ], + "no_ssl": [ + "True", + "False" + ], + "no_stdio": [ + "True", + "False" + ], + "no_seed": [ + "True", + "False" + ], + "no_sock": [ + "True", + "False" + ], + "no_ssl3": [ + "True", + "False" + ], + "no_threads": [ + "True", + "False" + ], + "no_tls1": [ + "True", + "False" + ], + "no_ts": [ + "True", + "False" + ], + "no_whirlpool": [ + "True", + "False" + ], + "no_zlib": [ + "True", + "False" + ], + "openssldir": [ + null, + "ANY" + ] + }, + "generators": [], + "python_requires": null, + "system_requires": {}, + "recipe_folder": "/home/igorz/.conan2/p/opensd7bdf135944e1/e", + "source_folder": null, + "build_folder": null, + "generators_folder": null, + "package_folder": null, + "cpp_info": { + "root": { + "includedirs": [ + "include" + ], + "srcdirs": null, + "libdirs": [ + "lib" + ], + "resdirs": null, + "bindirs": [ + "bin" + ], + "builddirs": null, + "frameworkdirs": null, + "system_libs": null, + "frameworks": null, + "libs": null, + "defines": null, + "cflags": null, + "cxxflags": null, + "sharedlinkflags": null, + "exelinkflags": null, + "objects": null, + "sysroot": null, + "requires": null, + "properties": null + } + }, + "conf_info": {}, + "label": "openssl/3.0.9", + "info": { + "settings": { + "os": "Linux", + "arch": "x86_64", + "compiler": "gcc", + "compiler.version": "11", + "build_type": "Release" + }, + "options": { + "386": "False", + "enable_weak_ssl_ciphers": "False", + "fPIC": "True", + "no_aria": "False", + "no_asm": "False", + "no_async": "False", + "no_bf": "False", + "no_blake2": "False", + "no_camellia": "False", + "no_cast": "False", + "no_chacha": "False", + "no_cms": "False", + "no_comp": "False", + "no_ct": "False", + "no_deprecated": "False", + "no_des": "False", + "no_dgram": "False", + "no_dh": "False", + "no_dsa": "False", + "no_dso": "False", + "no_ec": "False", + "no_ecdh": "False", + "no_ecdsa": "False", + "no_engine": "False", + "no_filenames": "False", + "no_fips": "False", + "no_gost": "False", + "no_idea": "False", + "no_legacy": "False", + "no_md2": "True", + "no_md4": "False", + "no_mdc2": "False", + "no_module": "False", + "no_ocsp": "False", + "no_pinshared": "False", + "no_rc2": "False", + "no_rc4": "False", + "no_rc5": "False", + "no_rfc3779": "False", + "no_rmd160": "False", + "no_seed": "False", + "no_sm2": "False", + "no_sm3": "False", + "no_sm4": "False", + "no_sock": "False", + "no_srp": "False", + "no_srtp": "False", + "no_sse2": "False", + "no_ssl": "False", + "no_ssl3": "False", + "no_stdio": "False", + "no_threads": "False", + "no_tls1": "False", + "no_ts": "False", + "no_whirlpool": "False", + "no_zlib": "False", + "openssldir": null, + "shared": "False" + }, + "requires": [ + "zlib/1.3.Z" + ] + }, + "dependencies": { + "1": { + "ref": "zlib/1.3.1", + "run": false, + "libs": true, + "skip": false, + "test": false, + "force": false, + "direct": true, + "build": false, + "transitive_headers": null, + "transitive_libs": null, + "headers": true, + "package_id_mode": "minor_mode", + "visible": true + } + }, + "context": "host", + "test": false + }, + "3": { + "ref": "meson/1.4.1#edd3ecbcb4b295d2f084be5bb944f1af", + "id": "3", + "recipe": "Cache", + "package_id": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "prev": "4a43a051838fc016591c956c0389e89e", + "rrev": "edd3ecbcb4b295d2f084be5bb944f1af", + "rrev_timestamp": 1717121413.971, + "prev_timestamp": 1717121751.058, + "remote": null, + "binary_remote": "conancenter", + "build_id": null, + "binary": "Download", + "invalid_build": false, + "info_invalid": null, + "name": "meson", + "user": null, + "channel": null, + "url": "https://github.com/conan-io/conan-center-index", + "license": "Apache-2.0", + "author": null, + "description": "Meson is a project to create the best possible next-generation build system", + "homepage": "https://github.com/mesonbuild/meson", + "build_policy": null, + "upload_policy": null, + "revision_mode": "hash", + "provides": null, + "deprecated": null, + "win_bash": null, + "win_bash_run": null, + "default_options": null, + "options_description": null, + "version": "1.4.1", + "topics": [ + "meson", + "mesonbuild", + "build-system" + ], + "package_type": "application", + "settings": {}, + "options": {}, + "options_definitions": {}, + "generators": [], + "python_requires": null, + "system_requires": {}, + "recipe_folder": "/home/igorz/.conan2/p/mesondba9cc745bd8c/e", + "source_folder": null, + "build_folder": null, + "generators_folder": null, + "package_folder": null, + "cpp_info": { + "root": { + "includedirs": [ + "include" + ], + "srcdirs": null, + "libdirs": [ + "lib" + ], + "resdirs": null, + "bindirs": [ + "bin" + ], + "builddirs": null, + "frameworkdirs": null, + "system_libs": null, + "frameworks": null, + "libs": null, + "defines": null, + "cflags": null, + "cxxflags": null, + "sharedlinkflags": null, + "exelinkflags": null, + "objects": null, + "sysroot": null, + "requires": null, + "properties": null + } + }, + "conf_info": {}, + "label": "meson/1.4.1", + "info": {}, + "dependencies": { + "4": { + "ref": "ninja/1.11.1", + "run": true, + "libs": false, + "skip": false, + "test": false, + "force": false, + "direct": true, + "build": false, + "transitive_headers": null, + "transitive_libs": null, + "headers": false, + "package_id_mode": null, + "visible": true + } + }, + "context": "host", + "test": false + }, + "4": { + "ref": "ninja/1.11.1#77587f8c8318662ac8e5a7867eb4be21", + "id": "4", + "recipe": "Cache", + "package_id": "3593751651824fb813502c69c971267624ced41a", + "prev": "60e6fc0f973babfbed66a66af22a4f02", + "rrev": "77587f8c8318662ac8e5a7867eb4be21", + "rrev_timestamp": 1684431244.21, + "prev_timestamp": 1684431632.795, + "remote": null, + "binary_remote": "conancenter", + "build_id": null, + "binary": "Download", + "invalid_build": false, + "info_invalid": null, + "name": "ninja", + "user": null, + "channel": null, + "url": "https://github.com/conan-io/conan-center-index", + "license": "Apache-2.0", + "author": null, + "description": "Ninja is a small build system with a focus on speed", + "homepage": "https://github.com/ninja-build/ninja", + "build_policy": null, + "upload_policy": null, + "revision_mode": "hash", + "provides": null, + "deprecated": null, + "win_bash": null, + "win_bash_run": null, + "default_options": null, + "options_description": null, + "version": "1.11.1", + "topics": [ + "ninja", + "build" + ], + "package_type": "application", + "settings": { + "os": "Linux", + "arch": "x86_64", + "compiler": "gcc", + "compiler.cppstd": "gnu17", + "compiler.libcxx": "libstdc++11", + "compiler.version": "11", + "build_type": "Release" + }, + "options": {}, + "options_definitions": {}, + "generators": [], + "python_requires": null, + "system_requires": {}, + "recipe_folder": "/home/igorz/.conan2/p/ninja19c9f8e277acc/e", + "source_folder": null, + "build_folder": null, + "generators_folder": null, + "package_folder": null, + "cpp_info": { + "root": { + "includedirs": [ + "include" + ], + "srcdirs": null, + "libdirs": [ + "lib" + ], + "resdirs": null, + "bindirs": [ + "bin" + ], + "builddirs": null, + "frameworkdirs": null, + "system_libs": null, + "frameworks": null, + "libs": null, + "defines": null, + "cflags": null, + "cxxflags": null, + "sharedlinkflags": null, + "exelinkflags": null, + "objects": null, + "sysroot": null, + "requires": null, + "properties": null + } + }, + "conf_info": {}, + "label": "ninja/1.11.1", + "info": { + "settings": { + "os": "Linux", + "arch": "x86_64", + "build_type": "Release" + } + }, + "dependencies": {}, + "context": "host", + "test": false + } + }, + "root": { + "0": "None" + }, + "overrides": {}, + "resolved_ranges": {}, + "replaced_requires": {}, + "error": null + } +} \ No newline at end of file diff --git a/tests/testdata/projects/package-managers/conan/conanfile.txt b/tests/testdata/projects/package-managers/conan/conanfile.txt new file mode 100644 index 00000000..dd67a13c --- /dev/null +++ b/tests/testdata/projects/package-managers/conan/conanfile.txt @@ -0,0 +1,4 @@ +[requires] +zlib/1.3.1 +openssl/3.0.9 +meson/1.4.1 \ No newline at end of file diff --git a/utils/techutils/techutils.go b/utils/techutils/techutils.go index 6d6926fe..cb537e60 100644 --- a/utils/techutils/techutils.go +++ b/utils/techutils/techutils.go @@ -37,6 +37,7 @@ const ( Dotnet Technology = "dotnet" Docker Technology = "docker" Oci Technology = "oci" + Conan Technology = "conan" ) const Pypi = "pypi" @@ -48,6 +49,7 @@ const ( GoLang CodeLanguage = "go" Java CodeLanguage = "java" CSharp CodeLanguage = "C#" + CPP CodeLanguage = "C++" ) // Associates a technology with project type (used in config commands for the package-managers). @@ -167,6 +169,11 @@ var technologiesData = map[Technology]TechData{ }, Docker: {}, Oci: {}, + Conan: { + indicators: []string{"conanfile.txt", "conanfile.py "}, + packageDescriptors: []string{"conanfile.txt", "conanfile.py "}, + formal: "Conan", + }, } var (