Skip to content

Commit b4fbc86

Browse files
committed
fix: adapt hsec-tools to new layout
1 parent ea8517a commit b4fbc86

File tree

3 files changed

+29
-37
lines changed

3 files changed

+29
-37
lines changed

code/hsec-tools/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Move `isVersionAffectedBy` and `isVersionRangeAffectedBy` to `Security.Advisories.Core` (`hsec-core`)
44
* Add support for GHC component in `query is-affected`
55
* Add `model.database_specific.{repository,osvs,home}` and `model.affected.database_specific.{osv,human_link}` in OSV exports
6+
* Adapt to new security-advisories layout
67

78
## 0.2.0.2
89

code/hsec-tools/hsec-tools.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ library
7373
, pandoc >=2.0 && <3.8
7474
, pandoc-types >=1.22 && <2
7575
, parsec >=3 && <4
76-
, pathwalk >=0.3 && <0.4
7776
, pretty >=1.0 && <1.2
7877
, prettyprinter >=1.7 && <1.8
7978
, process >=1.6 && <1.7

code/hsec-tools/src/Security/Advisories/Filesystem.hs

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Security.Advisories.Filesystem
1313
(
1414
dirNameAdvisories
1515
, dirNameReserved
16+
, dirNamePublished
1617
, isSecurityAdvisoriesRepo
1718
, getReservedIds
1819
, getAdvisoryIds
@@ -36,12 +37,10 @@ import Data.Semigroup (Max(Max, getMax))
3637
import Data.Traversable (for)
3738

3839
import Control.Monad.IO.Class (MonadIO, liftIO)
39-
import Control.Monad.Writer.Strict (execWriterT, tell)
4040
import qualified Data.Text as T
4141
import qualified Data.Text.IO as T
42-
import System.FilePath ((</>), takeBaseName, splitDirectories)
43-
import System.Directory (doesDirectoryExist, pathIsSymbolicLink)
44-
import System.Directory.PathWalk
42+
import System.FilePath ((</>), dropExtension, splitDirectories)
43+
import System.Directory (doesDirectoryExist, listDirectory)
4544
import Validation (Validation (..))
4645

4746
import Security.Advisories (Advisory, AttributeOverridePolicy (NoOverrides), OutOfBandAttributes (..), ParseAdvisoryError, parseAdvisory, ComponentIdentifier(..))
@@ -51,13 +50,15 @@ import Control.Monad.Except (runExceptT, ExceptT (ExceptT), withExceptT)
5150
import Security.Advisories.Parse (OOBError(GitHasNoOOB, PathHasNoComponentIdentifier))
5251
import Security.Advisories.Core.Advisory (ghcComponentFromText)
5352

54-
5553
dirNameAdvisories :: FilePath
5654
dirNameAdvisories = "advisories"
5755

5856
dirNameReserved :: FilePath
5957
dirNameReserved = "reserved"
6058

59+
dirNamePublished :: FilePath
60+
dirNamePublished = "published"
61+
6162
-- | Check whether the directory appears to be the root of a
6263
-- /security-advisories/ filesystem. Only checks that the
6364
-- @advisories@ subdirectory exists.
@@ -109,7 +110,7 @@ forReserved
109110
:: (MonadIO m, Monoid r)
110111
=> FilePath -> (FilePath -> HsecId -> m r) -> m r
111112
forReserved root =
112-
_forFiles (root </> dirNameAdvisories </> dirNameReserved)
113+
_forFilesByYear (root </> dirNameAdvisories </> dirNameReserved)
113114

114115
-- | Invoke a callback for each HSEC ID under each of the advisory
115116
-- subdirectories, excluding the @reserved@ directory. The results
@@ -121,23 +122,17 @@ forReserved root =
121122
forAdvisory
122123
:: (MonadIO m, Monoid r)
123124
=> FilePath -> (FilePath -> HsecId -> m r) -> m r
124-
forAdvisory root go = do
125-
let dir = root </> dirNameAdvisories
126-
subdirs <- filter (/= dirNameReserved) <$> _getSubdirs dir
127-
fmap fold $ for subdirs $ \subdir -> _forFiles (dir </> subdir) go
125+
forAdvisory root =
126+
_forFilesByYear (root </> dirNameAdvisories </> dirNamePublished)
128127

129-
-- | List deduplicated parsed Advisories
128+
-- | List parsed Advisories
130129
listAdvisories
131130
:: (MonadIO m)
132131
=> FilePath -> m (Validation [(FilePath, ParseAdvisoryError)] [Advisory])
133132
listAdvisories root =
134-
forAdvisory root $ \advisoryPath _advisoryId -> do
135-
isSym <- liftIO $ pathIsSymbolicLink advisoryPath
136-
if isSym
137-
then return $ pure []
138-
else
139-
bimap (\err -> [(advisoryPath, err)]) pure
140-
<$> advisoryFromFile advisoryPath
133+
forAdvisory root $ \advisoryPath _advisoryId ->
134+
bimap (\err -> [(advisoryPath, err)]) pure
135+
<$> advisoryFromFile advisoryPath
141136

142137
-- | Parse an advisory from a file system path
143138
advisoryFromFile
@@ -158,28 +153,25 @@ advisoryFromFile advisoryPath = do
158153
$ either Failure Success
159154
$ parseAdvisory NoOverrides oob fileContent
160155

161-
-- | Get names (not paths) of subdirectories of the given directory
162-
-- (one level). There's no monoidal, interruptible variant of
163-
-- @pathWalk@ so we use @WriterT@ to smuggle the result out.
164-
--
165-
_getSubdirs :: (MonadIO m) => FilePath -> m [FilePath]
166-
_getSubdirs root =
167-
execWriterT $
168-
pathWalkInterruptible root $ \_ subdirs _ -> do
169-
tell subdirs
170-
pure Stop
171-
172-
_forFiles
156+
_forFilesByYear
173157
:: (MonadIO m, Monoid r)
174158
=> FilePath -- ^ (sub)directory name
175159
-> (FilePath -> HsecId -> m r)
176160
-> m r
177-
_forFiles root go =
178-
pathWalkAccumulate root $ \dir _ files ->
179-
fmap fold $ for files $ \file ->
180-
case parseHsecId (takeBaseName file) of
181-
Nothing -> pure mempty
182-
Just hsid -> go (dir </> file) hsid
161+
_forFilesByYear root go = do
162+
yearsFile <- liftIO $ listDirectory root
163+
fmap (foldMap fold) $
164+
for yearsFile $ \year -> do
165+
let yearDir = root </> year
166+
isYear <- liftIO $ doesDirectoryExist yearDir
167+
if isYear
168+
then do
169+
files <- liftIO $ listDirectory yearDir
170+
for files $ \file ->
171+
case parseHsecId ("HSEC-" <> year <> "-" <> dropExtension file) of
172+
Nothing -> pure mempty
173+
Just hsid -> go (yearDir </> file) hsid
174+
else pure mempty
183175

184176
parseComponentIdentifier :: Monad m => FilePath -> ExceptT OOBError m (Maybe ComponentIdentifier)
185177
parseComponentIdentifier fp = ExceptT . pure $ case drop 1 $ reverse $ splitDirectories fp of

0 commit comments

Comments
 (0)