diff --git a/Changelog.md b/Changelog.md index b06ced84ec..e3898a00a2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ # FOSSA CLI Changelog +## 3.9.30 + +- Vendored Dependencies: add support for metadata (description, and homepage) for dependencies. ([#1455](https://github.com/fossas/fossa-cli/pull/1455)) + ## 3.9.29 - install scripts: Surface curl errors and display http status code correctly. ([#1456](https://github.com/fossas/fossa-cli/pull/1456)) - Update jar-callgraph version to 1.0.2 [#1454](https://github.com/fossas/fossa-cli/pull/1454) diff --git a/docs/features/vendored-dependencies.md b/docs/features/vendored-dependencies.md index 5b0c3cbfd3..a270ff4395 100644 --- a/docs/features/vendored-dependencies.md +++ b/docs/features/vendored-dependencies.md @@ -17,6 +17,13 @@ vendored-dependencies: - name: Django path: vendor/Django-3.4.16.zip # path can be either a file or a folder. version: "3.4.16" # revision will be set to the MD5 hash of the filepath if left unspecified. +# You can also provide a description and/or homepage. These values populate metadata fields in reports in the FOSSA web UI. +- name: Winston + path: vendor/winston.zip + version: "5.0.0-alpha" + metadata: + description: "winston archive" + homepage: "https://winston-project.com" ``` 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 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". +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). + We also support json-formatted dependencies: ```json @@ -63,7 +72,11 @@ We also support json-formatted dependencies: }, { "name": "winston", "path": "vendor/winston.tar.gz", - "version": "5.0.0-alpha" + "version": "5.0.0-alpha", + "metadata": { + "description": "winston archive", + "homepage": "https://winston-project.com/homepage" + } } ], "remote-dependencies": [ diff --git a/docs/references/files/fossa-deps.md b/docs/references/files/fossa-deps.md index dadd9db2c5..c72b417c29 100644 --- a/docs/references/files/fossa-deps.md +++ b/docs/references/files/fossa-deps.md @@ -1,6 +1,6 @@ # `fossa-deps` -`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. +`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. 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 `.{yaml, yaml, json}` file will be used instead. @@ -10,7 +10,7 @@ For more details on specifying a fossa-deps file, please refer to the [subcomman ### `referenced-dependencies:` -Denotes listing of dependencies, which are to be analyzed in conjunction with the analysis. +Denotes listing of dependencies, which are to be analyzed in conjunction with the analysis. - `type`: Type of dependency. (Required) - `name`: Name of the dependency. It should be the same name as listed in dependencies registry. (Required) @@ -25,11 +25,11 @@ referenced-dependencies: version: 2.1.7 ``` -For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through. +For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through. ### `custom-dependencies:` -Denotes listing of dependencies, which can't be automatically discovered or identified but are to be stubbed and included in the analysis. +Denotes listing of dependencies, which can't be automatically discovered or identified but are to be stubbed and included in the analysis. - `name`: Name of the dependency. (Required) - `version`: Revision of the dependency. (Required) @@ -37,8 +37,8 @@ Denotes listing of dependencies, which can't be automatically discovered or iden - `metadata.homepage`: Homepage of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface. - `metadata.description`: Description of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface. -Example: -```yaml +Example: +```yaml - name: foo-wrapper version: 1.2.3 license: MIT @@ -47,7 +47,7 @@ Example: description: Provides foo and a helpful interface around foo-like tasks. ``` -For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through. +For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through. ### `remote-dependencies:` @@ -62,11 +62,11 @@ Denotes listing of dependencies, whose source code is to be downloaded from prov > Combined length of url and version has upper bound. It depends on your organization identifier. You can find your organization identifier in FOSSA Webapp, by going to any project's "settings" page, and retrieving numeric value from project's locator. For example, project locator of `custom+123/some-project-id`, means -`123` is your organization identifier. +`123` is your organization identifier. > Combined length of `url`, `version`, and your `organizaion id` must be less than `241`. -For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through. +For more details, please refer to the [feature](../../features/manual-dependencies.md) walk through. ### `vendored-dependencies:` @@ -74,17 +74,22 @@ Denotes listing of files or directories, which are to be archived and uploaded t - `name`: Name of the dependency (Required) - `path`: Local path to a file, or a directory (Required) -- `version`: Revision of the dependency. If not specified, the md5 hash of the file path will be used. +- `version`: Revision of the dependency. If not specified, the md5 hash of the file path will be used. +- `metadata.homepage`: Homepage of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface. +- `metadata.description`: Description of the dependency. This metadata is used to enrich reporting provided in FOSSA's web interface. ```yaml vendored-dependencies: - name: Django path: vendor/Django-3.4.16.zip version: 3.4.16 + metadata: + homepage: https://djangoproject.com + description: Django ``` > 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. -For more details, please refer to the [feature](../../features/vendored-dependencies.md) walk through. +For more details, please refer to the [feature](../../features/vendored-dependencies.md) walk through. ## Errors in the `fossa-deps` file diff --git a/docs/references/files/fossa-deps.schema.json b/docs/references/files/fossa-deps.schema.json index 0767ec85bf..8a79d13773 100644 --- a/docs/references/files/fossa-deps.schema.json +++ b/docs/references/files/fossa-deps.schema.json @@ -212,6 +212,19 @@ "version": { "type": "string", "description": "Version of the dependency. This will be the version associated with this vendored dependency in FOSSA's dashboard" + }, + "metadata": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Description of the dependency (if any)" + }, + "homepage": { + "type": "string", + "description": "Homepage of the dependency. This should be web address." + } + } } }, "required": [ diff --git a/docs/walkthroughs/conan.md b/docs/walkthroughs/conan.md index 7b07419d9c..8f36dfea11 100644 --- a/docs/walkthroughs/conan.md +++ b/docs/walkthroughs/conan.md @@ -1,8 +1,8 @@ # Custom Integration with Conan Package Manager -Conan is a dependency and package manager for C and C++ languages. It is free and open-source, works on all -platforms (Windows, Linux, OSX, FreeBSD, Solaris, etc.), and can be used to develop for all targets, including -embedded, mobile (iOS, Android), and bare metal. It also integrates with all build systems like CMake, +Conan is a dependency and package manager for C and C++ languages. It is free and open-source, works on all +platforms (Windows, Linux, OSX, FreeBSD, Solaris, etc.), and can be used to develop for all targets, including +embedded, mobile (iOS, Android), and bare metal. It also integrates with all build systems like CMake, Visual Studio (MSBuild), Makefiles, etc., including proprietary ones. ## Prerequisite @@ -12,8 +12,8 @@ Visual Studio (MSBuild), Makefiles, etc., including proprietary ones. ## Integration -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 -[vendor-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md). +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 +[vendored-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md). To use this integration, 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: ### Limitations -This integration method uses [vendor-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md) +This integration method uses [vendored-dependencies](./../features/vendored-dependencies.md) and [custom-dependencies](../features/manual-dependencies.md) functionalities, and as such, it does not provide the following, - 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 This integration example uses the `conan graph info` command with `--format json` and `-c tools.build:download_source=True` option, which are only available in Conan v2 (`v2.0.0+`). -#### 3. I want to use a custom profile or provide additional options. +#### 3. I want to use a custom profile or provide additional options. You can provide any additional [`conan graph info`](https://docs.conan.io/2.0/reference/commands/graph/info.html) options (except `--format` or `-f`) -To do so, provide options to the Python script. For example, +To do so, provide options to the Python script. For example, ```bash >> python3 make_fossa_deps_conan.py -s compiler=gcc @@ -116,4 +116,3 @@ that declared license is always used. - [Conan Package Manager](https://docs.conan.io) - [Conan graph command](https://docs.conan.io/2.0/reference/commands/graph/info.html) - diff --git a/integration-test/Analysis/LicenseScannerSpec.hs b/integration-test/Analysis/LicenseScannerSpec.hs index f608c6e8d8..176d996c81 100644 --- a/integration-test/Analysis/LicenseScannerSpec.hs +++ b/integration-test/Analysis/LicenseScannerSpec.hs @@ -46,6 +46,7 @@ vendoredDep = "recursive-archive-test" "vendor/foo.tar.gz" (Just "0.0.1") + Nothing -- the contents of the archive look like this. The `FOO_LICENSE` files contain an MIT license. -- `bar_apache.rb` and `something.rb` contain an Apache-2.0 license. diff --git a/spectrometer.cabal b/spectrometer.cabal index facb46d631..f89634f853 100644 --- a/spectrometer.cabal +++ b/spectrometer.cabal @@ -236,6 +236,7 @@ library App.Fossa.Container.Sources.Podman App.Fossa.Container.Sources.Registry App.Fossa.Container.Test + App.Fossa.DependencyMetadata App.Fossa.DumpBinaries App.Fossa.EmbeddedBinary App.Fossa.FirstPartyScan diff --git a/src/App/Fossa/ArchiveUploader.hs b/src/App/Fossa/ArchiveUploader.hs index a7ba27ce73..85cf1469b3 100644 --- a/src/App/Fossa/ArchiveUploader.hs +++ b/src/App/Fossa/ArchiveUploader.hs @@ -9,6 +9,7 @@ import App.Fossa.VendoredDependency ( arcToLocator, compressFile, dedupVendoredDeps, + getMetadata, hashFile, ) import App.Types (ComponentUploadFileType (..), DependencyRebuild) @@ -52,7 +53,7 @@ compressAndUpload :: Path Abs Dir -> VendoredDependency -> m Archive -compressAndUpload arcDir tmpDir VendoredDependency{..} = context "compressing and uploading vendored deps" $ do +compressAndUpload arcDir tmpDir dep@VendoredDependency{..} = context "compressing and uploading vendored deps" $ do logSticky $ "Compressing '" <> vendoredName <> "' at '" <> vendoredPath <> "'" compressedFile <- sendIO $ compressFile tmpDir arcDir (toString vendoredPath) @@ -66,7 +67,7 @@ compressAndUpload arcDir tmpDir VendoredDependency{..} = context "compressing an res <- uploadArchive signedURL compressedFile logDebug . pretty $ (decodeUtf8 @Text res) - pure $ Archive vendoredName depVersion + pure . uncurry (Archive vendoredName depVersion) $ (getMetadata dep) -- archiveUploadSourceUnit receives a list of vendored dependencies, a root path, and API settings. -- Using this information, it uploads each vendored dependency and queues a build for the dependency. diff --git a/src/App/Fossa/DependencyMetadata.hs b/src/App/Fossa/DependencyMetadata.hs new file mode 100644 index 0000000000..ad9d824d87 --- /dev/null +++ b/src/App/Fossa/DependencyMetadata.hs @@ -0,0 +1,20 @@ +module App.Fossa.DependencyMetadata ( + DependencyMetadata (..), +) where + +import Data.Aeson (FromJSON (..), withObject, (.:?)) +import Data.Aeson.Extra (forbidMembers) +import Data.Text (Text) + +data DependencyMetadata = DependencyMetadata + { depDescription :: Maybe Text + , depHomepage :: Maybe Text + } + deriving (Eq, Ord, Show) + +instance FromJSON DependencyMetadata where + parseJSON = withObject "metadata" $ \obj -> + DependencyMetadata + <$> obj .:? "description" + <*> obj .:? "homepage" + <* forbidMembers "metadata" ["url"] obj diff --git a/src/App/Fossa/FirstPartyScan.hs b/src/App/Fossa/FirstPartyScan.hs index 9dd45cbf2b..4db0fe2b51 100644 --- a/src/App/Fossa/FirstPartyScan.hs +++ b/src/App/Fossa/FirstPartyScan.hs @@ -99,7 +99,7 @@ firstPartyScanMain :: firstPartyScanMain base cfg org = do runFirstPartyScans <- shouldRunFirstPartyScans cfg org manualDeps <- findAndReadFossaDepsFile base - let vdep = VendoredDependency "first-party" "." Nothing + let vdep = VendoredDependency "first-party" "." Nothing Nothing uploadKind = orgFileUpload org pathFilters <- mergePathFilters base manualDeps (licenseScanPathFilters $ vendoredDeps cfg) case runFirstPartyScans of diff --git a/src/App/Fossa/Init/fossa-deps.yml b/src/App/Fossa/Init/fossa-deps.yml index 14c080f56e..5290dbddd3 100644 --- a/src/App/Fossa/Init/fossa-deps.yml +++ b/src/App/Fossa/Init/fossa-deps.yml @@ -19,8 +19,8 @@ # # # referenced-dependencies # # -- -# # Denotes listing of dependencies, which are to be analyzed in -# # conjunction with the analysis. This is used for packages that +# # Denotes listing of dependencies, which are to be analyzed in +# # conjunction with the analysis. This is used for packages that # # originate from a known package manager. # # # # Possible dependency type include: @@ -66,13 +66,13 @@ # # # custom-dependencies # # -- -# # Denotes listing of dependencies, which can't be automatically discovered -# # or identified but are to be stubbed and included in the analysis. This is used -# # to add a unique dependency to your dependency graph +# # Denotes listing of dependencies, which can't be automatically discovered +# # or identified but are to be stubbed and included in the analysis. This is used +# # to add a unique dependency to your dependency graph # # and the metadata you wish to associate with it. # # # # Learn more: https://github.com/fossas/fossa-cli/blob/master/docs/features/manual-dependencies.md#custom-dependencies -# # +# # # custom-dependencies: # - name: foo-wrapper # Name of the dependency. (Required) # version: 1.2.3 # Revision of the dependency. (Required) @@ -85,8 +85,8 @@ # # # remote-dependencies # # -- -# # Denotes listing of dependencies, whose source code is to be downloaded -# # from provided URL, and analyzed for license scanning in FOSSA backend. The following archive types +# # Denotes listing of dependencies, whose source code is to be downloaded +# # from provided URL, and analyzed for license scanning in FOSSA backend. The following archive types # # are supported: *.zip, *.tar, *.tar.gz, *.tar.bz2, *.tar.xz. # # # # Learn more: https://github.com/fossas/fossa-cli/blob/master/docs/references/files/fossa-deps.md#remote-dependencies @@ -103,13 +103,16 @@ # # # vendored-dependencies # # -- -# # Denotes listing of files or directories, which are to be +# # Denotes listing of files or directories, which are to be # # either, license scanned by fossa-cli, or and uploaded to FOSSA backend for # # license scanning. # # # # Learn more: https://github.com/fossas/fossa-cli/blob/master/docs/features/vendored-dependencies.md # # # vendored-dependencies: -# - name: Django # Name of the dependency (Required) -# path: vendor/Django-3.4.16.zip # Local path to a archive file, or a directory (Required) -# version: 3.4.16 # Revision of the dependency. If not specified, the md5 hash of the file path will be used. +# - name: Django # Name of the dependency (Required) +# path: vendor/Django-3.4.16.zip # Local path to a archive file, or a directory (Required) +# version: 3.4.16 # Revision of the dependency. If not specified, the md5 hash of the file path will be used. +# metadata: # Metadata of the dependency (Optional) +# description: Django # Description of the dependency, this will be shown in FOSSA UI, and generated reports. (Optional) +# homepage: https://www.djangoproject.com # Homepage of the dependency, this will be shown in FOSSA UI, and generated reports. (Optional) diff --git a/src/App/Fossa/LicenseScanner.hs b/src/App/Fossa/LicenseScanner.hs index 85f447f7b9..f30c1605e8 100644 --- a/src/App/Fossa/LicenseScanner.hs +++ b/src/App/Fossa/LicenseScanner.hs @@ -23,6 +23,7 @@ import App.Fossa.VendoredDependency ( compressFile, dedupVendoredDeps, forceVendoredToArchive, + getMetadata, hashFile, skippedDepsDebugLog, vendoredDependencyScanModeToDependencyRebuild, @@ -327,7 +328,7 @@ uploadVendoredDep :: VendoredDependency -> LicenseSourceUnit -> m (Maybe Archive) -uploadVendoredDep baseDir VendoredDependency{..} licenseSourceUnit = do +uploadVendoredDep baseDir dep@VendoredDependency{..} licenseSourceUnit = do depVersion <- case vendoredVersion of Nothing -> sendIO $ withSystemTempDir "fossa-temp" (calculateVendoredHash baseDir vendoredPath) Just version -> pure version @@ -337,7 +338,7 @@ uploadVendoredDep baseDir VendoredDependency{..} licenseSourceUnit = do logSticky $ "Uploading license results for '" <> vendoredName <> "' to secure S3 bucket" uploadLicenseScanResult signedURL licenseSourceUnit - pure $ Just $ Archive vendoredName depVersion + pure . Just . uncurry (Archive vendoredName depVersion) $ (getMetadata dep) -- | licenseScanSourceUnit receives a list of vendored dependencies, a root path, and API settings. -- Using this information, it license scans each vendored dependency, uploads the license scan results and then queues a build for the dependency. diff --git a/src/App/Fossa/ManualDeps.hs b/src/App/Fossa/ManualDeps.hs index 6537800dd8..d76b31604b 100644 --- a/src/App/Fossa/ManualDeps.hs +++ b/src/App/Fossa/ManualDeps.hs @@ -24,6 +24,7 @@ import App.Fossa.Config.Analyze ( VendoredDependencyOptions (..), ) import App.Fossa.Config.Common (validateFile) +import App.Fossa.DependencyMetadata (DependencyMetadata (..)) import App.Fossa.LicenseScanner (licenseScanSourceUnit) import App.Fossa.VendoredDependency ( VendoredDependency (..), @@ -385,12 +386,6 @@ data RemoteDependency = RemoteDependency } deriving (Eq, Ord, Show) -data DependencyMetadata = DependencyMetadata - { depDescription :: Maybe Text - , depHomepage :: Maybe Text - } - deriving (Eq, Ord, Show) - instance FromJSON ManualDependencies where parseJSON (Object obj) = ManualDependencies @@ -576,14 +571,6 @@ instance ToDiagnostic RemoteDepLengthIsGtThanAllowed where renderDiagnostic (RemoteDepLengthIsGtThanAllowedHelp maxLen) = createErrataWithHeaderOnly $ "Ensure that the combined length is below: " <> toText maxLen --- Dependency "metadata" section for both Remote and Custom Dependencies -instance FromJSON DependencyMetadata where - parseJSON = withObject "metadata" $ \obj -> - DependencyMetadata - <$> obj .:? "description" - <*> obj .:? "homepage" - <* forbidMembers "metadata" ["url"] obj - -- Parse supported dependency types into their respective type or return Nothing. depTypeFromText :: Text -> Maybe DepType depTypeFromText text = case text of diff --git a/src/App/Fossa/SBOM/Analyze.hs b/src/App/Fossa/SBOM/Analyze.hs index 75b127ee94..db89b8f45e 100644 --- a/src/App/Fossa/SBOM/Analyze.hs +++ b/src/App/Fossa/SBOM/Analyze.hs @@ -52,7 +52,7 @@ analyzeInternal config = do let revision = sbomRevision config void $ uploadSBOM config - let archive = Archive (projectName revision) (projectRevision revision) + let archive = Archive (projectName revision) (projectRevision revision) Nothing Nothing _ <- queueSBOMBuild archive (sbomTeam config) (sbomRebuild config) -- The locator used in the URL has the organization ID on it, so we diff --git a/src/App/Fossa/VendoredDependency.hs b/src/App/Fossa/VendoredDependency.hs index f4e01b2a5a..030895e2e7 100644 --- a/src/App/Fossa/VendoredDependency.hs +++ b/src/App/Fossa/VendoredDependency.hs @@ -15,8 +15,10 @@ module App.Fossa.VendoredDependency ( SkippableDeps (..), NeedScanningDeps (..), SkippedDepsLogMsg (..), + getMetadata, ) where +import App.Fossa.DependencyMetadata (DependencyMetadata (..)) import App.Types (DependencyRebuild (..)) import Codec.Archive.Tar qualified as Tar import Codec.Compression.GZip qualified as GZip @@ -40,7 +42,11 @@ import Data.String.Conversion ( import Data.Text (Text, isInfixOf) import Data.Text qualified as Text import Data.UUID.V4 (nextRandom) -import Fossa.API.Types (Archive (..)) +import Fossa.API.Types ( + Archive (..), + ArchiveDescription (..), + ArchiveHomePage (..), + ) import Path (Abs, Dir, Path) import Prettyprinter (Pretty (pretty), vsep) import Srclib.Types (Locator (..)) @@ -50,6 +56,7 @@ data VendoredDependency = VendoredDependency { vendoredName :: Text , vendoredPath :: Text , vendoredVersion :: Maybe Text + , vendoredMetadata :: Maybe DependencyMetadata } deriving (Eq, Ord, Show) @@ -60,6 +67,7 @@ instance FromJSON VendoredDependency where <$> (obj `neText` "name") <*> (obj `neText` "path") <*> (unTextLike <$$> obj .:? "version") + <*> (obj .:? "metadata") <* forbidMembers "vendored dependencies" ["type", "license", "url", "description"] obj case vendoredVersion vendorDep of @@ -151,7 +159,7 @@ duplicateFailureBundle names = <> "Please ensure that each vendored dependency entry has a unique name." forceVendoredToArchive :: VendoredDependency -> Archive -forceVendoredToArchive dep = Archive (vendoredName dep) (fromMaybe "" $ vendoredVersion dep) +forceVendoredToArchive dep = uncurry (Archive (vendoredName dep) (fromMaybe "" $ vendoredVersion dep)) (getMetadata dep) arcToLocator :: Archive -> Locator arcToLocator arc = @@ -200,3 +208,8 @@ skippedDepsDebugLog needScanningDeps skippedDeps scanMode = case skippedDeps of SkippableDeps [] -> AllDepsNeedScanningMsg _ -> SomeDepsNeedScanningMsg skippedDeps + +getMetadata :: VendoredDependency -> (Maybe ArchiveDescription, Maybe ArchiveHomePage) +getMetadata dep = case vendoredMetadata dep of + Nothing -> (Nothing, Nothing) + Just DependencyMetadata{..} -> (ArchiveDescription <$> depDescription, ArchiveHomePage <$> depHomepage) diff --git a/src/Fossa/API/Types.hs b/src/Fossa/API/Types.hs index 4ad3b71ef5..1b0b14f21a 100644 --- a/src/Fossa/API/Types.hs +++ b/src/Fossa/API/Types.hs @@ -7,6 +7,8 @@ module Fossa.API.Types ( ApiOpts (..), Archive (..), ArchiveComponents (..), + ArchiveDescription (..), + ArchiveHomePage (..), Build (..), BuildStatus (..), BuildTask (..), @@ -161,9 +163,17 @@ instance ToJSON ArchiveComponents where DependencyRebuildInvalidateCache -> True ] +newtype ArchiveDescription = ArchiveDescription Text + deriving (Eq, Ord, ToJSON, ToText, Show) + +newtype ArchiveHomePage = ArchiveHomePage Text + deriving (Eq, Ord, ToJSON, ToText, Show) + data Archive = Archive { archiveName :: Text , archiveVersion :: Text + , archiveDescription :: Maybe ArchiveDescription + , archiveHomePage :: Maybe ArchiveHomePage } deriving (Eq, Ord, Show) @@ -175,6 +185,8 @@ instance ToJSON Archive where object [ "packageSpec" .= archiveName , "revision" .= archiveVersion + , "description" .= archiveDescription + , "projectURL" .= archiveHomePage ] data BuildStatus diff --git a/src/Strategy/Conan/Enrich.hs b/src/Strategy/Conan/Enrich.hs index d4e6207e21..5fef3477af 100644 --- a/src/Strategy/Conan/Enrich.hs +++ b/src/Strategy/Conan/Enrich.hs @@ -132,7 +132,7 @@ conanDepToVendorDep :: Dependency -> Either Dependency (Dependency, VendoredDepe conanDepToVendorDep d = case listToMaybe $ dependencyLocations d of Nothing -> Left d - Just pathOfDep -> Right (d, VendoredDependency depName pathOfDep depVersion) + Just pathOfDep -> Right (d, VendoredDependency depName pathOfDep depVersion Nothing) where depName :: Text depName = dependencyName d diff --git a/test/App/Fossa/ManualDepsSpec.hs b/test/App/Fossa/ManualDepsSpec.hs index 320505f94c..f950b6e64e 100644 --- a/test/App/Fossa/ManualDepsSpec.hs +++ b/test/App/Fossa/ManualDepsSpec.hs @@ -53,8 +53,9 @@ theWorks = ManualDependencies references customs vendors remotes locators , RemoteDependency "url-dep-two" "1.2.4" "www.url2.tar.gz" Nothing ] vendors = - [ VendoredDependency "vendored" "path" Nothing - , VendoredDependency "versioned" "path/to/dep" (Just "2.1.0") + [ VendoredDependency "vendored" "path" Nothing Nothing + , VendoredDependency "versioned" "path/to/dep" (Just "2.1.0") Nothing + , VendoredDependency "metadata" "path" (Just "1.1.0") (Just (DependencyMetadata (Just "description for vendored") (Just "we don't validate homepages - vendored"))) ] locators = [ Locator "fetcher-1" "one" Nothing @@ -436,5 +437,5 @@ locatorDepWithEmptyDep :: Text locatorDepWithEmptyDep = [r| locator-dependencies: -- +- |] diff --git a/test/App/Fossa/SBOMAnalyzeSpec.hs b/test/App/Fossa/SBOMAnalyzeSpec.hs index 88a14f8072..c0af116d35 100644 --- a/test/App/Fossa/SBOMAnalyzeSpec.hs +++ b/test/App/Fossa/SBOMAnalyzeSpec.hs @@ -21,7 +21,7 @@ spec = do describe "SBOM Analyze" $ do currDir <- runIO getCurrentDir it' "should upload a file" $ do - let archive = Archive "somesbom" "1.2.3" + let archive = Archive "somesbom" "1.2.3" Nothing Nothing let revision = ProjectRevision "somesbom" "1.2.3" Nothing let config = SBOMAnalyzeConfig (BaseDir currDir) Fixtures.apiOpts (SBOMFile "test/App/Fossa/SBOM/testdata/sampleCycloneDX.json") SevInfo DependencyRebuildReuseCache Nothing revision diff --git a/test/App/Fossa/testdata/the-works.json b/test/App/Fossa/testdata/the-works.json index a43ebdbcdf..68e198550b 100755 --- a/test/App/Fossa/testdata/the-works.json +++ b/test/App/Fossa/testdata/the-works.json @@ -35,6 +35,15 @@ "name": "versioned", "path": "path/to/dep", "version": "2.1.0" + }, + { + "name": "metadata", + "path": "path", + "version": "1.1.0", + "metadata": { + "description": "description for vendored", + "homepage": "we don't validate homepages - vendored" + } } ], "remote-dependencies": [ @@ -57,4 +66,4 @@ "fetcher-1+one", "fetcher-2+two$1.0.0" ] -} \ No newline at end of file +} diff --git a/test/App/Fossa/testdata/the-works.yml b/test/App/Fossa/testdata/the-works.yml index 61a3c70f61..0edd105174 100644 --- a/test/App/Fossa/testdata/the-works.yml +++ b/test/App/Fossa/testdata/the-works.yml @@ -11,6 +11,12 @@ vendored-dependencies: - name: versioned path: path/to/dep version: 2.1.0 +- name: metadata + path: path + version: 1.1.0 + metadata: + description: description for vendored + homepage: we don't validate homepages - vendored custom-dependencies: - name: hello @@ -33,7 +39,7 @@ remote-dependencies: - name: url-dep-two version: 1.2.4 url: www.url2.tar.gz - + locator-dependencies: - "fetcher-1+one" -- "fetcher-2+two$1.0.0" \ No newline at end of file +- "fetcher-2+two$1.0.0" diff --git a/test/Conan/EnrichSpec.hs b/test/Conan/EnrichSpec.hs index 6ab1f066ad..966d8e004f 100644 --- a/test/Conan/EnrichSpec.hs +++ b/test/Conan/EnrichSpec.hs @@ -25,7 +25,12 @@ import DepTypes ( Dependency (..), VerConstraint (CEq), ) -import Fossa.API.Types (Archive (Archive), ArchiveComponents (..)) +import Fossa.API.Types ( + Archive (Archive), + ArchiveComponents (..), + ArchiveDescription (..), + ArchiveHomePage (..), + ) import Graphing (directs, edges) import Path (Dir, Path, Rel, mkRelDir, ()) import Path.IO (getCurrentDir) @@ -150,9 +155,9 @@ mkArchiveDep name ver loc = Dependency ArchiveType name (Just $ CEq ver) [loc] -- Archives archiveFoo :: Archive -archiveFoo = mkArchive "foo" "0.0.1" +archiveFoo = mkArchive "foo" "0.0.1" Nothing Nothing -mkArchive :: Text -> Text -> Archive +mkArchive :: Text -> Text -> Maybe ArchiveDescription -> Maybe ArchiveHomePage -> Archive mkArchive = Archive -- API Expectations @@ -178,7 +183,7 @@ conanToVendoredDepSpec = describe "conanToVendoredDep" $ do it "should transforms conan to vendor dep, when dep has location" $ do let res = conanDepToVendorDep conanDepFoo - res `shouldBe` Right (conanDepFoo, VendoredDependency "foo" "vendored/foo" $ Just "0.0.1") + res `shouldBe` Right (conanDepFoo, VendoredDependency "foo" "vendored/foo" (Just "0.0.1") Nothing) it "should not transforms conan to vendor dep, when dep does not have location" $ do let dep = conanDepFoo{dependencyLocations = []} diff --git a/test/Test/Fixtures.hs b/test/Test/Fixtures.hs index e58c33fafa..3ab06d5e79 100644 --- a/test/Test/Fixtures.hs +++ b/test/Test/Fixtures.hs @@ -442,6 +442,7 @@ firstVendoredDep = "first-archive-test" "vendored/foo" (Just "0.0.1") + Nothing secondVendoredDep :: VendoredDependency secondVendoredDep = @@ -449,6 +450,7 @@ secondVendoredDep = "second-archive-test" "vendored/bar" (Just "0.0.1") + Nothing vendoredDeps :: NonEmpty VendoredDependency vendoredDeps = NE.fromList [firstVendoredDep, secondVendoredDep] @@ -475,12 +477,16 @@ firstArchive = Archive "first-archive-test" "0.0.1" + Nothing + Nothing secondArchive :: Archive secondArchive = Archive "second-archive-test" "0.0.1" + Nothing + Nothing archives :: [Archive] archives = [firstArchive, secondArchive]