Skip to content

Commit dcc8570

Browse files
authored
[ANE-1639] add metadata to vendored dependencies (#1455)
* add metadata to archive * refactor * format * update docs * add test * update fossa-deps example * cr nits * fix test * fix spacing * remove newline
1 parent 93514ae commit dcc8570

23 files changed

+167
-67
lines changed

Changelog.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# FOSSA CLI Changelog
22

3+
## 3.9.30
4+
5+
- Vendored Dependencies: add support for metadata (description, and homepage) for dependencies. ([#1455](https://github.com/fossas/fossa-cli/pull/1455))
6+
37
## 3.9.29
48
- install scripts: Surface curl errors and display http status code correctly. ([#1456](https://github.com/fossas/fossa-cli/pull/1456))
59
- Update jar-callgraph version to 1.0.2 [#1454](https://github.com/fossas/fossa-cli/pull/1454)

docs/features/vendored-dependencies.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ vendored-dependencies:
1717
- name: Django
1818
path: vendor/Django-3.4.16.zip # path can be either a file or a folder.
1919
version: "3.4.16" # revision will be set to the MD5 hash of the filepath if left unspecified.
20+
# You can also provide a description and/or homepage. These values populate metadata fields in reports in the FOSSA web UI.
21+
- name: Winston
22+
path: vendor/winston.zip
23+
version: "5.0.0-alpha"
24+
metadata:
25+
description: "winston archive"
26+
homepage: "https://winston-project.com"
2027
```
2128
2229
The path to a vendored dependency can either be a path to an archive or a path to a directory.
@@ -27,6 +34,8 @@ If the version is not specified, FOSSA CLI calculates the version by generating
2734
2835
Note: When parsed, YAML considers text that could be a decimal number (such as 1.0 or 2.0) to be a number, not a string. This means that we'd parse the version 1.0 as 1. This probably isn't what you want. To avoid this, surround your version with quotes, as in "1.0".
2936
37+
You can also optionally add metadata fields ("description" and "homepage") to populate these fields in the FOSSA web UI (these fields can be displayed when generating reports).
38+
3039
We also support json-formatted dependencies:
3140
3241
```json
@@ -63,7 +72,11 @@ We also support json-formatted dependencies:
6372
}, {
6473
"name": "winston",
6574
"path": "vendor/winston.tar.gz",
66-
"version": "5.0.0-alpha"
75+
"version": "5.0.0-alpha",
76+
"metadata": {
77+
"description": "winston archive",
78+
"homepage": "https://winston-project.com/homepage"
79+
}
6780
}
6881
],
6982
"remote-dependencies": [

docs/references/files/fossa-deps.md

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# `fossa-deps`
22

3-
`fossa-deps` file is a file named `fossa-deps.{yaml, yml, json}` at the root of the project. It can be used to provide manual and vendor dependencies.
3+
`fossa-deps` file is a file named `fossa-deps.{yaml, yml, json}` at the root of the project. It can be used to provide manual and vendor dependencies.
44

55
By default, the `fossa-deps.{yaml, yml, json}` file at the root of the project is used. However, if the `--fossa-deps-file` flag is present, then the provided `<name-of-file>.{yaml, yaml, json}` file will be used instead.
66

@@ -10,7 +10,7 @@ For more details on specifying a fossa-deps file, please refer to the [subcomman
1010

1111
### `referenced-dependencies:`
1212

13-
Denotes listing of dependencies, which are to be analyzed in conjunction with the analysis.
13+
Denotes listing of dependencies, which are to be analyzed in conjunction with the analysis.
1414

1515
- `type`: Type of dependency. (Required)
1616
- `name`: Name of the dependency. It should be the same name as listed in dependencies registry. (Required)
@@ -25,20 +25,20 @@ referenced-dependencies:
2525
version: 2.1.7
2626
```
2727
28-
For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through.
28+
For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through.
2929
3030
### `custom-dependencies:`
3131

32-
Denotes listing of dependencies, which can't be automatically discovered or identified but are to be stubbed and included in the analysis.
32+
Denotes listing of dependencies, which can't be automatically discovered or identified but are to be stubbed and included in the analysis.
3333

3434
- `name`: Name of the dependency. (Required)
3535
- `version`: Revision of the dependency. (Required)
3636
- `license`: License of the dependency. (Required)
3737
- `metadata.homepage`: Homepage of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface.
3838
- `metadata.description`: Description of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface.
3939

40-
Example:
41-
```yaml
40+
Example:
41+
```yaml
4242
- name: foo-wrapper
4343
version: 1.2.3
4444
license: MIT
@@ -47,7 +47,7 @@ Example:
4747
description: Provides foo and a helpful interface around foo-like tasks.
4848
```
4949

50-
For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through.
50+
For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through.
5151

5252
### `remote-dependencies:`
5353

@@ -62,29 +62,34 @@ Denotes listing of dependencies, whose source code is to be downloaded from prov
6262
> Combined length of url and version has upper bound. It depends on your organization identifier. You can
6363
find your organization identifier in FOSSA Webapp, by going to any project's "settings" page, and retrieving
6464
numeric value from project's locator. For example, project locator of `custom+123/some-project-id`, means
65-
`123` is your organization identifier.
65+
`123` is your organization identifier.
6666

6767
> Combined length of `url`, `version`, and your `organizaion id` must be less than `241`.
6868

69-
For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through.
69+
For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through.
7070

7171
### `vendored-dependencies:`
7272

7373
Denotes listing of files or directories, which are to be archived and uploaded to FOSSA backend for license scanning.
7474

7575
- `name`: Name of the dependency (Required)
7676
- `path`: Local path to a file, or a directory (Required)
77-
- `version`: Revision of the dependency. If not specified, the md5 hash of the file path will be used.
77+
- `version`: Revision of the dependency. If not specified, the md5 hash of the file path will be used.
78+
- `metadata.homepage`: Homepage of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface.
79+
- `metadata.description`: Description of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface.
7880

7981
```yaml
8082
vendored-dependencies:
8183
- name: Django
8284
path: vendor/Django-3.4.16.zip
8385
version: 3.4.16
86+
metadata:
87+
homepage: https://djangoproject.com
88+
description: Django
8489
```
8590
> Note: License scanning currently operates by uploading the files at the specified path to a secure S3 bucket. All files that do not contain licenses are then removed after 2 weeks.
8691

87-
For more details, please refer to the [feature](../../features/vendored-dependencies.md) walk through.
92+
For more details, please refer to the [feature](../../features/vendored-dependencies.md) walk through.
8893

8994
## Errors in the `fossa-deps` file
9095

docs/references/files/fossa-deps.schema.json

+13
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,19 @@
212212
"version": {
213213
"type": "string",
214214
"description": "Version of the dependency. This will be the version associated with this vendored dependency in FOSSA's dashboard"
215+
},
216+
"metadata": {
217+
"type": "object",
218+
"properties": {
219+
"description": {
220+
"type": "string",
221+
"description": "Description of the dependency (if any)"
222+
},
223+
"homepage": {
224+
"type": "string",
225+
"description": "Homepage of the dependency. This should be web address."
226+
}
227+
}
215228
}
216229
},
217230
"required": [

docs/walkthroughs/conan.md

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Custom Integration with Conan Package Manager
22

3-
Conan is a dependency and package manager for C and C++ languages. It is free and open-source, works on all
4-
platforms (Windows, Linux, OSX, FreeBSD, Solaris, etc.), and can be used to develop for all targets, including
5-
embedded, mobile (iOS, Android), and bare metal. It also integrates with all build systems like CMake,
3+
Conan is a dependency and package manager for C and C++ languages. It is free and open-source, works on all
4+
platforms (Windows, Linux, OSX, FreeBSD, Solaris, etc.), and can be used to develop for all targets, including
5+
embedded, mobile (iOS, Android), and bare metal. It also integrates with all build systems like CMake,
66
Visual Studio (MSBuild), Makefiles, etc., including proprietary ones.
77

88
## Prerequisite
@@ -12,8 +12,8 @@ Visual Studio (MSBuild), Makefiles, etc., including proprietary ones.
1212

1313
## Integration
1414

15-
This integration uses the `conan graph info` command to retrieve the dependency graph and source code for all dependencies. From this data, it generates [fossa-deps](./../references/files/fossa-deps.md) file with
16-
[vendor-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md).
15+
This integration uses the `conan graph info` command to retrieve the dependency graph and source code for all dependencies. From this data, it generates [fossa-deps](./../references/files/fossa-deps.md) file with
16+
[vendored-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md).
1717

1818
To use this integration,
1919
1. Download [make_fossa_deps_conan.py](./make_fossa_deps_conan.py) python script, and place it in the same directory as `conanfile.txt` or `conanfile.py.`
@@ -32,7 +32,7 @@ In this approach, `make_fossa_deps_conan.py` does the followings:
3232

3333
### Limitations
3434

35-
This integration method uses [vendor-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md)
35+
This integration method uses [vendored-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md)
3636
functionalities, and as such, it does not provide the following,
3737

3838
- Security functionalities (FOSSA will not be able to identify vulnerabilities, only licensing and copyright issues)
@@ -92,11 +92,11 @@ script is supplied as a potential option if you want to start using FOSSA for Co
9292
This integration example uses the `conan graph info` command with `--format json` and
9393
`-c tools.build:download_source=True` option, which are only available in Conan v2 (`v2.0.0+`).
9494

95-
#### 3. I want to use a custom profile or provide additional options.
95+
#### 3. I want to use a custom profile or provide additional options.
9696

9797
You can provide any additional [`conan graph info`](https://docs.conan.io/2.0/reference/commands/graph/info.html) options (except `--format` or `-f`)
9898

99-
To do so, provide options to the Python script. For example,
99+
To do so, provide options to the Python script. For example,
100100

101101
```bash
102102
>> python3 make_fossa_deps_conan.py -s compiler=gcc
@@ -116,4 +116,3 @@ that declared license is always used.
116116

117117
- [Conan Package Manager](https://docs.conan.io)
118118
- [Conan graph command](https://docs.conan.io/2.0/reference/commands/graph/info.html)
119-

integration-test/Analysis/LicenseScannerSpec.hs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ vendoredDep =
4646
"recursive-archive-test"
4747
"vendor/foo.tar.gz"
4848
(Just "0.0.1")
49+
Nothing
4950

5051
-- the contents of the archive look like this. The `FOO_LICENSE` files contain an MIT license.
5152
-- `bar_apache.rb` and `something.rb` contain an Apache-2.0 license.

spectrometer.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ library
236236
App.Fossa.Container.Sources.Podman
237237
App.Fossa.Container.Sources.Registry
238238
App.Fossa.Container.Test
239+
App.Fossa.DependencyMetadata
239240
App.Fossa.DumpBinaries
240241
App.Fossa.EmbeddedBinary
241242
App.Fossa.FirstPartyScan

src/App/Fossa/ArchiveUploader.hs

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import App.Fossa.VendoredDependency (
99
arcToLocator,
1010
compressFile,
1111
dedupVendoredDeps,
12+
getMetadata,
1213
hashFile,
1314
)
1415
import App.Types (ComponentUploadFileType (..), DependencyRebuild)
@@ -52,7 +53,7 @@ compressAndUpload ::
5253
Path Abs Dir ->
5354
VendoredDependency ->
5455
m Archive
55-
compressAndUpload arcDir tmpDir VendoredDependency{..} = context "compressing and uploading vendored deps" $ do
56+
compressAndUpload arcDir tmpDir dep@VendoredDependency{..} = context "compressing and uploading vendored deps" $ do
5657
logSticky $ "Compressing '" <> vendoredName <> "' at '" <> vendoredPath <> "'"
5758
compressedFile <- sendIO $ compressFile tmpDir arcDir (toString vendoredPath)
5859

@@ -66,7 +67,7 @@ compressAndUpload arcDir tmpDir VendoredDependency{..} = context "compressing an
6667
res <- uploadArchive signedURL compressedFile
6768
logDebug . pretty $ (decodeUtf8 @Text res)
6869

69-
pure $ Archive vendoredName depVersion
70+
pure . uncurry (Archive vendoredName depVersion) $ (getMetadata dep)
7071

7172
-- archiveUploadSourceUnit receives a list of vendored dependencies, a root path, and API settings.
7273
-- Using this information, it uploads each vendored dependency and queues a build for the dependency.

src/App/Fossa/DependencyMetadata.hs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module App.Fossa.DependencyMetadata (
2+
DependencyMetadata (..),
3+
) where
4+
5+
import Data.Aeson (FromJSON (..), withObject, (.:?))
6+
import Data.Aeson.Extra (forbidMembers)
7+
import Data.Text (Text)
8+
9+
data DependencyMetadata = DependencyMetadata
10+
{ depDescription :: Maybe Text
11+
, depHomepage :: Maybe Text
12+
}
13+
deriving (Eq, Ord, Show)
14+
15+
instance FromJSON DependencyMetadata where
16+
parseJSON = withObject "metadata" $ \obj ->
17+
DependencyMetadata
18+
<$> obj .:? "description"
19+
<*> obj .:? "homepage"
20+
<* forbidMembers "metadata" ["url"] obj

src/App/Fossa/FirstPartyScan.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ firstPartyScanMain ::
9999
firstPartyScanMain base cfg org = do
100100
runFirstPartyScans <- shouldRunFirstPartyScans cfg org
101101
manualDeps <- findAndReadFossaDepsFile base
102-
let vdep = VendoredDependency "first-party" "." Nothing
102+
let vdep = VendoredDependency "first-party" "." Nothing Nothing
103103
uploadKind = orgFileUpload org
104104
pathFilters <- mergePathFilters base manualDeps (licenseScanPathFilters $ vendoredDeps cfg)
105105
case runFirstPartyScans of

src/App/Fossa/Init/fossa-deps.yml

+15-12
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#
2020
# # referenced-dependencies
2121
# # --
22-
# # Denotes listing of dependencies, which are to be analyzed in
23-
# # conjunction with the analysis. This is used for packages that
22+
# # Denotes listing of dependencies, which are to be analyzed in
23+
# # conjunction with the analysis. This is used for packages that
2424
# # originate from a known package manager.
2525
# #
2626
# # Possible dependency type include:
@@ -66,13 +66,13 @@
6666
#
6767
# # custom-dependencies
6868
# # --
69-
# # Denotes listing of dependencies, which can't be automatically discovered
70-
# # or identified but are to be stubbed and included in the analysis. This is used
71-
# # to add a unique dependency to your dependency graph
69+
# # Denotes listing of dependencies, which can't be automatically discovered
70+
# # or identified but are to be stubbed and included in the analysis. This is used
71+
# # to add a unique dependency to your dependency graph
7272
# # and the metadata you wish to associate with it.
7373
# #
7474
# # Learn more: https://github.com/fossas/fossa-cli/blob/master/docs/features/manual-dependencies.md#custom-dependencies
75-
# #
75+
# #
7676
# custom-dependencies:
7777
# - name: foo-wrapper # Name of the dependency. (Required)
7878
# version: 1.2.3 # Revision of the dependency. (Required)
@@ -85,8 +85,8 @@
8585
#
8686
# # remote-dependencies
8787
# # --
88-
# # Denotes listing of dependencies, whose source code is to be downloaded
89-
# # from provided URL, and analyzed for license scanning in FOSSA backend. The following archive types
88+
# # Denotes listing of dependencies, whose source code is to be downloaded
89+
# # from provided URL, and analyzed for license scanning in FOSSA backend. The following archive types
9090
# # are supported: *.zip, *.tar, *.tar.gz, *.tar.bz2, *.tar.xz.
9191
# #
9292
# # Learn more: https://github.com/fossas/fossa-cli/blob/master/docs/references/files/fossa-deps.md#remote-dependencies
@@ -103,13 +103,16 @@
103103
#
104104
# # vendored-dependencies
105105
# # --
106-
# # Denotes listing of files or directories, which are to be
106+
# # Denotes listing of files or directories, which are to be
107107
# # either, license scanned by fossa-cli, or and uploaded to FOSSA backend for
108108
# # license scanning.
109109
# #
110110
# # Learn more: https://github.com/fossas/fossa-cli/blob/master/docs/features/vendored-dependencies.md
111111
# #
112112
# vendored-dependencies:
113-
# - name: Django # Name of the dependency (Required)
114-
# path: vendor/Django-3.4.16.zip # Local path to a archive file, or a directory (Required)
115-
# version: 3.4.16 # Revision of the dependency. If not specified, the md5 hash of the file path will be used.
113+
# - name: Django # Name of the dependency (Required)
114+
# path: vendor/Django-3.4.16.zip # Local path to a archive file, or a directory (Required)
115+
# version: 3.4.16 # Revision of the dependency. If not specified, the md5 hash of the file path will be used.
116+
# metadata: # Metadata of the dependency (Optional)
117+
# description: Django # Description of the dependency, this will be shown in FOSSA UI, and generated reports. (Optional)
118+
# homepage: https://www.djangoproject.com # Homepage of the dependency, this will be shown in FOSSA UI, and generated reports. (Optional)

src/App/Fossa/LicenseScanner.hs

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import App.Fossa.VendoredDependency (
2323
compressFile,
2424
dedupVendoredDeps,
2525
forceVendoredToArchive,
26+
getMetadata,
2627
hashFile,
2728
skippedDepsDebugLog,
2829
vendoredDependencyScanModeToDependencyRebuild,
@@ -327,7 +328,7 @@ uploadVendoredDep ::
327328
VendoredDependency ->
328329
LicenseSourceUnit ->
329330
m (Maybe Archive)
330-
uploadVendoredDep baseDir VendoredDependency{..} licenseSourceUnit = do
331+
uploadVendoredDep baseDir dep@VendoredDependency{..} licenseSourceUnit = do
331332
depVersion <- case vendoredVersion of
332333
Nothing -> sendIO $ withSystemTempDir "fossa-temp" (calculateVendoredHash baseDir vendoredPath)
333334
Just version -> pure version
@@ -337,7 +338,7 @@ uploadVendoredDep baseDir VendoredDependency{..} licenseSourceUnit = do
337338
logSticky $ "Uploading license results for '" <> vendoredName <> "' to secure S3 bucket"
338339
uploadLicenseScanResult signedURL licenseSourceUnit
339340

340-
pure $ Just $ Archive vendoredName depVersion
341+
pure . Just . uncurry (Archive vendoredName depVersion) $ (getMetadata dep)
341342

342343
-- | licenseScanSourceUnit receives a list of vendored dependencies, a root path, and API settings.
343344
-- Using this information, it license scans each vendored dependency, uploads the license scan results and then queues a build for the dependency.

0 commit comments

Comments
 (0)