Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert MSB errors to warnings #1469

Merged
merged 6 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# FOSSA CLI Changelog


## 3.9.33

- MSB: Failure to resolve a linked project no longer causes the scan to fail ([[#1469](https://github.com/fossas/fossa-cli/pull/1469)]).

## 3.9.32

- Platform Support: Add a binary for ARM64 Linux environments. ([#1465](https://github.com/fossas/fossa-cli/pull/1465))
Expand Down
34 changes: 17 additions & 17 deletions src/App/Fossa/VSI/IAT/Resolve.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import App.Fossa.VSI.IAT.Types (
import App.Fossa.VSI.IAT.Types qualified as IAT
import App.Fossa.VSI.Types qualified as VSI
import Control.Algebra (Has)
import Control.Effect.Diagnostics (Diagnostics, context, fatalText, recover)
import Control.Effect.Diagnostics (Diagnostics, context, recover, warn)
import Control.Effect.FossaApiClient (FossaApiClient, resolveProjectDependencies, resolveUserDefinedBinary)
import Data.Maybe (fromMaybe, isNothing)
import Control.Monad (unless)
import Data.Either (partitionEithers)
import Data.String.Conversion (toText)
import Data.Text (Text, intercalate)
import Graphing (Graphing, direct, edges, empty)
import Graphing (Graphing, direct, edges)
import Srclib.Types (
SourceUserDefDep (..),
)
Expand Down Expand Up @@ -48,30 +49,29 @@ resolveGraph locators skipResolving = context ("Resolving graph for " <> toText
-- This typically means that the user doesn't have access to the project, or the project doesn't exist.
-- Collect failed locators and report them to the user, along with mitigation suggestions.
subgraphs <- traverseZipM (resolveSubgraph skipResolving) locators
if any resolutionFailed subgraphs
then fatalText $ resolveGraphFailureBundle subgraphs
else pure . mconcat $ fmap unwrap subgraphs
let (warned, success) = partitionMap partitionSubgraph subgraphs
renderWarnings warned
pure $ mconcat success
where
resolutionFailed (_, b) = isNothing b
unwrap (_, b) = fromMaybe empty b
renderWarnings subgraphs = unless (null subgraphs) . warn $ resolveGraphFailureBundle subgraphs
partitionSubgraph (a, Nothing) = Left a
partitionSubgraph (_, Just b) = Right b

resolveGraphFailureBundle :: [(VSI.Locator, Maybe (Graphing VSI.Locator))] -> Text
resolveGraphFailureBundle :: [VSI.Locator] -> Text
resolveGraphFailureBundle subgraphs =
"Failed to resolve dependencies for the following FOSSA projects:\n\t"
<> intercalate "\n\t" (renderFailed subgraphs)
<> intercalate "\n\t" (fmap VSI.renderLocator subgraphs)
<> "\n\n"
<> "You may not have access to the projects, or they may not exist (see the warnings below for details).\n"
<> "If desired you can use --experimental-skip-vsi-graph to skip resolving the dependencies of these projects."
where
renderFailed [] = []
renderFailed ((a, b) : xs) = case b of
Just _ -> renderFailed xs
Nothing -> VSI.renderLocator a : renderFailed xs
<> "You may not have access to the projects, or they may not exist.\n"

-- | Given a traverseable list and a monadic function that resolves them to b, traverse and zip the list into a pair of (a, b)
traverseZipM :: (Traversable t, Applicative m) => (a -> m b) -> t a -> m (t (a, b))
traverseZipM f = traverse (\a -> (a,) <$> f a)

-- | Split the list into two mapped lists based on the predicate.
partitionMap :: (a -> Either b c) -> [a] -> ([b], [c])
partitionMap split items = partitionEithers $ map split items

-- Pass through the list of skipped locators all the way here:
-- we want to still record the direct dependency, we just don't want to resolve it.
resolveSubgraph :: (Has FossaApiClient sig m, Has Diagnostics sig m) => VSI.SkipResolution -> VSI.Locator -> m (Maybe (Graphing VSI.Locator))
Expand Down
11 changes: 8 additions & 3 deletions test/App/Fossa/VSI/IAT/ResolveSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import DepTypes (DepType (CustomType))
import Graphing qualified
import Srclib.Converter (depTypeToFetcher)
import Srclib.Types (SourceUserDefDep (..))
import Test.Effect (expectFatal', it', shouldBe')
import Test.Effect (it', shouldBe')
import Test.Hspec (Spec, describe)
import Test.MockApi (fails, returnsOnce)

Expand Down Expand Up @@ -47,17 +47,22 @@ spec = do
maybeDeps <- resolveRevision package
maybeDeps `shouldBe'` Just [dep1, dep2]
describe "resolveGraph" $ do
it' "dies if resolving any subgraph fails to resolve" $ do
it' "resolves available subgraphs" $ do
let package1 = testTopLevelLocator 1
package2 = testTopLevelLocator 2
dep1 = testLocator 11
dep2 = testLocator 12
skips = SkipResolution (Set.empty)
expectedGraph =
Graphing.directs [package1]
<> Graphing.edges [(package1, dep1), (package1, dep2)]
-- Package1 is fine
ResolveProjectDependencies package1 `returnsOnce` [dep1, dep2]
-- Package2 has an error
ResolveProjectDependencies package2 `fails` "Mock error"
expectFatal' $ resolveGraph [package1, package2] skips
-- The graph should resolve with the successful results.
graph <- resolveGraph [package1, package2] skips
graph `shouldBe'` expectedGraph
it' "resolves dependencies not in the skip list" $ do
let package1 = testTopLevelLocator 1
package2 = testTopLevelLocator 2
Expand Down
Loading