Projects STRLCPY syft Commits da362464
🤬
  • feat: Add R cataloger (#1790)

    Add a cataloger that detects installed R packages by looking for DESCRIPTION
    files. The base R package is now picked up in coverageImage tests in
    test/cli/packages_cmd_test.go, so increment expected package counts for the
    tests that use that image.
    
    Signed-off-by: Will Murphy <[email protected]>
  • Loading...
  • William Murphy committed with GitHub 12 months ago
    da362464
    1 parent 0580328a
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■
    internal/constants.go
    skipped 5 lines
    6 6   
    7 7   // JSONSchemaVersion is the current schema version output by the JSON encoder
    8 8   // This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
    9  - JSONSchemaVersion = "7.1.5"
     9 + JSONSchemaVersion = "7.1.6"
    10 10  )
    11 11   
  • ■ ■ ■ ■ ■ ■
    schema/json/generate.go
    skipped 28 lines
    29 29  // not matter as long as it is exported.
    30 30   
    31 31  // TODO: this should be generated from reflection of whats in the pkg package
     32 +// Should be created during generation below; use reflection's ability to
     33 +// create types at runtime.
     34 +// should be same name as struct minus metadata
    32 35  type artifactMetadataContainer struct {
    33 36   Alpm pkg.AlpmMetadata
    34 37   Apk pkg.ApkMetadata
    skipped 21 lines
    56 59   PythonPackage pkg.PythonPackageMetadata
    57 60   PythonPipfilelock pkg.PythonPipfileLockMetadata
    58 61   PythonRequirements pkg.PythonRequirementsMetadata
     62 + RDescriptionFile pkg.RDescriptionFileMetadata
    59 63   Rebar pkg.RebarLockMetadata
    60 64   Rpm pkg.RpmMetadata
    61 65   RustCargo pkg.CargoPackageMetadata
    skipped 108 lines
  • ■ ■ ■ ■ ■ ■
    schema/json/schema-7.1.6.json
     1 +{
     2 + "$schema": "https://json-schema.org/draft/2020-12/schema",
     3 + "$id": "https://github.com/anchore/syft/syft/formats/syftjson/model/document",
     4 + "$ref": "#/$defs/Document",
     5 + "$defs": {
     6 + "AlpmFileRecord": {
     7 + "properties": {
     8 + "path": {
     9 + "type": "string"
     10 + },
     11 + "type": {
     12 + "type": "string"
     13 + },
     14 + "uid": {
     15 + "type": "string"
     16 + },
     17 + "gid": {
     18 + "type": "string"
     19 + },
     20 + "time": {
     21 + "type": "string",
     22 + "format": "date-time"
     23 + },
     24 + "size": {
     25 + "type": "string"
     26 + },
     27 + "link": {
     28 + "type": "string"
     29 + },
     30 + "digest": {
     31 + "items": {
     32 + "$ref": "#/$defs/Digest"
     33 + },
     34 + "type": "array"
     35 + }
     36 + },
     37 + "type": "object"
     38 + },
     39 + "AlpmMetadata": {
     40 + "properties": {
     41 + "basepackage": {
     42 + "type": "string"
     43 + },
     44 + "package": {
     45 + "type": "string"
     46 + },
     47 + "version": {
     48 + "type": "string"
     49 + },
     50 + "description": {
     51 + "type": "string"
     52 + },
     53 + "architecture": {
     54 + "type": "string"
     55 + },
     56 + "size": {
     57 + "type": "integer"
     58 + },
     59 + "packager": {
     60 + "type": "string"
     61 + },
     62 + "license": {
     63 + "type": "string"
     64 + },
     65 + "url": {
     66 + "type": "string"
     67 + },
     68 + "validation": {
     69 + "type": "string"
     70 + },
     71 + "reason": {
     72 + "type": "integer"
     73 + },
     74 + "files": {
     75 + "items": {
     76 + "$ref": "#/$defs/AlpmFileRecord"
     77 + },
     78 + "type": "array"
     79 + },
     80 + "backup": {
     81 + "items": {
     82 + "$ref": "#/$defs/AlpmFileRecord"
     83 + },
     84 + "type": "array"
     85 + }
     86 + },
     87 + "type": "object",
     88 + "required": [
     89 + "basepackage",
     90 + "package",
     91 + "version",
     92 + "description",
     93 + "architecture",
     94 + "size",
     95 + "packager",
     96 + "license",
     97 + "url",
     98 + "validation",
     99 + "reason",
     100 + "files",
     101 + "backup"
     102 + ]
     103 + },
     104 + "ApkFileRecord": {
     105 + "properties": {
     106 + "path": {
     107 + "type": "string"
     108 + },
     109 + "ownerUid": {
     110 + "type": "string"
     111 + },
     112 + "ownerGid": {
     113 + "type": "string"
     114 + },
     115 + "permissions": {
     116 + "type": "string"
     117 + },
     118 + "digest": {
     119 + "$ref": "#/$defs/Digest"
     120 + }
     121 + },
     122 + "type": "object",
     123 + "required": [
     124 + "path"
     125 + ]
     126 + },
     127 + "ApkMetadata": {
     128 + "properties": {
     129 + "package": {
     130 + "type": "string"
     131 + },
     132 + "originPackage": {
     133 + "type": "string"
     134 + },
     135 + "maintainer": {
     136 + "type": "string"
     137 + },
     138 + "version": {
     139 + "type": "string"
     140 + },
     141 + "license": {
     142 + "type": "string"
     143 + },
     144 + "architecture": {
     145 + "type": "string"
     146 + },
     147 + "url": {
     148 + "type": "string"
     149 + },
     150 + "description": {
     151 + "type": "string"
     152 + },
     153 + "size": {
     154 + "type": "integer"
     155 + },
     156 + "installedSize": {
     157 + "type": "integer"
     158 + },
     159 + "pullDependencies": {
     160 + "items": {
     161 + "type": "string"
     162 + },
     163 + "type": "array"
     164 + },
     165 + "provides": {
     166 + "items": {
     167 + "type": "string"
     168 + },
     169 + "type": "array"
     170 + },
     171 + "pullChecksum": {
     172 + "type": "string"
     173 + },
     174 + "gitCommitOfApkPort": {
     175 + "type": "string"
     176 + },
     177 + "files": {
     178 + "items": {
     179 + "$ref": "#/$defs/ApkFileRecord"
     180 + },
     181 + "type": "array"
     182 + }
     183 + },
     184 + "type": "object",
     185 + "required": [
     186 + "package",
     187 + "originPackage",
     188 + "maintainer",
     189 + "version",
     190 + "license",
     191 + "architecture",
     192 + "url",
     193 + "description",
     194 + "size",
     195 + "installedSize",
     196 + "pullDependencies",
     197 + "provides",
     198 + "pullChecksum",
     199 + "gitCommitOfApkPort",
     200 + "files"
     201 + ]
     202 + },
     203 + "BinaryMetadata": {
     204 + "properties": {
     205 + "matches": {
     206 + "items": {
     207 + "$ref": "#/$defs/ClassifierMatch"
     208 + },
     209 + "type": "array"
     210 + }
     211 + },
     212 + "type": "object",
     213 + "required": [
     214 + "matches"
     215 + ]
     216 + },
     217 + "CargoPackageMetadata": {
     218 + "properties": {
     219 + "name": {
     220 + "type": "string"
     221 + },
     222 + "version": {
     223 + "type": "string"
     224 + },
     225 + "source": {
     226 + "type": "string"
     227 + },
     228 + "checksum": {
     229 + "type": "string"
     230 + },
     231 + "dependencies": {
     232 + "items": {
     233 + "type": "string"
     234 + },
     235 + "type": "array"
     236 + }
     237 + },
     238 + "type": "object",
     239 + "required": [
     240 + "name",
     241 + "version",
     242 + "source",
     243 + "checksum",
     244 + "dependencies"
     245 + ]
     246 + },
     247 + "ClassifierMatch": {
     248 + "properties": {
     249 + "classifier": {
     250 + "type": "string"
     251 + },
     252 + "location": {
     253 + "$ref": "#/$defs/Location"
     254 + }
     255 + },
     256 + "type": "object",
     257 + "required": [
     258 + "classifier",
     259 + "location"
     260 + ]
     261 + },
     262 + "CocoapodsMetadata": {
     263 + "properties": {
     264 + "checksum": {
     265 + "type": "string"
     266 + }
     267 + },
     268 + "type": "object",
     269 + "required": [
     270 + "checksum"
     271 + ]
     272 + },
     273 + "ConanLockMetadata": {
     274 + "properties": {
     275 + "ref": {
     276 + "type": "string"
     277 + },
     278 + "package_id": {
     279 + "type": "string"
     280 + },
     281 + "prev": {
     282 + "type": "string"
     283 + },
     284 + "requires": {
     285 + "type": "string"
     286 + },
     287 + "build_requires": {
     288 + "type": "string"
     289 + },
     290 + "py_requires": {
     291 + "type": "string"
     292 + },
     293 + "options": {
     294 + "patternProperties": {
     295 + ".*": {
     296 + "type": "string"
     297 + }
     298 + },
     299 + "type": "object"
     300 + },
     301 + "path": {
     302 + "type": "string"
     303 + },
     304 + "context": {
     305 + "type": "string"
     306 + }
     307 + },
     308 + "type": "object",
     309 + "required": [
     310 + "ref"
     311 + ]
     312 + },
     313 + "ConanMetadata": {
     314 + "properties": {
     315 + "ref": {
     316 + "type": "string"
     317 + }
     318 + },
     319 + "type": "object",
     320 + "required": [
     321 + "ref"
     322 + ]
     323 + },
     324 + "Coordinates": {
     325 + "properties": {
     326 + "path": {
     327 + "type": "string"
     328 + },
     329 + "layerID": {
     330 + "type": "string"
     331 + }
     332 + },
     333 + "type": "object",
     334 + "required": [
     335 + "path"
     336 + ]
     337 + },
     338 + "DartPubMetadata": {
     339 + "properties": {
     340 + "name": {
     341 + "type": "string"
     342 + },
     343 + "version": {
     344 + "type": "string"
     345 + },
     346 + "hosted_url": {
     347 + "type": "string"
     348 + },
     349 + "vcs_url": {
     350 + "type": "string"
     351 + }
     352 + },
     353 + "type": "object",
     354 + "required": [
     355 + "name",
     356 + "version"
     357 + ]
     358 + },
     359 + "Descriptor": {
     360 + "properties": {
     361 + "name": {
     362 + "type": "string"
     363 + },
     364 + "version": {
     365 + "type": "string"
     366 + },
     367 + "configuration": true
     368 + },
     369 + "type": "object",
     370 + "required": [
     371 + "name",
     372 + "version"
     373 + ]
     374 + },
     375 + "Digest": {
     376 + "properties": {
     377 + "algorithm": {
     378 + "type": "string"
     379 + },
     380 + "value": {
     381 + "type": "string"
     382 + }
     383 + },
     384 + "type": "object",
     385 + "required": [
     386 + "algorithm",
     387 + "value"
     388 + ]
     389 + },
     390 + "Document": {
     391 + "properties": {
     392 + "artifacts": {
     393 + "items": {
     394 + "$ref": "#/$defs/Package"
     395 + },
     396 + "type": "array"
     397 + },
     398 + "artifactRelationships": {
     399 + "items": {
     400 + "$ref": "#/$defs/Relationship"
     401 + },
     402 + "type": "array"
     403 + },
     404 + "files": {
     405 + "items": {
     406 + "$ref": "#/$defs/File"
     407 + },
     408 + "type": "array"
     409 + },
     410 + "secrets": {
     411 + "items": {
     412 + "$ref": "#/$defs/Secrets"
     413 + },
     414 + "type": "array"
     415 + },
     416 + "source": {
     417 + "$ref": "#/$defs/Source"
     418 + },
     419 + "distro": {
     420 + "$ref": "#/$defs/LinuxRelease"
     421 + },
     422 + "descriptor": {
     423 + "$ref": "#/$defs/Descriptor"
     424 + },
     425 + "schema": {
     426 + "$ref": "#/$defs/Schema"
     427 + }
     428 + },
     429 + "type": "object",
     430 + "required": [
     431 + "artifacts",
     432 + "artifactRelationships",
     433 + "source",
     434 + "distro",
     435 + "descriptor",
     436 + "schema"
     437 + ]
     438 + },
     439 + "DotnetDepsMetadata": {
     440 + "properties": {
     441 + "name": {
     442 + "type": "string"
     443 + },
     444 + "version": {
     445 + "type": "string"
     446 + },
     447 + "path": {
     448 + "type": "string"
     449 + },
     450 + "sha512": {
     451 + "type": "string"
     452 + },
     453 + "hashPath": {
     454 + "type": "string"
     455 + }
     456 + },
     457 + "type": "object",
     458 + "required": [
     459 + "name",
     460 + "version",
     461 + "path",
     462 + "sha512",
     463 + "hashPath"
     464 + ]
     465 + },
     466 + "DpkgFileRecord": {
     467 + "properties": {
     468 + "path": {
     469 + "type": "string"
     470 + },
     471 + "digest": {
     472 + "$ref": "#/$defs/Digest"
     473 + },
     474 + "isConfigFile": {
     475 + "type": "boolean"
     476 + }
     477 + },
     478 + "type": "object",
     479 + "required": [
     480 + "path",
     481 + "isConfigFile"
     482 + ]
     483 + },
     484 + "DpkgMetadata": {
     485 + "properties": {
     486 + "package": {
     487 + "type": "string"
     488 + },
     489 + "source": {
     490 + "type": "string"
     491 + },
     492 + "version": {
     493 + "type": "string"
     494 + },
     495 + "sourceVersion": {
     496 + "type": "string"
     497 + },
     498 + "architecture": {
     499 + "type": "string"
     500 + },
     501 + "maintainer": {
     502 + "type": "string"
     503 + },
     504 + "installedSize": {
     505 + "type": "integer"
     506 + },
     507 + "files": {
     508 + "items": {
     509 + "$ref": "#/$defs/DpkgFileRecord"
     510 + },
     511 + "type": "array"
     512 + }
     513 + },
     514 + "type": "object",
     515 + "required": [
     516 + "package",
     517 + "source",
     518 + "version",
     519 + "sourceVersion",
     520 + "architecture",
     521 + "maintainer",
     522 + "installedSize",
     523 + "files"
     524 + ]
     525 + },
     526 + "File": {
     527 + "properties": {
     528 + "id": {
     529 + "type": "string"
     530 + },
     531 + "location": {
     532 + "$ref": "#/$defs/Coordinates"
     533 + },
     534 + "metadata": {
     535 + "$ref": "#/$defs/FileMetadataEntry"
     536 + },
     537 + "contents": {
     538 + "type": "string"
     539 + },
     540 + "digests": {
     541 + "items": {
     542 + "$ref": "#/$defs/Digest"
     543 + },
     544 + "type": "array"
     545 + }
     546 + },
     547 + "type": "object",
     548 + "required": [
     549 + "id",
     550 + "location"
     551 + ]
     552 + },
     553 + "FileMetadataEntry": {
     554 + "properties": {
     555 + "mode": {
     556 + "type": "integer"
     557 + },
     558 + "type": {
     559 + "type": "string"
     560 + },
     561 + "linkDestination": {
     562 + "type": "string"
     563 + },
     564 + "userID": {
     565 + "type": "integer"
     566 + },
     567 + "groupID": {
     568 + "type": "integer"
     569 + },
     570 + "mimeType": {
     571 + "type": "string"
     572 + },
     573 + "size": {
     574 + "type": "integer"
     575 + }
     576 + },
     577 + "type": "object",
     578 + "required": [
     579 + "mode",
     580 + "type",
     581 + "userID",
     582 + "groupID",
     583 + "mimeType",
     584 + "size"
     585 + ]
     586 + },
     587 + "GemMetadata": {
     588 + "properties": {
     589 + "name": {
     590 + "type": "string"
     591 + },
     592 + "version": {
     593 + "type": "string"
     594 + },
     595 + "files": {
     596 + "items": {
     597 + "type": "string"
     598 + },
     599 + "type": "array"
     600 + },
     601 + "authors": {
     602 + "items": {
     603 + "type": "string"
     604 + },
     605 + "type": "array"
     606 + },
     607 + "licenses": {
     608 + "items": {
     609 + "type": "string"
     610 + },
     611 + "type": "array"
     612 + },
     613 + "homepage": {
     614 + "type": "string"
     615 + }
     616 + },
     617 + "type": "object",
     618 + "required": [
     619 + "name",
     620 + "version"
     621 + ]
     622 + },
     623 + "GolangBinMetadata": {
     624 + "properties": {
     625 + "goBuildSettings": {
     626 + "patternProperties": {
     627 + ".*": {
     628 + "type": "string"
     629 + }
     630 + },
     631 + "type": "object"
     632 + },
     633 + "goCompiledVersion": {
     634 + "type": "string"
     635 + },
     636 + "architecture": {
     637 + "type": "string"
     638 + },
     639 + "h1Digest": {
     640 + "type": "string"
     641 + },
     642 + "mainModule": {
     643 + "type": "string"
     644 + }
     645 + },
     646 + "type": "object",
     647 + "required": [
     648 + "goCompiledVersion",
     649 + "architecture"
     650 + ]
     651 + },
     652 + "GolangModMetadata": {
     653 + "properties": {
     654 + "h1Digest": {
     655 + "type": "string"
     656 + }
     657 + },
     658 + "type": "object"
     659 + },
     660 + "HackageMetadata": {
     661 + "properties": {
     662 + "name": {
     663 + "type": "string"
     664 + },
     665 + "version": {
     666 + "type": "string"
     667 + },
     668 + "pkgHash": {
     669 + "type": "string"
     670 + },
     671 + "snapshotURL": {
     672 + "type": "string"
     673 + }
     674 + },
     675 + "type": "object",
     676 + "required": [
     677 + "name",
     678 + "version"
     679 + ]
     680 + },
     681 + "IDLikes": {
     682 + "items": {
     683 + "type": "string"
     684 + },
     685 + "type": "array"
     686 + },
     687 + "JavaManifest": {
     688 + "properties": {
     689 + "main": {
     690 + "patternProperties": {
     691 + ".*": {
     692 + "type": "string"
     693 + }
     694 + },
     695 + "type": "object"
     696 + },
     697 + "namedSections": {
     698 + "patternProperties": {
     699 + ".*": {
     700 + "patternProperties": {
     701 + ".*": {
     702 + "type": "string"
     703 + }
     704 + },
     705 + "type": "object"
     706 + }
     707 + },
     708 + "type": "object"
     709 + }
     710 + },
     711 + "type": "object"
     712 + },
     713 + "JavaMetadata": {
     714 + "properties": {
     715 + "virtualPath": {
     716 + "type": "string"
     717 + },
     718 + "manifest": {
     719 + "$ref": "#/$defs/JavaManifest"
     720 + },
     721 + "pomProperties": {
     722 + "$ref": "#/$defs/PomProperties"
     723 + },
     724 + "pomProject": {
     725 + "$ref": "#/$defs/PomProject"
     726 + },
     727 + "digest": {
     728 + "items": {
     729 + "$ref": "#/$defs/Digest"
     730 + },
     731 + "type": "array"
     732 + }
     733 + },
     734 + "type": "object",
     735 + "required": [
     736 + "virtualPath"
     737 + ]
     738 + },
     739 + "KbPackageMetadata": {
     740 + "properties": {
     741 + "product_id": {
     742 + "type": "string"
     743 + },
     744 + "kb": {
     745 + "type": "string"
     746 + }
     747 + },
     748 + "type": "object",
     749 + "required": [
     750 + "product_id",
     751 + "kb"
     752 + ]
     753 + },
     754 + "LinuxKernelMetadata": {
     755 + "properties": {
     756 + "name": {
     757 + "type": "string"
     758 + },
     759 + "architecture": {
     760 + "type": "string"
     761 + },
     762 + "version": {
     763 + "type": "string"
     764 + },
     765 + "extendedVersion": {
     766 + "type": "string"
     767 + },
     768 + "buildTime": {
     769 + "type": "string"
     770 + },
     771 + "author": {
     772 + "type": "string"
     773 + },
     774 + "format": {
     775 + "type": "string"
     776 + },
     777 + "rwRootFS": {
     778 + "type": "boolean"
     779 + },
     780 + "swapDevice": {
     781 + "type": "integer"
     782 + },
     783 + "rootDevice": {
     784 + "type": "integer"
     785 + },
     786 + "videoMode": {
     787 + "type": "string"
     788 + }
     789 + },
     790 + "type": "object",
     791 + "required": [
     792 + "name",
     793 + "architecture",
     794 + "version"
     795 + ]
     796 + },
     797 + "LinuxKernelModuleMetadata": {
     798 + "properties": {
     799 + "name": {
     800 + "type": "string"
     801 + },
     802 + "version": {
     803 + "type": "string"
     804 + },
     805 + "sourceVersion": {
     806 + "type": "string"
     807 + },
     808 + "path": {
     809 + "type": "string"
     810 + },
     811 + "description": {
     812 + "type": "string"
     813 + },
     814 + "author": {
     815 + "type": "string"
     816 + },
     817 + "license": {
     818 + "type": "string"
     819 + },
     820 + "kernelVersion": {
     821 + "type": "string"
     822 + },
     823 + "versionMagic": {
     824 + "type": "string"
     825 + },
     826 + "parameters": {
     827 + "patternProperties": {
     828 + ".*": {
     829 + "$ref": "#/$defs/LinuxKernelModuleParameter"
     830 + }
     831 + },
     832 + "type": "object"
     833 + }
     834 + },
     835 + "type": "object"
     836 + },
     837 + "LinuxKernelModuleParameter": {
     838 + "properties": {
     839 + "type": {
     840 + "type": "string"
     841 + },
     842 + "description": {
     843 + "type": "string"
     844 + }
     845 + },
     846 + "type": "object"
     847 + },
     848 + "LinuxRelease": {
     849 + "properties": {
     850 + "prettyName": {
     851 + "type": "string"
     852 + },
     853 + "name": {
     854 + "type": "string"
     855 + },
     856 + "id": {
     857 + "type": "string"
     858 + },
     859 + "idLike": {
     860 + "$ref": "#/$defs/IDLikes"
     861 + },
     862 + "version": {
     863 + "type": "string"
     864 + },
     865 + "versionID": {
     866 + "type": "string"
     867 + },
     868 + "versionCodename": {
     869 + "type": "string"
     870 + },
     871 + "buildID": {
     872 + "type": "string"
     873 + },
     874 + "imageID": {
     875 + "type": "string"
     876 + },
     877 + "imageVersion": {
     878 + "type": "string"
     879 + },
     880 + "variant": {
     881 + "type": "string"
     882 + },
     883 + "variantID": {
     884 + "type": "string"
     885 + },
     886 + "homeURL": {
     887 + "type": "string"
     888 + },
     889 + "supportURL": {
     890 + "type": "string"
     891 + },
     892 + "bugReportURL": {
     893 + "type": "string"
     894 + },
     895 + "privacyPolicyURL": {
     896 + "type": "string"
     897 + },
     898 + "cpeName": {
     899 + "type": "string"
     900 + },
     901 + "supportEnd": {
     902 + "type": "string"
     903 + }
     904 + },
     905 + "type": "object"
     906 + },
     907 + "Location": {
     908 + "properties": {
     909 + "path": {
     910 + "type": "string"
     911 + },
     912 + "layerID": {
     913 + "type": "string"
     914 + },
     915 + "annotations": {
     916 + "patternProperties": {
     917 + ".*": {
     918 + "type": "string"
     919 + }
     920 + },
     921 + "type": "object"
     922 + }
     923 + },
     924 + "type": "object",
     925 + "required": [
     926 + "path"
     927 + ]
     928 + },
     929 + "MixLockMetadata": {
     930 + "properties": {
     931 + "name": {
     932 + "type": "string"
     933 + },
     934 + "version": {
     935 + "type": "string"
     936 + },
     937 + "pkgHash": {
     938 + "type": "string"
     939 + },
     940 + "pkgHashExt": {
     941 + "type": "string"
     942 + }
     943 + },
     944 + "type": "object",
     945 + "required": [
     946 + "name",
     947 + "version",
     948 + "pkgHash",
     949 + "pkgHashExt"
     950 + ]
     951 + },
     952 + "NixStoreMetadata": {
     953 + "properties": {
     954 + "outputHash": {
     955 + "type": "string"
     956 + },
     957 + "output": {
     958 + "type": "string"
     959 + },
     960 + "files": {
     961 + "items": {
     962 + "type": "string"
     963 + },
     964 + "type": "array"
     965 + }
     966 + },
     967 + "type": "object",
     968 + "required": [
     969 + "outputHash",
     970 + "files"
     971 + ]
     972 + },
     973 + "NpmPackageJSONMetadata": {
     974 + "properties": {
     975 + "name": {
     976 + "type": "string"
     977 + },
     978 + "version": {
     979 + "type": "string"
     980 + },
     981 + "author": {
     982 + "type": "string"
     983 + },
     984 + "licenses": {
     985 + "items": {
     986 + "type": "string"
     987 + },
     988 + "type": "array"
     989 + },
     990 + "homepage": {
     991 + "type": "string"
     992 + },
     993 + "description": {
     994 + "type": "string"
     995 + },
     996 + "url": {
     997 + "type": "string"
     998 + },
     999 + "private": {
     1000 + "type": "boolean"
     1001 + }
     1002 + },
     1003 + "type": "object",
     1004 + "required": [
     1005 + "name",
     1006 + "version",
     1007 + "author",
     1008 + "licenses",
     1009 + "homepage",
     1010 + "description",
     1011 + "url",
     1012 + "private"
     1013 + ]
     1014 + },
     1015 + "NpmPackageLockJSONMetadata": {
     1016 + "properties": {
     1017 + "resolved": {
     1018 + "type": "string"
     1019 + },
     1020 + "integrity": {
     1021 + "type": "string"
     1022 + }
     1023 + },
     1024 + "type": "object",
     1025 + "required": [
     1026 + "resolved",
     1027 + "integrity"
     1028 + ]
     1029 + },
     1030 + "Package": {
     1031 + "properties": {
     1032 + "id": {
     1033 + "type": "string"
     1034 + },
     1035 + "name": {
     1036 + "type": "string"
     1037 + },
     1038 + "version": {
     1039 + "type": "string"
     1040 + },
     1041 + "type": {
     1042 + "type": "string"
     1043 + },
     1044 + "foundBy": {
     1045 + "type": "string"
     1046 + },
     1047 + "locations": {
     1048 + "items": {
     1049 + "$ref": "#/$defs/Location"
     1050 + },
     1051 + "type": "array"
     1052 + },
     1053 + "licenses": {
     1054 + "items": {
     1055 + "type": "string"
     1056 + },
     1057 + "type": "array"
     1058 + },
     1059 + "language": {
     1060 + "type": "string"
     1061 + },
     1062 + "cpes": {
     1063 + "items": {
     1064 + "type": "string"
     1065 + },
     1066 + "type": "array"
     1067 + },
     1068 + "purl": {
     1069 + "type": "string"
     1070 + },
     1071 + "metadataType": {
     1072 + "type": "string"
     1073 + },
     1074 + "metadata": {
     1075 + "anyOf": [
     1076 + {
     1077 + "type": "null"
     1078 + },
     1079 + {
     1080 + "$ref": "#/$defs/AlpmMetadata"
     1081 + },
     1082 + {
     1083 + "$ref": "#/$defs/ApkMetadata"
     1084 + },
     1085 + {
     1086 + "$ref": "#/$defs/BinaryMetadata"
     1087 + },
     1088 + {
     1089 + "$ref": "#/$defs/CargoPackageMetadata"
     1090 + },
     1091 + {
     1092 + "$ref": "#/$defs/CocoapodsMetadata"
     1093 + },
     1094 + {
     1095 + "$ref": "#/$defs/ConanLockMetadata"
     1096 + },
     1097 + {
     1098 + "$ref": "#/$defs/ConanMetadata"
     1099 + },
     1100 + {
     1101 + "$ref": "#/$defs/DartPubMetadata"
     1102 + },
     1103 + {
     1104 + "$ref": "#/$defs/DotnetDepsMetadata"
     1105 + },
     1106 + {
     1107 + "$ref": "#/$defs/DpkgMetadata"
     1108 + },
     1109 + {
     1110 + "$ref": "#/$defs/GemMetadata"
     1111 + },
     1112 + {
     1113 + "$ref": "#/$defs/GolangBinMetadata"
     1114 + },
     1115 + {
     1116 + "$ref": "#/$defs/GolangModMetadata"
     1117 + },
     1118 + {
     1119 + "$ref": "#/$defs/HackageMetadata"
     1120 + },
     1121 + {
     1122 + "$ref": "#/$defs/JavaMetadata"
     1123 + },
     1124 + {
     1125 + "$ref": "#/$defs/KbPackageMetadata"
     1126 + },
     1127 + {
     1128 + "$ref": "#/$defs/LinuxKernelMetadata"
     1129 + },
     1130 + {
     1131 + "$ref": "#/$defs/LinuxKernelModuleMetadata"
     1132 + },
     1133 + {
     1134 + "$ref": "#/$defs/MixLockMetadata"
     1135 + },
     1136 + {
     1137 + "$ref": "#/$defs/NixStoreMetadata"
     1138 + },
     1139 + {
     1140 + "$ref": "#/$defs/NpmPackageJSONMetadata"
     1141 + },
     1142 + {
     1143 + "$ref": "#/$defs/NpmPackageLockJSONMetadata"
     1144 + },
     1145 + {
     1146 + "$ref": "#/$defs/PhpComposerJSONMetadata"
     1147 + },
     1148 + {
     1149 + "$ref": "#/$defs/PortageMetadata"
     1150 + },
     1151 + {
     1152 + "$ref": "#/$defs/PythonPackageMetadata"
     1153 + },
     1154 + {
     1155 + "$ref": "#/$defs/PythonPipfileLockMetadata"
     1156 + },
     1157 + {
     1158 + "$ref": "#/$defs/PythonRequirementsMetadata"
     1159 + },
     1160 + {
     1161 + "$ref": "#/$defs/RDescriptionFileMetadata"
     1162 + },
     1163 + {
     1164 + "$ref": "#/$defs/RebarLockMetadata"
     1165 + },
     1166 + {
     1167 + "$ref": "#/$defs/RpmMetadata"
     1168 + }
     1169 + ]
     1170 + }
     1171 + },
     1172 + "type": "object",
     1173 + "required": [
     1174 + "id",
     1175 + "name",
     1176 + "version",
     1177 + "type",
     1178 + "foundBy",
     1179 + "locations",
     1180 + "licenses",
     1181 + "language",
     1182 + "cpes",
     1183 + "purl"
     1184 + ]
     1185 + },
     1186 + "PhpComposerAuthors": {
     1187 + "properties": {
     1188 + "name": {
     1189 + "type": "string"
     1190 + },
     1191 + "email": {
     1192 + "type": "string"
     1193 + },
     1194 + "homepage": {
     1195 + "type": "string"
     1196 + }
     1197 + },
     1198 + "type": "object",
     1199 + "required": [
     1200 + "name"
     1201 + ]
     1202 + },
     1203 + "PhpComposerExternalReference": {
     1204 + "properties": {
     1205 + "type": {
     1206 + "type": "string"
     1207 + },
     1208 + "url": {
     1209 + "type": "string"
     1210 + },
     1211 + "reference": {
     1212 + "type": "string"
     1213 + },
     1214 + "shasum": {
     1215 + "type": "string"
     1216 + }
     1217 + },
     1218 + "type": "object",
     1219 + "required": [
     1220 + "type",
     1221 + "url",
     1222 + "reference"
     1223 + ]
     1224 + },
     1225 + "PhpComposerJSONMetadata": {
     1226 + "properties": {
     1227 + "name": {
     1228 + "type": "string"
     1229 + },
     1230 + "version": {
     1231 + "type": "string"
     1232 + },
     1233 + "source": {
     1234 + "$ref": "#/$defs/PhpComposerExternalReference"
     1235 + },
     1236 + "dist": {
     1237 + "$ref": "#/$defs/PhpComposerExternalReference"
     1238 + },
     1239 + "require": {
     1240 + "patternProperties": {
     1241 + ".*": {
     1242 + "type": "string"
     1243 + }
     1244 + },
     1245 + "type": "object"
     1246 + },
     1247 + "provide": {
     1248 + "patternProperties": {
     1249 + ".*": {
     1250 + "type": "string"
     1251 + }
     1252 + },
     1253 + "type": "object"
     1254 + },
     1255 + "require-dev": {
     1256 + "patternProperties": {
     1257 + ".*": {
     1258 + "type": "string"
     1259 + }
     1260 + },
     1261 + "type": "object"
     1262 + },
     1263 + "suggest": {
     1264 + "patternProperties": {
     1265 + ".*": {
     1266 + "type": "string"
     1267 + }
     1268 + },
     1269 + "type": "object"
     1270 + },
     1271 + "type": {
     1272 + "type": "string"
     1273 + },
     1274 + "notification-url": {
     1275 + "type": "string"
     1276 + },
     1277 + "bin": {
     1278 + "items": {
     1279 + "type": "string"
     1280 + },
     1281 + "type": "array"
     1282 + },
     1283 + "license": {
     1284 + "items": {
     1285 + "type": "string"
     1286 + },
     1287 + "type": "array"
     1288 + },
     1289 + "authors": {
     1290 + "items": {
     1291 + "$ref": "#/$defs/PhpComposerAuthors"
     1292 + },
     1293 + "type": "array"
     1294 + },
     1295 + "description": {
     1296 + "type": "string"
     1297 + },
     1298 + "homepage": {
     1299 + "type": "string"
     1300 + },
     1301 + "keywords": {
     1302 + "items": {
     1303 + "type": "string"
     1304 + },
     1305 + "type": "array"
     1306 + },
     1307 + "time": {
     1308 + "type": "string"
     1309 + }
     1310 + },
     1311 + "type": "object",
     1312 + "required": [
     1313 + "name",
     1314 + "version",
     1315 + "source",
     1316 + "dist"
     1317 + ]
     1318 + },
     1319 + "PomParent": {
     1320 + "properties": {
     1321 + "groupId": {
     1322 + "type": "string"
     1323 + },
     1324 + "artifactId": {
     1325 + "type": "string"
     1326 + },
     1327 + "version": {
     1328 + "type": "string"
     1329 + }
     1330 + },
     1331 + "type": "object",
     1332 + "required": [
     1333 + "groupId",
     1334 + "artifactId",
     1335 + "version"
     1336 + ]
     1337 + },
     1338 + "PomProject": {
     1339 + "properties": {
     1340 + "path": {
     1341 + "type": "string"
     1342 + },
     1343 + "parent": {
     1344 + "$ref": "#/$defs/PomParent"
     1345 + },
     1346 + "groupId": {
     1347 + "type": "string"
     1348 + },
     1349 + "artifactId": {
     1350 + "type": "string"
     1351 + },
     1352 + "version": {
     1353 + "type": "string"
     1354 + },
     1355 + "name": {
     1356 + "type": "string"
     1357 + },
     1358 + "description": {
     1359 + "type": "string"
     1360 + },
     1361 + "url": {
     1362 + "type": "string"
     1363 + }
     1364 + },
     1365 + "type": "object",
     1366 + "required": [
     1367 + "path",
     1368 + "groupId",
     1369 + "artifactId",
     1370 + "version",
     1371 + "name"
     1372 + ]
     1373 + },
     1374 + "PomProperties": {
     1375 + "properties": {
     1376 + "path": {
     1377 + "type": "string"
     1378 + },
     1379 + "name": {
     1380 + "type": "string"
     1381 + },
     1382 + "groupId": {
     1383 + "type": "string"
     1384 + },
     1385 + "artifactId": {
     1386 + "type": "string"
     1387 + },
     1388 + "version": {
     1389 + "type": "string"
     1390 + },
     1391 + "extraFields": {
     1392 + "patternProperties": {
     1393 + ".*": {
     1394 + "type": "string"
     1395 + }
     1396 + },
     1397 + "type": "object"
     1398 + }
     1399 + },
     1400 + "type": "object",
     1401 + "required": [
     1402 + "path",
     1403 + "name",
     1404 + "groupId",
     1405 + "artifactId",
     1406 + "version"
     1407 + ]
     1408 + },
     1409 + "PortageFileRecord": {
     1410 + "properties": {
     1411 + "path": {
     1412 + "type": "string"
     1413 + },
     1414 + "digest": {
     1415 + "$ref": "#/$defs/Digest"
     1416 + }
     1417 + },
     1418 + "type": "object",
     1419 + "required": [
     1420 + "path"
     1421 + ]
     1422 + },
     1423 + "PortageMetadata": {
     1424 + "properties": {
     1425 + "installedSize": {
     1426 + "type": "integer"
     1427 + },
     1428 + "files": {
     1429 + "items": {
     1430 + "$ref": "#/$defs/PortageFileRecord"
     1431 + },
     1432 + "type": "array"
     1433 + }
     1434 + },
     1435 + "type": "object",
     1436 + "required": [
     1437 + "installedSize",
     1438 + "files"
     1439 + ]
     1440 + },
     1441 + "PythonDirectURLOriginInfo": {
     1442 + "properties": {
     1443 + "url": {
     1444 + "type": "string"
     1445 + },
     1446 + "commitId": {
     1447 + "type": "string"
     1448 + },
     1449 + "vcs": {
     1450 + "type": "string"
     1451 + }
     1452 + },
     1453 + "type": "object",
     1454 + "required": [
     1455 + "url"
     1456 + ]
     1457 + },
     1458 + "PythonFileDigest": {
     1459 + "properties": {
     1460 + "algorithm": {
     1461 + "type": "string"
     1462 + },
     1463 + "value": {
     1464 + "type": "string"
     1465 + }
     1466 + },
     1467 + "type": "object",
     1468 + "required": [
     1469 + "algorithm",
     1470 + "value"
     1471 + ]
     1472 + },
     1473 + "PythonFileRecord": {
     1474 + "properties": {
     1475 + "path": {
     1476 + "type": "string"
     1477 + },
     1478 + "digest": {
     1479 + "$ref": "#/$defs/PythonFileDigest"
     1480 + },
     1481 + "size": {
     1482 + "type": "string"
     1483 + }
     1484 + },
     1485 + "type": "object",
     1486 + "required": [
     1487 + "path"
     1488 + ]
     1489 + },
     1490 + "PythonPackageMetadata": {
     1491 + "properties": {
     1492 + "name": {
     1493 + "type": "string"
     1494 + },
     1495 + "version": {
     1496 + "type": "string"
     1497 + },
     1498 + "license": {
     1499 + "type": "string"
     1500 + },
     1501 + "author": {
     1502 + "type": "string"
     1503 + },
     1504 + "authorEmail": {
     1505 + "type": "string"
     1506 + },
     1507 + "platform": {
     1508 + "type": "string"
     1509 + },
     1510 + "files": {
     1511 + "items": {
     1512 + "$ref": "#/$defs/PythonFileRecord"
     1513 + },
     1514 + "type": "array"
     1515 + },
     1516 + "sitePackagesRootPath": {
     1517 + "type": "string"
     1518 + },
     1519 + "topLevelPackages": {
     1520 + "items": {
     1521 + "type": "string"
     1522 + },
     1523 + "type": "array"
     1524 + },
     1525 + "directUrlOrigin": {
     1526 + "$ref": "#/$defs/PythonDirectURLOriginInfo"
     1527 + }
     1528 + },
     1529 + "type": "object",
     1530 + "required": [
     1531 + "name",
     1532 + "version",
     1533 + "license",
     1534 + "author",
     1535 + "authorEmail",
     1536 + "platform",
     1537 + "sitePackagesRootPath"
     1538 + ]
     1539 + },
     1540 + "PythonPipfileLockMetadata": {
     1541 + "properties": {
     1542 + "hashes": {
     1543 + "items": {
     1544 + "type": "string"
     1545 + },
     1546 + "type": "array"
     1547 + },
     1548 + "index": {
     1549 + "type": "string"
     1550 + }
     1551 + },
     1552 + "type": "object",
     1553 + "required": [
     1554 + "hashes",
     1555 + "index"
     1556 + ]
     1557 + },
     1558 + "PythonRequirementsMetadata": {
     1559 + "properties": {
     1560 + "name": {
     1561 + "type": "string"
     1562 + },
     1563 + "extras": {
     1564 + "items": {
     1565 + "type": "string"
     1566 + },
     1567 + "type": "array"
     1568 + },
     1569 + "versionConstraint": {
     1570 + "type": "string"
     1571 + },
     1572 + "url": {
     1573 + "type": "string"
     1574 + },
     1575 + "markers": {
     1576 + "patternProperties": {
     1577 + ".*": {
     1578 + "type": "string"
     1579 + }
     1580 + },
     1581 + "type": "object"
     1582 + }
     1583 + },
     1584 + "type": "object",
     1585 + "required": [
     1586 + "name",
     1587 + "extras",
     1588 + "versionConstraint",
     1589 + "url",
     1590 + "markers"
     1591 + ]
     1592 + },
     1593 + "RDescriptionFileMetadata": {
     1594 + "properties": {
     1595 + "title": {
     1596 + "type": "string"
     1597 + },
     1598 + "description": {
     1599 + "type": "string"
     1600 + },
     1601 + "author": {
     1602 + "type": "string"
     1603 + },
     1604 + "maintainer": {
     1605 + "type": "string"
     1606 + },
     1607 + "url": {
     1608 + "items": {
     1609 + "type": "string"
     1610 + },
     1611 + "type": "array"
     1612 + },
     1613 + "repository": {
     1614 + "type": "string"
     1615 + },
     1616 + "built": {
     1617 + "type": "string"
     1618 + },
     1619 + "needsCompilation": {
     1620 + "type": "boolean"
     1621 + },
     1622 + "imports": {
     1623 + "items": {
     1624 + "type": "string"
     1625 + },
     1626 + "type": "array"
     1627 + },
     1628 + "depends": {
     1629 + "items": {
     1630 + "type": "string"
     1631 + },
     1632 + "type": "array"
     1633 + },
     1634 + "suggests": {
     1635 + "items": {
     1636 + "type": "string"
     1637 + },
     1638 + "type": "array"
     1639 + }
     1640 + },
     1641 + "type": "object"
     1642 + },
     1643 + "RebarLockMetadata": {
     1644 + "properties": {
     1645 + "name": {
     1646 + "type": "string"
     1647 + },
     1648 + "version": {
     1649 + "type": "string"
     1650 + },
     1651 + "pkgHash": {
     1652 + "type": "string"
     1653 + },
     1654 + "pkgHashExt": {
     1655 + "type": "string"
     1656 + }
     1657 + },
     1658 + "type": "object",
     1659 + "required": [
     1660 + "name",
     1661 + "version",
     1662 + "pkgHash",
     1663 + "pkgHashExt"
     1664 + ]
     1665 + },
     1666 + "Relationship": {
     1667 + "properties": {
     1668 + "parent": {
     1669 + "type": "string"
     1670 + },
     1671 + "child": {
     1672 + "type": "string"
     1673 + },
     1674 + "type": {
     1675 + "type": "string"
     1676 + },
     1677 + "metadata": true
     1678 + },
     1679 + "type": "object",
     1680 + "required": [
     1681 + "parent",
     1682 + "child",
     1683 + "type"
     1684 + ]
     1685 + },
     1686 + "RpmMetadata": {
     1687 + "properties": {
     1688 + "name": {
     1689 + "type": "string"
     1690 + },
     1691 + "version": {
     1692 + "type": "string"
     1693 + },
     1694 + "epoch": {
     1695 + "oneOf": [
     1696 + {
     1697 + "type": "integer"
     1698 + },
     1699 + {
     1700 + "type": "null"
     1701 + }
     1702 + ]
     1703 + },
     1704 + "architecture": {
     1705 + "type": "string"
     1706 + },
     1707 + "release": {
     1708 + "type": "string"
     1709 + },
     1710 + "sourceRpm": {
     1711 + "type": "string"
     1712 + },
     1713 + "size": {
     1714 + "type": "integer"
     1715 + },
     1716 + "license": {
     1717 + "type": "string"
     1718 + },
     1719 + "vendor": {
     1720 + "type": "string"
     1721 + },
     1722 + "modularityLabel": {
     1723 + "type": "string"
     1724 + },
     1725 + "files": {
     1726 + "items": {
     1727 + "$ref": "#/$defs/RpmdbFileRecord"
     1728 + },
     1729 + "type": "array"
     1730 + }
     1731 + },
     1732 + "type": "object",
     1733 + "required": [
     1734 + "name",
     1735 + "version",
     1736 + "epoch",
     1737 + "architecture",
     1738 + "release",
     1739 + "sourceRpm",
     1740 + "size",
     1741 + "license",
     1742 + "vendor",
     1743 + "modularityLabel",
     1744 + "files"
     1745 + ]
     1746 + },
     1747 + "RpmdbFileRecord": {
     1748 + "properties": {
     1749 + "path": {
     1750 + "type": "string"
     1751 + },
     1752 + "mode": {
     1753 + "type": "integer"
     1754 + },
     1755 + "size": {
     1756 + "type": "integer"
     1757 + },
     1758 + "digest": {
     1759 + "$ref": "#/$defs/Digest"
     1760 + },
     1761 + "userName": {
     1762 + "type": "string"
     1763 + },
     1764 + "groupName": {
     1765 + "type": "string"
     1766 + },
     1767 + "flags": {
     1768 + "type": "string"
     1769 + }
     1770 + },
     1771 + "type": "object",
     1772 + "required": [
     1773 + "path",
     1774 + "mode",
     1775 + "size",
     1776 + "digest",
     1777 + "userName",
     1778 + "groupName",
     1779 + "flags"
     1780 + ]
     1781 + },
     1782 + "Schema": {
     1783 + "properties": {
     1784 + "version": {
     1785 + "type": "string"
     1786 + },
     1787 + "url": {
     1788 + "type": "string"
     1789 + }
     1790 + },
     1791 + "type": "object",
     1792 + "required": [
     1793 + "version",
     1794 + "url"
     1795 + ]
     1796 + },
     1797 + "SearchResult": {
     1798 + "properties": {
     1799 + "classification": {
     1800 + "type": "string"
     1801 + },
     1802 + "lineNumber": {
     1803 + "type": "integer"
     1804 + },
     1805 + "lineOffset": {
     1806 + "type": "integer"
     1807 + },
     1808 + "seekPosition": {
     1809 + "type": "integer"
     1810 + },
     1811 + "length": {
     1812 + "type": "integer"
     1813 + },
     1814 + "value": {
     1815 + "type": "string"
     1816 + }
     1817 + },
     1818 + "type": "object",
     1819 + "required": [
     1820 + "classification",
     1821 + "lineNumber",
     1822 + "lineOffset",
     1823 + "seekPosition",
     1824 + "length"
     1825 + ]
     1826 + },
     1827 + "Secrets": {
     1828 + "properties": {
     1829 + "location": {
     1830 + "$ref": "#/$defs/Coordinates"
     1831 + },
     1832 + "secrets": {
     1833 + "items": {
     1834 + "$ref": "#/$defs/SearchResult"
     1835 + },
     1836 + "type": "array"
     1837 + }
     1838 + },
     1839 + "type": "object",
     1840 + "required": [
     1841 + "location",
     1842 + "secrets"
     1843 + ]
     1844 + },
     1845 + "Source": {
     1846 + "properties": {
     1847 + "id": {
     1848 + "type": "string"
     1849 + },
     1850 + "type": {
     1851 + "type": "string"
     1852 + },
     1853 + "target": true
     1854 + },
     1855 + "type": "object",
     1856 + "required": [
     1857 + "id",
     1858 + "type",
     1859 + "target"
     1860 + ]
     1861 + }
     1862 + }
     1863 +}
     1864 + 
  • ■ ■ ■ ■ ■ ■
    syft/formats/common/spdxhelpers/source_info.go
    skipped 51 lines
    52 52   answer = "acquired package info from linux kernel module files"
    53 53   case pkg.NixPkg:
    54 54   answer = "acquired package info from nix store path"
     55 + case pkg.Rpkg:
     56 + answer = "acquired package info from R-package DESCRIPTION file"
    55 57   default:
    56 58   answer = "acquired package info from the following paths"
    57 59   }
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    syft/formats/common/spdxhelpers/source_info_test.go
    skipped 222 lines
    223 223   "from nix store path",
    224 224   },
    225 225   },
     226 + {
     227 + input: pkg.Package{
     228 + Type: pkg.Rpkg,
     229 + },
     230 + expected: []string{
     231 + "acquired package info from R-package DESCRIPTION file",
     232 + },
     233 + },
    226 234   }
    227 235   var pkgTypes []pkg.Type
    228 236   for _, test := range tests {
    skipped 13 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/cataloger.go
    skipped 27 lines
    28 28   "github.com/anchore/syft/syft/pkg/cataloger/php"
    29 29   "github.com/anchore/syft/syft/pkg/cataloger/portage"
    30 30   "github.com/anchore/syft/syft/pkg/cataloger/python"
     31 + "github.com/anchore/syft/syft/pkg/cataloger/r"
    31 32   "github.com/anchore/syft/syft/pkg/cataloger/rpm"
    32 33   "github.com/anchore/syft/syft/pkg/cataloger/ruby"
    33 34   "github.com/anchore/syft/syft/pkg/cataloger/rust"
    skipped 19 lines
    53 54   php.NewComposerInstalledCataloger(),
    54 55   portage.NewPortageCataloger(),
    55 56   python.NewPythonPackageCataloger(),
     57 + r.NewPackageCataloger(),
    56 58   rpm.NewRpmDBCataloger(),
    57 59   ruby.NewGemSpecCataloger(),
    58 60   sbom.NewSBOMCataloger(),
    skipped 62 lines
    121 123   portage.NewPortageCataloger(),
    122 124   python.NewPythonIndexCataloger(),
    123 125   python.NewPythonPackageCataloger(),
     126 + r.NewPackageCataloger(),
    124 127   rpm.NewFileCataloger(),
    125 128   rpm.NewRpmDBCataloger(),
    126 129   ruby.NewGemFileLockCataloger(),
    skipped 72 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/cataloger.go
     1 +package r
     2 + 
     3 +import (
     4 + "github.com/anchore/syft/syft/pkg/cataloger/generic"
     5 +)
     6 + 
     7 +const catalogerName = "r-package-cataloger"
     8 + 
     9 +// NewPackageCataloger returns a new R cataloger object based on detection of R package DESCRIPTION files.
     10 +func NewPackageCataloger() *generic.Cataloger {
     11 + return generic.NewCataloger(catalogerName).
     12 + WithParserByGlobs(parseDescriptionFile, "**/DESCRIPTION")
     13 +}
     14 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/cataloger_test.go
     1 +package r
     2 + 
     3 +import (
     4 + "testing"
     5 + 
     6 + "github.com/anchore/syft/syft/artifact"
     7 + "github.com/anchore/syft/syft/pkg"
     8 + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
     9 + "github.com/anchore/syft/syft/source"
     10 +)
     11 + 
     12 +func TestRPackageCataloger(t *testing.T) {
     13 + expectedPkgs := []pkg.Package{
     14 + {
     15 + Name: "base",
     16 + Version: "4.3.0",
     17 + FoundBy: "r-package-cataloger",
     18 + Locations: source.NewLocationSet(source.NewLocation("base/DESCRIPTION")),
     19 + Licenses: []string{"Part of R 4.3.0"},
     20 + Language: pkg.R,
     21 + Type: pkg.Rpkg,
     22 + PURL: "pkg:cran/[email protected]",
     23 + MetadataType: pkg.RDescriptionFileMetadataType,
     24 + Metadata: pkg.RDescriptionFileMetadata{
     25 + Title: "The R Base Package",
     26 + Description: "Base R functions.",
     27 + Author: "R Core Team and contributors worldwide",
     28 + Maintainer: "R Core Team <[email protected]>",
     29 + Built: "R 4.3.0; ; 2023-04-21 11:33:09 UTC; unix",
     30 + Suggests: []string{"methods"},
     31 + },
     32 + },
     33 + {
     34 + Name: "stringr",
     35 + Version: "1.5.0.9000",
     36 + FoundBy: "r-package-cataloger",
     37 + Locations: source.NewLocationSet(source.NewLocation("stringr/DESCRIPTION")),
     38 + Licenses: []string{"MIT + file LICENSE"},
     39 + Language: pkg.R,
     40 + Type: pkg.Rpkg,
     41 + PURL: "pkg:cran/[email protected]",
     42 + MetadataType: pkg.RDescriptionFileMetadataType,
     43 + Metadata: pkg.RDescriptionFileMetadata{
     44 + Title: "Simple, Consistent Wrappers for Common String Operations",
     45 + Description: "A consistent, simple and easy to use set of wrappers around the fantastic 'stringi' package. All function and argument names (and positions) are consistent, all functions deal with \"NA\"'s and zero length vectors in the same way, and the output from one function is easy to feed into the input of another.",
     46 + URL: []string{"https://stringr.tidyverse.org", "https://github.com/tidyverse/stringr"},
     47 + Imports: []string{
     48 + "cli", "glue (>= 1.6.1)", "lifecycle (>= 1.0.3)", "magrittr",
     49 + "rlang (>= 1.0.0)", "stringi (>= 1.5.3)", "vctrs (>= 0.4.0)",
     50 + },
     51 + Depends: []string{"R (>= 3.3)"},
     52 + Suggests: []string{"covr", "dplyr", "gt", "htmltools", "htmlwidgets", "knitr", "rmarkdown", "testthat (>= 3.0.0)", "tibble"},
     53 + },
     54 + },
     55 + }
     56 + // TODO: relationships are not under test yet
     57 + var expectedRelationships []artifact.Relationship
     58 + 
     59 + pkgtest.NewCatalogTester().FromDirectory(t, "test-fixtures/installed").Expects(expectedPkgs, expectedRelationships).TestCataloger(t, NewPackageCataloger())
     60 +}
     61 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/package.go
     1 +package r
     2 + 
     3 +import (
     4 + "github.com/anchore/packageurl-go"
     5 + "github.com/anchore/syft/syft/pkg"
     6 + "github.com/anchore/syft/syft/source"
     7 +)
     8 + 
     9 +func newPackage(pd parseData, locations ...source.Location) pkg.Package {
     10 + locationSet := source.NewLocationSet()
     11 + for _, loc := range locations {
     12 + locationSet.Add(loc.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation))
     13 + }
     14 + result := pkg.Package{
     15 + Name: pd.Package,
     16 + Version: pd.Version,
     17 + Locations: locationSet,
     18 + Licenses: []string{pd.License},
     19 + Language: pkg.R,
     20 + Type: pkg.Rpkg,
     21 + PURL: packageURL(pd),
     22 + MetadataType: pkg.RDescriptionFileMetadataType,
     23 + Metadata: pd.RDescriptionFileMetadata,
     24 + }
     25 + 
     26 + result.SetID()
     27 + return result
     28 +}
     29 + 
     30 +func packageURL(m parseData) string {
     31 + return packageurl.NewPackageURL("cran", "", m.Package, m.Version, nil, "").ToString()
     32 +}
     33 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/package_test.go
     1 +package r
     2 + 
     3 +import "testing"
     4 + 
     5 +func Test_newPackage(t *testing.T) {
     6 + testCases := []struct {
     7 + name string
     8 + }{}
     9 + 
     10 + for _, tt := range testCases {
     11 + t.Run(tt.name, func(t *testing.T) {
     12 + })
     13 + }
     14 +}
     15 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/parse_description.go
     1 +package r
     2 + 
     3 +import (
     4 + "bufio"
     5 + "io"
     6 + "regexp"
     7 + "strings"
     8 + 
     9 + "github.com/anchore/syft/syft/artifact"
     10 + "github.com/anchore/syft/syft/pkg"
     11 + "github.com/anchore/syft/syft/pkg/cataloger/generic"
     12 + "github.com/anchore/syft/syft/source"
     13 +)
     14 + 
     15 +/* some examples of license strings found in DESCRIPTION files:
     16 +find /usr/local/lib/R -name DESCRIPTION | xargs cat | grep 'License:' | sort | uniq
     17 +License: GPL
     18 +License: GPL (>= 2)
     19 +License: GPL (>=2)
     20 +License: GPL(>=2)
     21 +License: GPL (>= 2) | file LICENCE
     22 +License: GPL-2 | GPL-3
     23 +License: GPL-3
     24 +License: LGPL (>= 2)
     25 +License: LGPL (>= 2.1)
     26 +License: MIT + file LICENSE
     27 +License: Part of R 4.3.0
     28 +License: Unlimited
     29 +*/
     30 + 
     31 +func parseDescriptionFile(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
     32 + values := extractFieldsFromDescriptionFile(reader)
     33 + m := parseDataFromDescriptionMap(values)
     34 + p := newPackage(m, []source.Location{reader.Location}...)
     35 + if p.Name == "" || p.Version == "" {
     36 + return nil, nil, nil
     37 + }
     38 + return []pkg.Package{p}, nil, nil
     39 +}
     40 + 
     41 +type parseData struct {
     42 + Package string
     43 + Version string
     44 + License string
     45 + pkg.RDescriptionFileMetadata
     46 +}
     47 + 
     48 +func parseDataFromDescriptionMap(values map[string]string) parseData {
     49 + return parseData{
     50 + License: values["License"],
     51 + Package: values["Package"],
     52 + Version: values["Version"],
     53 + RDescriptionFileMetadata: pkg.RDescriptionFileMetadata{
     54 + Title: values["Title"],
     55 + Description: cleanMultiLineValue(values["Description"]),
     56 + Maintainer: values["Maintainer"],
     57 + URL: commaSeparatedList(values["URL"]),
     58 + Depends: commaSeparatedList(values["Depends"]),
     59 + Imports: commaSeparatedList(values["Imports"]),
     60 + Suggests: commaSeparatedList(values["Suggests"]),
     61 + NeedsCompilation: yesNoToBool(values["NeedsCompilation"]),
     62 + Author: values["Author"],
     63 + Repository: values["Repository"],
     64 + Built: values["Built"],
     65 + },
     66 + }
     67 +}
     68 + 
     69 +func yesNoToBool(s string) bool {
     70 + /*
     71 + $ docker run --rm -it rocker/r-ver bash
     72 + $ install2.r ggplot2 dplyr mlr3 caret # just some packages for a larger sample
     73 + $ find /usr/local/lib/R -name DESCRIPTION | xargs cat | grep 'NeedsCompilation:' | sort | uniq
     74 + NeedsCompilation: no
     75 + NeedsCompilation: yes
     76 + $ find /usr/local/lib/R -name DESCRIPTION | xargs cat | grep 'NeedsCompilation:' | wc -l
     77 + 105
     78 + */
     79 + return strings.EqualFold(s, "yes")
     80 +}
     81 + 
     82 +func commaSeparatedList(s string) []string {
     83 + var result []string
     84 + split := strings.Split(s, ",")
     85 + for _, piece := range split {
     86 + value := strings.TrimSpace(piece)
     87 + if value == "" {
     88 + continue
     89 + }
     90 + result = append(result, value)
     91 + }
     92 + return result
     93 +}
     94 + 
     95 +var space = regexp.MustCompile(`\s+`)
     96 + 
     97 +func cleanMultiLineValue(s string) string {
     98 + return space.ReplaceAllString(s, " ")
     99 +}
     100 + 
     101 +func extractFieldsFromDescriptionFile(reader io.Reader) map[string]string {
     102 + result := make(map[string]string)
     103 + key := ""
     104 + var valueFragment strings.Builder
     105 + scanner := bufio.NewScanner(reader)
     106 + 
     107 + for scanner.Scan() {
     108 + line := scanner.Text()
     109 + // line is like Key: Value -> start capturing value; close out previous value
     110 + // line is like \t\t continued value -> append to existing value
     111 + if len(line) == 0 {
     112 + continue
     113 + }
     114 + if startsWithWhitespace(line) {
     115 + // we're continuing a value
     116 + if key == "" {
     117 + continue
     118 + }
     119 + valueFragment.WriteByte('\n')
     120 + valueFragment.WriteString(strings.TrimSpace(line))
     121 + } else {
     122 + if key != "" {
     123 + // capture previous value
     124 + result[key] = valueFragment.String()
     125 + key = ""
     126 + valueFragment = strings.Builder{}
     127 + }
     128 + parts := strings.SplitN(line, ":", 2)
     129 + if len(parts) != 2 {
     130 + continue
     131 + }
     132 + key = parts[0]
     133 + valueFragment.WriteString(strings.TrimSpace(parts[1]))
     134 + }
     135 + }
     136 + if key != "" {
     137 + result[key] = valueFragment.String()
     138 + }
     139 + return result
     140 +}
     141 + 
     142 +func startsWithWhitespace(s string) bool {
     143 + if s == "" {
     144 + return false
     145 + }
     146 + return s[0] == ' ' || s[0] == '\t'
     147 +}
     148 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/parse_description_test.go
     1 +package r
     2 + 
     3 +import (
     4 + "os"
     5 + "path/filepath"
     6 + "testing"
     7 + 
     8 + "github.com/stretchr/testify/assert"
     9 + "github.com/stretchr/testify/require"
     10 + 
     11 + "github.com/anchore/syft/syft/pkg"
     12 + "github.com/anchore/syft/syft/source"
     13 +)
     14 + 
     15 +func Test_parseDescriptionFile(t *testing.T) {
     16 + type packageAssertions []func(*testing.T, []pkg.Package)
     17 + tests := []struct {
     18 + name string
     19 + assertions packageAssertions
     20 + fixture string
     21 + }{
     22 + {
     23 + name: "no package is returned if no version found",
     24 + fixture: filepath.Join("test-fixtures", "map-parse", "no-version"),
     25 + assertions: packageAssertions{
     26 + func(t *testing.T, p []pkg.Package) {
     27 + assert.Empty(t, p)
     28 + },
     29 + },
     30 + },
     31 + {
     32 + name: "no package is returned if no package name found",
     33 + fixture: filepath.Join("test-fixtures", "map-parse", "no-name"),
     34 + assertions: packageAssertions{
     35 + func(t *testing.T, p []pkg.Package) {
     36 + assert.Empty(t, p)
     37 + },
     38 + },
     39 + },
     40 + {
     41 + name: "package return if both name and version found",
     42 + fixture: filepath.Join("test-fixtures", "map-parse", "simple"),
     43 + assertions: packageAssertions{
     44 + func(t *testing.T, p []pkg.Package) {
     45 + assert.Equal(t, 1, len(p))
     46 + assert.Equal(t, "base", p[0].Name)
     47 + assert.Equal(t, "4.3.0", p[0].Version)
     48 + },
     49 + },
     50 + },
     51 + }
     52 + 
     53 + for _, tt := range tests {
     54 + t.Run(tt.name, func(t *testing.T) {
     55 + f, err := os.Open(tt.fixture)
     56 + input := source.LocationReadCloser{
     57 + Location: source.NewLocation(tt.fixture),
     58 + ReadCloser: f,
     59 + }
     60 + got, _, err := parseDescriptionFile(nil, nil, input)
     61 + assert.NoError(t, err)
     62 + for _, assertion := range tt.assertions {
     63 + assertion(t, got)
     64 + }
     65 + })
     66 + }
     67 +}
     68 + 
     69 +func Test_extractFieldsFromDescriptionFile(t *testing.T) {
     70 + tests := []struct {
     71 + name string
     72 + fixture string
     73 + want map[string]string
     74 + }{
     75 + {
     76 + name: "go case",
     77 + fixture: "test-fixtures/map-parse/simple",
     78 + want: map[string]string{
     79 + "Package": "base",
     80 + "Version": "4.3.0",
     81 + "Suggests": "methods",
     82 + "Built": "R 4.3.0; ; 2023-04-21 11:33:09 UTC; unix",
     83 + },
     84 + },
     85 + {
     86 + name: "bad cases",
     87 + fixture: "test-fixtures/map-parse/bad",
     88 + want: map[string]string{
     89 + "Key": "",
     90 + "Whitespace": "",
     91 + },
     92 + },
     93 + {
     94 + name: "multiline key-value",
     95 + fixture: "test-fixtures/map-parse/multiline",
     96 + want: map[string]string{
     97 + "Description": `A consistent, simple and easy to use set of wrappers around
     98 +the fantastic 'stringi' package. All function and argument names (and
     99 +positions) are consistent, all functions deal with "NA"'s and zero
     100 +length vectors in the same way, and the output from one function is
     101 +easy to feed into the input of another.`,
     102 + "License": "MIT + file LICENSE",
     103 + "Key": "value",
     104 + },
     105 + },
     106 + {
     107 + name: "eof multiline",
     108 + fixture: "test-fixtures/map-parse/eof-multiline",
     109 + want: map[string]string{
     110 + "License": "MIT + file LICENSE",
     111 + "Description": `A consistent, simple and easy to use set of wrappers around
     112 +the fantastic 'stringi' package. All function and argument names (and
     113 +positions) are consistent, all functions deal with "NA"'s and zero
     114 +length vectors in the same way, and the output from one function is
     115 +easy to feed into the input of another.`,
     116 + },
     117 + },
     118 + }
     119 + 
     120 + for _, test := range tests {
     121 + t.Run(test.name, func(t *testing.T) {
     122 + file, err := os.Open(test.fixture)
     123 + require.NoError(t, err)
     124 + 
     125 + result := extractFieldsFromDescriptionFile(file)
     126 + 
     127 + assert.Equal(t, test.want, result)
     128 + })
     129 + }
     130 + 
     131 +}
     132 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/DESCRIPTION
     1 +Package: stringr
     2 +Title: Simple, Consistent Wrappers for Common String Operations
     3 +Version: 1.5.0.9000
     4 +Authors@R:
     5 + c(person(given = "Hadley",
     6 + family = "Wickham",
     7 + role = c("aut", "cre", "cph"),
     8 + email = "[email protected]"),
     9 + person(given = "RStudio",
     10 + role = c("cph", "fnd")))
     11 +Description: A consistent, simple and easy to use set of wrappers around
     12 + the fantastic 'stringi' package. All function and argument names (and
     13 + positions) are consistent, all functions deal with "NA"'s and zero
     14 + length vectors in the same way, and the output from one function is
     15 + easy to feed into the input of another.
     16 +License: MIT + file LICENSE
     17 +URL: https://stringr.tidyverse.org, https://github.com/tidyverse/stringr
     18 +BugReports: https://github.com/tidyverse/stringr/issues
     19 +Depends:
     20 + R (>= 3.3)
     21 +Imports:
     22 + cli,
     23 + glue (>= 1.6.1),
     24 + lifecycle (>= 1.0.3),
     25 + magrittr,
     26 + rlang (>= 1.0.0),
     27 + stringi (>= 1.5.3),
     28 + vctrs (>= 0.4.0)
     29 +Suggests:
     30 + covr,
     31 + dplyr,
     32 + gt,
     33 + htmltools,
     34 + htmlwidgets,
     35 + knitr,
     36 + rmarkdown,
     37 + testthat (>= 3.0.0),
     38 + tibble
     39 +VignetteBuilder:
     40 + knitr
     41 +Config/Needs/website: tidyverse/tidytemplate
     42 +Config/testthat/edition: 3
     43 +Encoding: UTF-8
     44 +LazyData: true
     45 +Roxygen: list(markdown = TRUE)
     46 +RoxygenNote: 7.2.1
     47 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/installed/base/DESCRIPTION
     1 +Package: base
     2 +Version: 4.3.0
     3 +Priority: base
     4 +Title: The R Base Package
     5 +Author: R Core Team and contributors worldwide
     6 +Maintainer: R Core Team <[email protected]>
     7 +Contact: R-help mailing list <[email protected]>
     8 +Description: Base R functions.
     9 +License: Part of R 4.3.0
     10 +Suggests: methods
     11 +Built: R 4.3.0; ; 2023-04-21 11:33:09 UTC; unix
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/installed/stringr/DESCRIPTION
     1 +Package: stringr
     2 +Title: Simple, Consistent Wrappers for Common String Operations
     3 +Version: 1.5.0.9000
     4 +Authors@R:
     5 + c(person(given = "Hadley",
     6 + family = "Wickham",
     7 + role = c("aut", "cre", "cph"),
     8 + email = "[email protected]"),
     9 + person(given = "RStudio",
     10 + role = c("cph", "fnd")))
     11 +Description: A consistent, simple and easy to use set of wrappers around
     12 + the fantastic 'stringi' package. All function and argument names (and
     13 + positions) are consistent, all functions deal with "NA"'s and zero
     14 + length vectors in the same way, and the output from one function is
     15 + easy to feed into the input of another.
     16 +License: MIT + file LICENSE
     17 +URL: https://stringr.tidyverse.org, https://github.com/tidyverse/stringr
     18 +BugReports: https://github.com/tidyverse/stringr/issues
     19 +Depends:
     20 + R (>= 3.3)
     21 +Imports:
     22 + cli,
     23 + glue (>= 1.6.1),
     24 + lifecycle (>= 1.0.3),
     25 + magrittr,
     26 + rlang (>= 1.0.0),
     27 + stringi (>= 1.5.3),
     28 + vctrs (>= 0.4.0)
     29 +Suggests:
     30 + covr,
     31 + dplyr,
     32 + gt,
     33 + htmltools,
     34 + htmlwidgets,
     35 + knitr,
     36 + rmarkdown,
     37 + testthat (>= 3.0.0),
     38 + tibble
     39 +VignetteBuilder:
     40 + knitr
     41 +Config/Needs/website: tidyverse/tidytemplate
     42 +Config/testthat/edition: 3
     43 +Encoding: UTF-8
     44 +LazyData: true
     45 +Roxygen: list(markdown = TRUE)
     46 +RoxygenNote: 7.2.1
     47 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/map-parse/bad
     1 +MissingColon
     2 +Whitespace:
     3 +Key:
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/map-parse/eof-multiline
     1 +License: MIT + file LICENSE
     2 +Description: A consistent, simple and easy to use set of wrappers around
     3 + the fantastic 'stringi' package. All function and argument names (and
     4 + positions) are consistent, all functions deal with "NA"'s and zero
     5 + length vectors in the same way, and the output from one function is
     6 + easy to feed into the input of another.
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/map-parse/multiline
     1 +Key: value
     2 + 
     3 +Description: A consistent, simple and easy to use set of wrappers around
     4 + the fantastic 'stringi' package. All function and argument names (and
     5 + positions) are consistent, all functions deal with "NA"'s and zero
     6 + length vectors in the same way, and the output from one function is
     7 + easy to feed into the input of another.
     8 +License: MIT + file LICENSE
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/map-parse/no-name
     1 +Version: 1.2.3
     2 +Description: a package with no name
     3 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/map-parse/no-version
     1 +Package: foo
     2 + 
  • ■ ■ ■ ■ ■
    syft/pkg/cataloger/r/test-fixtures/map-parse/simple
     1 +Package: base
     2 +Version: 4.3.0
     3 +Suggests: methods
     4 +Built: R 4.3.0; ; 2023-04-21 11:33:09 UTC; unix
     5 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/language.go
    skipped 22 lines
    23 23   JavaScript Language = "javascript"
    24 24   PHP Language = "php"
    25 25   Python Language = "python"
     26 + R Language = "R"
    26 27   Ruby Language = "ruby"
    27 28   Rust Language = "rust"
    28 29   Swift Language = "swift"
    skipped 12 lines
    41 42   JavaScript,
    42 43   PHP,
    43 44   Python,
     45 + R,
    44 46   Ruby,
    45 47   Rust,
    46 48   Swift,
    skipped 44 lines
    91 93   // answer: no. We want this to definitively answer "which language does this package represent?"
    92 94   // which might not be possible in all cases. See for more context: https://github.com/package-url/purl-spec/pull/178
    93 95   return UnknownLanguage
     96 + case packageurl.TypeCran, "r":
     97 + return R
    94 98   default:
    95 99   return UnknownLanguage
    96 100   }
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/language_test.go
    skipped 65 lines
    66 66   purl: "pkg:hex/hpax/[email protected]",
    67 67   want: UnknownLanguage,
    68 68   },
     69 + {
     70 + purl: "pkg:cran/[email protected]",
     71 + want: R,
     72 + },
    69 73   }
    70 74   
    71 75   var languages []string
    skipped 158 lines
    230 234   {
    231 235   name: "haskell",
    232 236   language: Haskell,
     237 + },
     238 + {
     239 + name: "R",
     240 + language: R,
    233 241   },
    234 242   }
    235 243   
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/metadata.go
    skipped 37 lines
    38 38   PythonPipfileLockMetadataType MetadataType = "PythonPipfileLockMetadata"
    39 39   PythonRequirementsMetadataType MetadataType = "PythonRequirementsMetadata"
    40 40   RebarLockMetadataType MetadataType = "RebarLockMetadataType"
     41 + RDescriptionFileMetadataType MetadataType = "RDescriptionFileMetadataType"
    41 42   RpmMetadataType MetadataType = "RpmMetadata"
    42 43   RustCargoPackageMetadataType MetadataType = "RustCargoPackageMetadata"
    43 44  )
    skipped 25 lines
    69 70   PythonPackageMetadataType,
    70 71   PythonPipfileLockMetadataType,
    71 72   PythonRequirementsMetadataType,
     73 + RDescriptionFileMetadataType,
    72 74   RebarLockMetadataType,
    73 75   RpmMetadataType,
    74 76   RustCargoPackageMetadataType,
    skipped 26 lines
    101 103   PythonPackageMetadataType: reflect.TypeOf(PythonPackageMetadata{}),
    102 104   PythonPipfileLockMetadataType: reflect.TypeOf(PythonPipfileLockMetadata{}),
    103 105   PythonRequirementsMetadataType: reflect.TypeOf(PythonRequirementsMetadata{}),
     106 + RDescriptionFileMetadataType: reflect.TypeOf(RDescriptionFileMetadata{}),
    104 107   RebarLockMetadataType: reflect.TypeOf(RebarLockMetadata{}),
    105 108   RpmMetadataType: reflect.TypeOf(RpmMetadata{}),
    106 109   RustCargoPackageMetadataType: reflect.TypeOf(CargoPackageMetadata{}),
    skipped 12 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/r_package_metadata.go
     1 +package pkg
     2 + 
     3 +type RDescriptionFileMetadata struct {
     4 + /*
     5 + Fields chosen by:
     6 + docker run --rm -it rocker/r-ver bash
     7 + $ install2.r ggplot2 # has a lot of dependencies
     8 + $ find /usr/local/lib/R -name DESCRIPTION | xargs cat | grep -v '^\s' | cut -d ':' -f 1 | sort | uniq -c | sort -nr
     9 + */
     10 + Title string `json:"title,omitempty"`
     11 + Description string `json:"description,omitempty"`
     12 + Author string `json:"author,omitempty"`
     13 + Maintainer string `json:"maintainer,omitempty"`
     14 + URL []string `json:"url,omitempty"`
     15 + Repository string `json:"repository,omitempty"`
     16 + Built string `json:"built,omitempty"`
     17 + NeedsCompilation bool `json:"needsCompilation,omitempty"`
     18 + Imports []string `json:"imports,omitempty"`
     19 + Depends []string `json:"depends,omitempty"`
     20 + Suggests []string `json:"suggests,omitempty"`
     21 +}
     22 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/type.go
    skipped 32 lines
    33 33   PhpComposerPkg Type = "php-composer"
    34 34   PortagePkg Type = "portage"
    35 35   PythonPkg Type = "python"
     36 + Rpkg Type = "R-package"
    36 37   RpmPkg Type = "rpm"
    37 38   RustPkg Type = "rust-crate"
    38 39  )
    skipped 22 lines
    61 62   PhpComposerPkg,
    62 63   PortagePkg,
    63 64   PythonPkg,
     65 + Rpkg,
    64 66   RpmPkg,
    65 67   RustPkg,
    66 68  }
    skipped 39 lines
    106 108   return "nix"
    107 109   case NpmPkg:
    108 110   return packageurl.TypeNPM
     111 + case Rpkg:
     112 + return packageurl.TypeCran
    109 113   case RpmPkg:
    110 114   return packageurl.TypeRPM
    111 115   case RustPkg:
    skipped 61 lines
    173 177   return LinuxKernelModulePkg
    174 178   case "nix":
    175 179   return NixPkg
     180 + case packageurl.TypeCran:
     181 + return Rpkg
    176 182   default:
    177 183   return UnknownPkg
    178 184   }
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/type_test.go
    skipped 90 lines
    91 91   purl: "pkg:nix/[email protected]?hash=h0cnbmfcn93xm5dg2x27ixhag1cwndga",
    92 92   expected: NixPkg,
    93 93   },
     94 + {
     95 + purl: "pkg:cran/[email protected]",
     96 + expected: Rpkg,
     97 + },
    94 98   }
    95 99   
    96 100   var pkgTypes []string
    skipped 29 lines
  • ■ ■ ■ ■ ■ ■
    test/cli/packages_cmd_test.go
    skipped 95 lines
    96 96   name: "squashed-scope-flag",
    97 97   args: []string{"packages", "-o", "json", "-s", "squashed", coverageImage},
    98 98   assertions: []traitAssertion{
    99  - assertPackageCount(35),
     99 + assertPackageCount(36),
    100 100   assertSuccessfulReturnCode,
    101 101   },
    102 102   },
    skipped 110 lines
    213 213   // the application config in the log matches that of what we expect to have been configured.
    214 214   assertInOutput("parallelism: 2"),
    215 215   assertInOutput("parallelism=2"),
    216  - assertPackageCount(35),
     216 + assertPackageCount(36),
    217 217   assertSuccessfulReturnCode,
    218 218   },
    219 219   },
    skipped 4 lines
    224 224   // the application config in the log matches that of what we expect to have been configured.
    225 225   assertInOutput("parallelism: 1"),
    226 226   assertInOutput("parallelism=1"),
    227  - assertPackageCount(35),
     227 + assertPackageCount(36),
    228 228   assertSuccessfulReturnCode,
    229 229   },
    230 230   },
    skipped 7 lines
    238 238   assertions: []traitAssertion{
    239 239   assertNotInOutput("secret_password"),
    240 240   assertNotInOutput("secret_key_path"),
    241  - assertPackageCount(35),
     241 + assertPackageCount(36),
    242 242   assertSuccessfulReturnCode,
    243 243   },
    244 244   },
    skipped 95 lines
  • ■ ■ ■ ■ ■ ■
    test/integration/catalog_packages_cases_test.go
    skipped 68 lines
    69 69   "joda-time": "2.9.2",
    70 70   },
    71 71   },
     72 + {
     73 + name: "find R packages",
     74 + pkgType: pkg.Rpkg,
     75 + pkgLanguage: pkg.R,
     76 + pkgInfo: map[string]string{
     77 + "base": "4.3.0",
     78 + },
     79 + },
    72 80  }
    73 81   
    74 82  var dirOnlyTestCases = []testCase{
    skipped 328 lines
  • ■ ■ ■ ■ ■ ■
    test/integration/catalog_packages_test.go
    skipped 219 lines
    220 220   
    221 221   observedLanguages.Remove(pkg.UnknownLanguage.String())
    222 222   definedLanguages.Remove(pkg.UnknownLanguage.String())
     223 + definedLanguages.Remove(pkg.R.String())
    223 224   observedPkgs.Remove(string(pkg.UnknownPkg))
    224 225   definedPkgs.Remove(string(pkg.BinaryPkg))
    225 226   definedPkgs.Remove(string(pkg.LinuxKernelPkg))
    226 227   definedPkgs.Remove(string(pkg.LinuxKernelModulePkg))
     228 + definedPkgs.Remove(string(pkg.Rpkg))
    227 229   definedPkgs.Remove(string(pkg.UnknownPkg))
    228 230   
    229 231   // for directory scans we should not expect to see any of the following package types
    skipped 93 lines
  • ■ ■ ■ ■ ■ ■
    test/integration/test-fixtures/image-pkg-coverage/pkgs/r/base/DESCRIPTION
     1 +Package: base
     2 +Version: 4.3.0
     3 +Priority: base
     4 +Title: The R Base Package
     5 +Author: R Core Team and contributors worldwide
     6 +Maintainer: R Core Team <[email protected]>
     7 +Contact: R-help mailing list <[email protected]>
     8 +Description: Base R functions.
     9 +License: Part of R 4.3.0
     10 +Suggests: methods
     11 +Built: R 4.3.0; ; 2023-04-21 11:33:09 UTC; unix
Please wait...
Page is in error, reload to recover