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
2 changes: 1 addition & 1 deletion detect/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ func (e *Engine) recursiveGlob(pattern string) bool {
suffix := parts[1] // e.g. "*.py"

// Use the cached extension set for simple "**/*.ext" patterns
if strings.HasPrefix(suffix, "*.") {
if strings.HasPrefix(suffix, "*.") && strings.Count(suffix, ".") == 1 {
ext := suffix[1:] // ".py"
e.loadFileExts()
return e.fileExts[ext] > 0
Expand Down
149 changes: 149 additions & 0 deletions detect/research_tools_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package detect

import "testing"

func TestResearchToolsProject(t *testing.T) {
report := runOn(t, "../testdata/research-tools-project")

assertToolDetected(t, report, "test", "nf-test")
assertToolDetected(t, report, "build", "nf-core")
assertToolDetected(t, report, "docs", "MultiQC")
assertToolDetected(t, report, "infrastructure", "Dockstore")
assertToolDetected(t, report, "infrastructure", "DVC")
assertToolDetected(t, report, "build", "cibuildwheel")
assertToolDetected(t, report, "docs", "MyST-Parser")
assertToolDetected(t, report, "test", "BenchmarkTools.jl")
assertToolDetected(t, report, "lint", "lintr")
assertToolDetected(t, report, "format", "styler")
assertToolDetected(t, report, "build", "targets")
assertToolDetected(t, report, "test", "vdiffr")
assertToolDetected(t, report, "test", "tinytest")
}

func TestResearchToolSignals(t *testing.T) {
tests := []struct {
name string
files map[string]string
category string
tool string
}{
{
name: "nf-test test file",
files: map[string]string{
"nextflow.config": "nextflow.enable.dsl=2\n",
"tests/modules/fastqc/main.nf.test": "nextflow_process { script \"main.nf\" }\n",
},
category: "test",
tool: "nf-test",
},
{
name: "nf-core metadata",
files: map[string]string{
".nf-core.yml": "repository_type: pipeline\n",
},
category: "build",
tool: "nf-core",
},
{
name: "nested MultiQC config",
files: map[string]string{
"assets/multiqc_config.yml": "title: Example analysis\n",
},
category: "docs",
tool: "MultiQC",
},
{
name: "Dockstore GitHub descriptor",
files: map[string]string{
".github/.dockstore.yml": "version: 1.2\nworkflows:\n - subclass: NFL\n primaryDescriptorPath: /nextflow.config\n",
},
category: "infrastructure",
tool: "Dockstore",
},
{
name: "DVC project config",
files: map[string]string{
".dvc/config": "[core]\n remote = storage\n",
},
category: "infrastructure",
tool: "DVC",
},
{
name: "cibuildwheel pyproject config",
files: map[string]string{
"pyproject.toml": "[project]\nname = \"native-example\"\nversion = \"1.0.0\"\n\n[tool.cibuildwheel]\ntest-command = \"pytest {project}/tests\"\n",
},
category: "build",
tool: "cibuildwheel",
},
{
name: "MyST-Parser dependency",
files: map[string]string{
"pyproject.toml": "[project]\nname = \"research-docs\"\nversion = \"1.0.0\"\ndependencies = [\"myst-parser>=4\"]\n",
},
category: "docs",
tool: "MyST-Parser",
},
{
name: "BenchmarkTools Julia dependency",
files: map[string]string{
"Project.toml": "name = \"NumericalModel\"\nuuid = \"12345678-1234-1234-1234-123456789abc\"\nversion = \"0.1.0\"\n\n[deps]\nBenchmarkTools = \"6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf\"\n",
},
category: "test",
tool: "BenchmarkTools.jl",
},
{
name: "lintr R dependency",
files: map[string]string{
"DESCRIPTION": "Package: modeltools\nVersion: 1.0.0\nSuggests: lintr\n",
},
category: "lint",
tool: "lintr",
},
{
name: "styler R dependency",
files: map[string]string{
"DESCRIPTION": "Package: modeltools\nVersion: 1.0.0\nSuggests: styler\n",
},
category: "format",
tool: "styler",
},
{
name: "targets pipeline",
files: map[string]string{
"_targets.R": "library(targets)\nlist(tar_target(result, run_model()))\n",
},
category: "build",
tool: "targets",
},
{
name: "vdiffr R dependency",
files: map[string]string{
"DESCRIPTION": "Package: plottools\nVersion: 1.0.0\nSuggests: vdiffr\n",
},
category: "test",
tool: "vdiffr",
},
{
name: "tinytest package runner",
files: map[string]string{
"DESCRIPTION": "Package: modeltools\nVersion: 1.0.0\nSuggests: tinytest\n",
"tests/tinytest.R": "if (requireNamespace(\"tinytest\")) tinytest::test_package(\"modeltools\")\n",
},
category: "test",
tool: "tinytest",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := t.TempDir()
for path, content := range tt.files {
writeProjectFile(t, dir, path, content)
}

report := runOn(t, dir)
assertToolDetected(t, report, tt.category, tt.tool)
})
}
}
20 changes: 20 additions & 0 deletions knowledge/_shared/dockstore.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tool]
name = "Dockstore"
category = "infrastructure"
homepage = "https://dockstore.org"
docs = "https://docs.dockstore.org"
repo = "https://github.com/dockstore/dockstore"
description = "Registry for scientific tools and workflows"

[detect]
files = [".dockstore.yml", ".dockstore.yaml", ".github/.dockstore.yml", ".github/.dockstore.yaml"]

[config]
files = [".dockstore.yml", ".dockstore.yaml", ".github/.dockstore.yml", ".github/.dockstore.yaml"]

[taxonomy]
role = ["cli-tool"]
layer = ["infrastructure"]
function = ["deployment"]
domain = ["scientific-computing"]
audience = ["researcher"]
25 changes: 25 additions & 0 deletions knowledge/_shared/dvc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[tool]
name = "DVC"
category = "infrastructure"
homepage = "https://dvc.org"
docs = "https://dvc.org/doc"
repo = "https://github.com/iterative/dvc"
description = "Version control for data and machine learning projects"

[detect]
files = ["dvc.yaml", "dvc.lock", ".dvc/config", ".dvcignore", "*.dvc", "**/*.dvc"]
dependencies = ["dvc"]

[commands]
run = "dvc pull"
alternatives = ["dvc repro", "dvc status"]

[config]
files = ["dvc.yaml", "dvc.lock", ".dvc/config", ".dvcignore"]
lockfile = "dvc.lock"

[taxonomy]
role = ["cli-tool"]
function = ["file-management"]
domain = ["data-science"]
audience = ["data-scientist", "researcher"]
23 changes: 23 additions & 0 deletions knowledge/_shared/multiqc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool]
name = "MultiQC"
category = "docs"
homepage = "https://multiqc.info"
docs = "https://docs.seqera.io/multiqc"
repo = "https://github.com/MultiQC/MultiQC"
description = "Aggregate reports for bioinformatics analyses"

