Skip to content

Commit 9756ac2

Browse files
authored
Support true forced rebuilds for vendored dependencies, refactor types (#1423)
1 parent 759be18 commit 9756ac2

27 files changed

+274
-204
lines changed

Changelog.md

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

3+
## v3.9.18
4+
- Resolves an issue where `vendored-dependencies` were rescanned locally, but not in the FOSSA service,
5+
when `forceRescans` was set to `true` ([#1423](https://github.com/fossas/fossa-cli/pull/1423)).
6+
37
## v3.9.17
4-
- Poetry: Adds partial support for dependency groups. ([#1420](https://github.com/fossas/fossa-cli/pull/1420)).
8+
- Poetry: Adds partial support for dependency groups. ([#1420](https://github.com/fossas/fossa-cli/pull/1420)).
59

610
## v3.9.16
711
- Treat `targets` field in the issue summary loaded from Core as optional during `fossa test` and `fossa report` ([#1422](https://github.com/fossas/fossa-cli/pull/1422)).

integration-test/Analysis/LicenseScannerSpec.hs

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Analysis.FixtureUtils (
99
)
1010
import App.Fossa.LicenseScanner (scanVendoredDep)
1111
import App.Fossa.VendoredDependency (VendoredDependency (VendoredDependency))
12-
import App.Types (FullFileUploads (..))
12+
import App.Types (FileUpload (..))
1313
import Control.Carrier.Diagnostics (runDiagnostics)
1414
import Control.Carrier.Stack (runStack)
1515
import Control.Carrier.StickyLogger (ignoreStickyLogger)
@@ -93,7 +93,7 @@ spec = do
9393
it "should find licenses in nested archives" $ do
9494
extractedDir <- getArtifact recursiveArchive
9595
let scanDir = extractedDir </> [reldir|cli-license-scan-integration-test-fixtures-main/recursive-archive|]
96-
units <- runStack . runDiagnostics . ignoreStickyLogger . runExecIO . runReadFSIO . fmap licenseSourceUnitLicenseUnits $ scanVendoredDep scanDir Nothing (FullFileUploads False) vendoredDep
96+
units <- runStack . runDiagnostics . ignoreStickyLogger . runExecIO . runReadFSIO . fmap licenseSourceUnitLicenseUnits $ scanVendoredDep scanDir Nothing FileUploadMatchData vendoredDep
9797
PIO.removeDirRecur extractedDir
9898
case units of
9999
Failure ws eg -> fail (show (renderFailure ws eg "An issue occurred"))
@@ -113,10 +113,10 @@ spec = do
113113
apacheUnit :: LicenseUnit
114114
apacheUnit = fromMaybe emptyLicenseUnit (head' $ NE.filter (\u -> licenseUnitName u == "apache-2.0") us)
115115

116-
it "should get full file contents from Themis if fullFileUploads is true" $ do
116+
it "should get full file contents from Themis if full file uploads enabled" $ do
117117
extractedDir <- getArtifact recursiveArchive
118118
let scanDir = extractedDir </> [reldir|cli-license-scan-integration-test-fixtures-main/recursive-archive|]
119-
units <- runStack . runDiagnostics . ignoreStickyLogger . runExecIO . runReadFSIO . fmap licenseSourceUnitLicenseUnits $ scanVendoredDep scanDir Nothing (FullFileUploads True) vendoredDep
119+
units <- runStack . runDiagnostics . ignoreStickyLogger . runExecIO . runReadFSIO . fmap licenseSourceUnitLicenseUnits $ scanVendoredDep scanDir Nothing FileUploadFullContent vendoredDep
120120
PIO.removeDirRecur extractedDir
121121
case units of
122122
Failure ws eg -> fail (show (renderFailure ws eg "An issue occurred"))
@@ -140,7 +140,7 @@ spec = do
140140
extractedDir <- getArtifact recursiveArchive
141141
let scanDir = extractedDir </> [reldir|cli-license-scan-integration-test-fixtures-main/recursive-archive|]
142142
let licenseScanPathFilters = LicenseScanPathFilters{licenseScanPathFiltersOnly = [GlobFilter "**.rb"], licenseScanPathFiltersExclude = [], licenseScanPathFilterFileExclude = []}
143-
units <- runStack . runDiagnostics . ignoreStickyLogger . runExecIO . runReadFSIO . fmap licenseSourceUnitLicenseUnits $ scanVendoredDep scanDir (Just licenseScanPathFilters) (FullFileUploads False) vendoredDep
143+
units <- runStack . runDiagnostics . ignoreStickyLogger . runExecIO . runReadFSIO . fmap licenseSourceUnitLicenseUnits $ scanVendoredDep scanDir (Just licenseScanPathFilters) FileUploadMatchData vendoredDep
144144
PIO.removeDirRecur extractedDir
145145
case units of
146146
Failure ws eg -> fail (show (renderFailure ws eg "An issue occurred"))

src/App/Fossa/Analyze/Upload.hs

+7-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import App.Fossa.Reachability.Types (SourceUnitReachability)
1414
import App.Fossa.Reachability.Upload (upload)
1515
import App.Types (
1616
BaseDir (BaseDir),
17-
FullFileUploads (FullFileUploads),
17+
FileUpload,
1818
ProjectMetadata,
1919
ProjectRevision (..),
2020
)
@@ -61,7 +61,7 @@ import Effect.Logger (
6161
logStdout,
6262
viaShow,
6363
)
64-
import Fossa.API.Types (Organization (orgRequiresFullFileUploads, orgSupportsReachability, organizationId), Project (projectIsMonorepo), UploadResponse (..))
64+
import Fossa.API.Types (Organization (orgSupportsReachability, organizationId), Project (projectIsMonorepo), UploadResponse (..), orgFileUpload)
6565
import Path (Abs, Dir, Path)
6666
import Srclib.Types (
6767
FullSourceUnit,
@@ -126,13 +126,11 @@ uploadSuccessfulAnalysis (BaseDir basedir) metadata jsonOutput revision scanUnit
126126
uploadResult <- case scanUnits of
127127
SourceUnitOnly units -> uploadAnalysis revision metadata units
128128
LicenseSourceUnitOnly licenseSourceUnit -> do
129-
let fullFileUploads = FullFileUploads $ orgRequiresFullFileUploads org
130129
let mergedUnits = mergeSourceAndLicenseUnits [] licenseSourceUnit
131-
runStickyLogger SevInfo $ uploadAnalysisWithFirstPartyLicensesToS3AndCore revision metadata mergedUnits fullFileUploads
130+
runStickyLogger SevInfo . uploadAnalysisWithFirstPartyLicensesToS3AndCore revision metadata mergedUnits $ orgFileUpload org
132131
SourceAndLicenseUnits sourceUnits licenseSourceUnit -> do
133-
let fullFileUploads = FullFileUploads $ orgRequiresFullFileUploads org
134132
let mergedUnits = mergeSourceAndLicenseUnits sourceUnits licenseSourceUnit
135-
runStickyLogger SevInfo $ uploadAnalysisWithFirstPartyLicensesToS3AndCore revision metadata mergedUnits fullFileUploads
133+
runStickyLogger SevInfo . uploadAnalysisWithFirstPartyLicensesToS3AndCore revision metadata mergedUnits $ orgFileUpload org
136134

137135
emitBuildWarnings uploadResult
138136

@@ -167,11 +165,11 @@ uploadAnalysisWithFirstPartyLicensesToS3AndCore ::
167165
ProjectRevision ->
168166
ProjectMetadata ->
169167
NE.NonEmpty FullSourceUnit ->
170-
FullFileUploads ->
168+
FileUpload ->
171169
m UploadResponse
172-
uploadAnalysisWithFirstPartyLicensesToS3AndCore revision metadata mergedUnits fullFileUploads = do
170+
uploadAnalysisWithFirstPartyLicensesToS3AndCore revision metadata mergedUnits uploadKind = do
173171
_ <- uploadAnalysisWithFirstPartyLicensesToS3 revision mergedUnits
174-
uploadAnalysisWithFirstPartyLicenses revision metadata fullFileUploads
172+
uploadAnalysisWithFirstPartyLicenses revision metadata uploadKind
175173

176174
uploadAnalysisWithFirstPartyLicensesToS3 ::
177175
( Has Diagnostics sig m

src/App/Fossa/ArchiveUploader.hs

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import App.Fossa.VendoredDependency (
1111
dedupVendoredDeps,
1212
hashFile,
1313
)
14+
import App.Types (DependencyRebuild)
1415
import Control.Carrier.Diagnostics qualified as Diag
1516
import Control.Carrier.StickyLogger (StickyLogger, logSticky)
1617
import Control.Effect.Diagnostics (context)
@@ -69,17 +70,20 @@ compressAndUpload arcDir tmpDir VendoredDependency{..} = context "compressing an
6970

7071
-- archiveUploadSourceUnit receives a list of vendored dependencies, a root path, and API settings.
7172
-- Using this information, it uploads each vendored dependency and queues a build for the dependency.
73+
--
74+
-- Note: this function intentionally does not accept a @FileUpload@ type, because it /always/ uploads full files.
7275
archiveUploadSourceUnit ::
7376
( Has Diag.Diagnostics sig m
7477
, Has (Lift IO) sig m
7578
, Has StickyLogger sig m
7679
, Has Logger sig m
7780
, Has FossaApiClient sig m
7881
) =>
82+
DependencyRebuild ->
7983
Path Abs Dir ->
8084
NonEmpty VendoredDependency ->
8185
m (NonEmpty Locator)
82-
archiveUploadSourceUnit baseDir vendoredDeps = do
86+
archiveUploadSourceUnit rebuild baseDir vendoredDeps = do
8387
uniqDeps <- dedupVendoredDeps vendoredDeps
8488

8589
-- At this point, we have a good list of deps, so go for it.
@@ -89,8 +93,7 @@ archiveUploadSourceUnit baseDir vendoredDeps = do
8993
-- orgID is appended when creating the build on the backend. We don't care
9094
-- about the response here because if the build has already been queued, we
9195
-- get a 401 response.
92-
res <- traverse queueArchiveBuild (NonEmpty.toList archives)
93-
logDebug $ pretty $ show res
96+
_ <- queueArchiveBuild (NonEmpty.toList archives) rebuild
9497

9598
-- The organizationID is needed to prefix each locator name. The FOSSA API
9699
-- automatically prefixes the locator when queuing the build but not when

src/App/Fossa/FirstPartyScan.hs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module App.Fossa.FirstPartyScan (
88
import App.Fossa.Config.Analyze (AnalyzeConfig (..), VendoredDependencyOptions (licenseScanPathFilters))
99
import App.Fossa.LicenseScanner (scanVendoredDep)
1010
import App.Fossa.ManualDeps (ManualDependencies (vendoredDependencies), VendoredDependency (..), findAndReadFossaDepsFile)
11-
import App.Types (FirstPartyScansFlag (..), FullFileUploads (FullFileUploads))
11+
import App.Types (FirstPartyScansFlag (..))
1212
import Control.Carrier.Diagnostics qualified as Diag
1313
import Control.Carrier.FossaApiClient (runFossaApiClient)
1414
import Control.Effect.Debug (Debug)
@@ -25,7 +25,7 @@ import Diag.Result
2525
import Effect.Exec (Exec)
2626
import Effect.Logger (Logger, logDebug)
2727
import Effect.ReadFS (Has, ReadFS, resolvePath')
28-
import Fossa.API.Types (ApiOpts (..), Organization (..), blankOrganization)
28+
import Fossa.API.Types (ApiOpts (..), Organization (..), blankOrganization, orgFileUpload)
2929
import Path (Abs, Dir, Path, Rel, SomeBase (..))
3030
import Path.Extra
3131
import Path.IO
@@ -100,12 +100,12 @@ firstPartyScanMain base cfg org = do
100100
runFirstPartyScans <- shouldRunFirstPartyScans cfg org
101101
manualDeps <- findAndReadFossaDepsFile base
102102
let vdep = VendoredDependency "first-party" "." Nothing
103-
fullFileUploads = FullFileUploads $ orgRequiresFullFileUploads org
103+
uploadKind = orgFileUpload org
104104
pathFilters <- mergePathFilters base manualDeps (licenseScanPathFilters $ vendoredDeps cfg)
105105
case runFirstPartyScans of
106106
(True) -> do
107107
_ <- logDebug "Running a first-party license scan on the code in this repository. Licenses found in this repository will show up as 'Directly in code' in the FOSSA UI"
108-
Just <$> scanVendoredDep base pathFilters fullFileUploads vdep
108+
Just <$> scanVendoredDep base pathFilters uploadKind vdep
109109
(False) -> pure Nothing
110110

111111
-- mergePathFilters takes the existing filters from the config and merges them with filters constructed by looking at the vendored dependencies

src/App/Fossa/Lernie/Analyze.hs

+16-12
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import App.Fossa.Lernie.Types (
2727
LernieWarning (..),
2828
OrgWideCustomLicenseConfigPolicy (..),
2929
)
30-
import App.Types (FullFileUploads (..))
30+
import App.Types (FileUpload (..))
3131
import Control.Carrier.Debug (Debug)
3232
import Control.Carrier.Diagnostics (Diagnostics, fatal, warn)
3333
import Control.Carrier.FossaApiClient (runFossaApiClient)
@@ -51,7 +51,7 @@ import Data.String.Conversion (ToText (toText), decodeUtf8)
5151
import Data.Text (Text)
5252
import Effect.Exec (AllowErr (Never), Command (..), Exec, execCurrentDirStdinThrow)
5353
import Effect.ReadFS (ReadFS)
54-
import Fossa.API.Types (ApiOpts, Organization (..))
54+
import Fossa.API.Types (ApiOpts, Organization (..), orgFileUpload)
5555
import Path (Abs, Dir, File, Path)
5656
import Srclib.Types (LicenseScanType (..), LicenseSourceUnit (..), LicenseUnit (..), LicenseUnitData (..), LicenseUnitInfo (..), LicenseUnitMatchData (..))
5757

@@ -75,8 +75,8 @@ analyzeWithLernie ::
7575
m (Maybe LernieResults)
7676
analyzeWithLernie rootDir maybeApiOpts grepOptions = do
7777
case (maybeApiOpts, orgWideCustomLicenseScanConfigPolicy grepOptions) of
78-
(_, Ignore) -> analyzeWithLernieMain rootDir grepOptions (FullFileUploads False)
79-
(Nothing, Use) -> analyzeWithLernieMain rootDir grepOptions (FullFileUploads False)
78+
(_, Ignore) -> analyzeWithLernieMain rootDir grepOptions FileUploadMatchData
79+
(Nothing, Use) -> analyzeWithLernieMain rootDir grepOptions FileUploadMatchData
8080
(Just apiOpts, Use) -> runFossaApiClient apiOpts $ analyzeWithLernieWithOrgInfo rootDir grepOptions
8181

8282
analyzeWithLernieWithOrgInfo ::
@@ -92,8 +92,10 @@ analyzeWithLernieWithOrgInfo ::
9292
m (Maybe LernieResults)
9393
analyzeWithLernieWithOrgInfo rootDir grepOptions = do
9494
orgWideCustomLicenses <- orgCustomLicenseScanConfigs <$> getOrganization
95-
fullFiles <- orgRequiresFullFileUploads <$> getOrganization
96-
analyzeWithLernieMain rootDir grepOptions{customLicenseSearch = nub $ orgWideCustomLicenses <> customLicenseSearch grepOptions} $ FullFileUploads fullFiles
95+
uploadKind <- orgFileUpload <$> getOrganization
96+
97+
let options = grepOptions{customLicenseSearch = nub $ orgWideCustomLicenses <> customLicenseSearch grepOptions}
98+
analyzeWithLernieMain rootDir options uploadKind
9799

98100
analyzeWithLernieMain ::
99101
( Has Diagnostics sig m
@@ -104,10 +106,10 @@ analyzeWithLernieMain ::
104106
) =>
105107
Path Abs Dir ->
106108
GrepOptions ->
107-
FullFileUploads ->
109+
FileUpload ->
108110
m (Maybe LernieResults)
109-
analyzeWithLernieMain rootDir grepOptions fullFiles = do
110-
let maybeLernieConfig = grepOptionsToLernieConfig rootDir grepOptions fullFiles
111+
analyzeWithLernieMain rootDir grepOptions uploadKind = do
112+
let maybeLernieConfig = grepOptionsToLernieConfig rootDir grepOptions uploadKind
111113
case maybeLernieConfig of
112114
Just lernieConfig -> do
113115
unless (null $ customLicenseSearch grepOptions) $ trackUsage CustomLicenseSearchUsage
@@ -117,11 +119,13 @@ analyzeWithLernieMain rootDir grepOptions fullFiles = do
117119
pure $ Just lernieResults
118120
Nothing -> pure Nothing
119121

120-
grepOptionsToLernieConfig :: Path Abs Dir -> GrepOptions -> FullFileUploads -> Maybe LernieConfig
121-
grepOptionsToLernieConfig rootDir grepOptions fullFiles =
122+
grepOptionsToLernieConfig :: Path Abs Dir -> GrepOptions -> FileUpload -> Maybe LernieConfig
123+
grepOptionsToLernieConfig rootDir grepOptions uploadKind =
122124
case (customLicenseSearches <> keywordSearches) of
123125
[] -> Nothing
124-
res -> Just $ LernieConfig rootDir res $ unFullFileUploads fullFiles
126+
res -> Just . LernieConfig rootDir res $ case uploadKind of
127+
FileUploadMatchData -> False
128+
FileUploadFullContent -> True
125129
where
126130
customLicenseSearches = map (grepEntryToLernieRegex CustomLicense) (customLicenseSearch grepOptions)
127131
keywordSearches = map (grepEntryToLernieRegex KeywordSearch) (keywordSearch grepOptions)

src/App/Fossa/LicenseScan.hs

+3-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import App.Fossa.VendoredDependency (
2121
VendoredDependency,
2222
dedupVendoredDeps,
2323
)
24-
import App.Types (BaseDir (BaseDir), FullFileUploads (FullFileUploads))
24+
import App.Types (BaseDir (BaseDir), FileUpload (FileUploadMatchData))
2525
import Control.Carrier.StickyLogger (
2626
Has,
2727
StickyLogger,
@@ -104,8 +104,7 @@ outputVendoredDeps (BaseDir dir) = runStickyLogger SevInfo $ do
104104
resultMap <- UploadUnits <$> runLicenseScan dir licenseScanPathFilters vendoredDeps
105105
logStdout . decodeUtf8 $ Aeson.encode resultMap
106106

107-
-- runLicenseScan does not require an API key, so we can't get the FullFileUploads param from the organization,
108-
-- so we just default FullFileUploads to False.
107+
-- runLicenseScan does not require an API key, so we can't query the organization; default to uploading match data only.
109108
runLicenseScan ::
110109
( Has Diagnostics sig m
111110
, Has ReadFS sig m
@@ -117,4 +116,4 @@ runLicenseScan ::
117116
Maybe LicenseScanPathFilters ->
118117
NonEmpty VendoredDependency ->
119118
m (NonEmpty LicenseSourceUnit)
120-
runLicenseScan basedir licenseScanPathFilters vdeps = dedupVendoredDeps vdeps >>= traverse (scanVendoredDep basedir licenseScanPathFilters $ FullFileUploads False)
119+
runLicenseScan basedir licenseScanPathFilters vdeps = dedupVendoredDeps vdeps >>= traverse (scanVendoredDep basedir licenseScanPathFilters FileUploadMatchData)

0 commit comments

Comments
 (0)