{- Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. -} module Util (withFixtureOptions) where import Data.List import System.Directory import System.FilePath import Thrift.Compiler.Options import Thrift.Compiler.OptParse import Thrift.Compiler.Plugins.Haskell import Thrift.Compiler.Plugins.Linter withFixtureOptions :: ([SomeOptions] -> IO a) -> IO a withFixtureOptions f = do dir <- getCurrentDirectory compilerDir <- findCompilerDir dir let outPath = if inTree then "compiler" "test" "fixtures" else "test" "fixtures" inTree = takeBaseName compilerDir == "compiler" testsCwd = if inTree then takeDirectory compilerDir else compilerDir includePathFor fp | inTree, "compiler/" `isPrefixOf` fp = "compiler" | "tests/" `isPrefixOf` fp = "tests" | otherwise = "." fixup fp | Just rest <- stripPrefix "compiler/" fp = rest | Just rest <- stripPrefix "tests/" fp = rest | otherwise = fp withCurrentDirectory testsCwd $ f [ TheseOptions (defaultOptions langopts) { optsPath = fixup path , optsOutPath = outPath genDir , optsIncludePath = includePathFor path , optsRecursive = True , optsGenMode = mode , optsSingleOutput = singleOut } | (TheseLangOpts langopts, mode, singleOut, genDir, path) <- [ (TheseLangOpts defaultHsOpts, EmitCode, False, "", "tests/if/hs_test.thrift") , (TheseLangOpts defaultHsOpts{hsoptsExtraHasFields=True}, EmitCode, False, "", "tests/if/service.thrift") , (TheseLangOpts defaultHsOpts, EmitCode, False, "", "compiler/test/if/a.thrift") , (TheseLangOpts NoOpts, EmitJSON WithoutLoc, False, "gen-basic", "compiler/test/if/a.thrift") , (TheseLangOpts NoOpts, EmitJSON WithoutLoc, True, "gen-single-out", "compiler/test/if/a.thrift") , (TheseLangOpts NoOpts, EmitJSON WithLoc, False, "gen-basic-loc", "compiler/test/if/a.thrift") , (TheseLangOpts NoOpts, EmitJSON WithLoc, True, "gen-single-out-loc", "compiler/test/if/a.thrift") ] ] findCompilerDir :: FilePath -> IO FilePath findCompilerDir cwd = lookFor "thrift-compiler.cabal" cwd maxDepth >>= \mdir -> case mdir of Nothing -> error "findCompilerDir: reached max depth, couldn't find thrift-compiler.cabal" Just d -> return d where lookFor _ _ (-1) = return Nothing lookFor file curDir depth = do existsHere <- doesFileExist (curDir file) if existsHere then return (Just curDir) else do xs <- listDirectory curDir visitDirsIn xs file curDir depth visitDirsIn [] _ _ _ = return Nothing visitDirsIn (d:ds) file curDir depth = do dirExists <- doesDirectoryExist (curDir d) if dirExists then do mfp <- lookFor file (curDir d) (depth-1) case mfp of Nothing -> visitDirsIn ds file curDir depth Just fp -> return (Just fp) else visitDirsIn ds file curDir depth maxDepth = 2 :: Int