[detect]
files = ["multiqc_config.yml", "multiqc_config.yaml", ".multiqc_config.yml", ".multiqc_config.yaml", "**/multiqc_config.yml", "**/multiqc_config.yaml"]
dependencies = ["multiqc"]

[commands]
run = "multiqc ."

[config]
files = ["multiqc_config.yml", "multiqc_config.yaml", ".multiqc_config.yml", ".multiqc_config.yaml", "**/multiqc_config.yml", "**/multiqc_config.yaml"]

[taxonomy]
role = ["cli-tool"]
function = ["visualization"]
domain = ["scientific-computing"]
audience = ["researcher"]
24 changes: 24 additions & 0 deletions knowledge/_shared/nf-core.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[tool]
name = "nf-core"
category = "build"
homepage = "https://nf-co.re"
docs = "https://nf-co.re/docs/nf-core-tools"
repo = "https://github.com/nf-core/tools"
description = "Tools for creating and maintaining nf-core Nextflow pipelines"

[detect]
files = [".nf-core.yml", ".nf-core.yaml"]
dependencies = ["nf-core"]

[commands]
run = "nf-core pipelines lint"
alternatives = ["nf-core pipelines schema lint", "nf-core pipelines create"]

[config]
files = [".nf-core.yml", ".nf-core.yaml"]

[taxonomy]
role = ["build-tool"]
function = ["automation"]
domain = ["scientific-computing"]
audience = ["researcher"]
23 changes: 23 additions & 0 deletions knowledge/_shared/nf-test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool]
name = "nf-test"
category = "test"
homepage = "https://www.nf-test.com"
docs = "https://www.nf-test.com/docs/getting-started/"
repo = "https://github.com/askimed/nf-test"
description = "Testing tool for Nextflow pipelines"

[detect]
files = ["nf-test.config", "**/*.nf.test", "**/*.nf.test.snap"]

[commands]
run = "nf-test test"
alternatives = ["nf-test list", "nf-test status"]

[config]
files = ["nf-test.config"]

[taxonomy]
role = ["testing-framework"]
function = ["testing"]
domain = ["scientific-computing"]
audience = ["researcher"]
21 changes: 21 additions & 0 deletions knowledge/julia/benchmarktools.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[tool]
name = "BenchmarkTools.jl"
category = "test"
homepage = "https://juliaci.github.io/BenchmarkTools.jl"
docs = "https://juliaci.github.io/BenchmarkTools.jl/stable/manual/"
repo = "https://github.com/JuliaCI/BenchmarkTools.jl"
description = "Benchmarking and performance tracking for Julia"

[detect]
dependencies = ["BenchmarkTools"]
dev_dependencies = ["BenchmarkTools"]
ecosystems = ["julia"]

[detect.key_exists]
"Project.toml" = ["deps.BenchmarkTools", "extras.BenchmarkTools", "weakdeps.BenchmarkTools"]

[taxonomy]
role = ["testing-framework"]
function = ["benchmarking"]
domain = ["scientific-computing"]
audience = ["researcher"]
25 changes: 25 additions & 0 deletions knowledge/python/cibuildwheel.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[tool]
name = "cibuildwheel"
category = "build"
homepage = "https://cibuildwheel.pypa.io"
docs = "https://cibuildwheel.pypa.io/en/stable/"
repo = "https://github.com/pypa/cibuildwheel"
description = "Build and test Python wheels across supported platforms"

[detect]
dependencies = ["cibuildwheel"]
dev_dependencies = ["cibuildwheel"]
ecosystems = ["python"]

[detect.key_exists]
"pyproject.toml" = ["tool.cibuildwheel"]

[commands]
run = "cibuildwheel"
alternatives = ["python -m cibuildwheel"]

[config]
files = ["pyproject.toml"]

[taxonomy]
role = ["build-tool"]
20 changes: 20 additions & 0 deletions knowledge/python/myst-parser.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tool]
name = "MyST-Parser"
category = "docs"
homepage = "https://myst-parser.readthedocs.io"
docs = "https://myst-parser.readthedocs.io/en/latest/"
repo = "https://github.com/executablebooks/MyST-Parser"
description = "MyST Markdown parser and Sphinx extension"

[detect]
dependencies = ["myst-parser"]
dev_dependencies = ["myst-parser"]
ecosystems = ["python"]

[detect.file_contains]
"conf.py" = ["myst_parser"]
"**/conf.py" = ["myst_parser"]

[taxonomy]
role = ["library"]
function = ["documentation"]
23 changes: 23 additions & 0 deletions knowledge/r/lintr.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool]
name = "lintr"
category = "lint"
homepage = "https://lintr.r-lib.org"
docs = "https://lintr.r-lib.org/reference/"
repo = "https://github.com/r-lib/lintr"
description = "Static analysis and style checks for R"

[detect]
files = [".lintr", ".lintr.R"]
dependencies = ["lintr"]
dev_dependencies = ["lintr"]
ecosystems = ["r"]

[commands]
run = "Rscript -e 'lintr::lint_dir()'"
alternatives = ["Rscript -e 'lintr::lint_package()'"]

[config]
files = [".lintr", ".lintr.R"]

[taxonomy]
role = ["linter"]
19 changes: 19 additions & 0 deletions knowledge/r/styler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[tool]
name = "styler"
category = "format"
homepage = "https://styler.r-lib.org"
docs = "https://styler.r-lib.org/reference/"
repo = "https://github.com/r-lib/styler"
description = "Source code formatter for R"

[detect]
dependencies = ["styler"]
dev_dependencies = ["styler"]
ecosystems = ["r"]

[commands]
run = "Rscript -e 'styler::style_pkg()'"
alternatives = ["Rscript -e 'styler::style_dir()'"]

[taxonomy]
role = ["formatter"]
Loading