mirror of
https://github.com/github/semantic.git
synced 2024-12-25 16:02:43 +03:00
Refactor IO back out into Source and SemanticDiff
This commit is contained in:
parent
bfe1181acb
commit
fff9b6d3ef
@ -49,7 +49,6 @@ library
|
||||
, Renderer.SExpression
|
||||
, Renderer.TOC
|
||||
, SemanticDiff
|
||||
, SemanticDiff.IO
|
||||
, SES
|
||||
, Source
|
||||
, SourceSpan
|
||||
|
@ -32,7 +32,6 @@ import Renderer.SExpression
|
||||
import Renderer.Split
|
||||
import Renderer.Summary
|
||||
import Renderer.TOC
|
||||
import SemanticDiff.IO
|
||||
import Source
|
||||
import Syntax
|
||||
import Term
|
||||
|
@ -24,7 +24,6 @@ import Text.Parser.TreeSitter.C
|
||||
import Text.Parser.TreeSitter.Go
|
||||
import Text.Parser.TreeSitter.JavaScript
|
||||
import Text.Parser.TreeSitter.Ruby
|
||||
import SemanticDiff.IO
|
||||
|
||||
data ParseJSON = ParseJSON
|
||||
{ category :: Text
|
||||
|
@ -13,7 +13,9 @@ import qualified Renderer as R
|
||||
import Development.GitRev
|
||||
import DiffCommand
|
||||
import ParseCommand
|
||||
import SemanticDiff.IO
|
||||
import qualified Data.Text.IO as TextIO
|
||||
import System.IO
|
||||
import System.Environment (lookupEnv)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
@ -56,3 +58,18 @@ versionString = "semantic-diff version " <> showVersion Library.version <> " ("
|
||||
|
||||
version :: Parser (a -> a)
|
||||
version = infoOption versionString (long "version" <> short 'V' <> help "output the version of the program")
|
||||
|
||||
writeToOutput :: Maybe FilePath -> Text -> IO ()
|
||||
writeToOutput output text = case output of
|
||||
Nothing -> do
|
||||
setEncoding
|
||||
TextIO.hPutStrLn stdout text
|
||||
Just path -> withFile path WriteMode (`TextIO.hPutStr` text)
|
||||
where
|
||||
setEncoding = do
|
||||
lang <- lookupEnv "LANG"
|
||||
case lang of
|
||||
-- If LANG is set and isn't the empty string, leave the encoding.
|
||||
Just x | x /= "" -> pure ()
|
||||
-- Otherwise default to utf8.
|
||||
_ -> hSetEncoding stdout utf8
|
||||
|
@ -1,56 +0,0 @@
|
||||
module SemanticDiff.IO where
|
||||
|
||||
import Prelude
|
||||
import Data.Text
|
||||
import qualified Data.Text.IO as TextIO
|
||||
import System.IO
|
||||
import System.Environment (lookupEnv)
|
||||
|
||||
import Control.Exception (catch, IOException)
|
||||
import qualified Data.ByteString as B1
|
||||
import qualified Data.Text.ICU.Convert as Convert
|
||||
import qualified Data.Text.ICU.Detect as Detect
|
||||
|
||||
import Source
|
||||
|
||||
writeToOutput :: Maybe FilePath -> Text -> IO ()
|
||||
writeToOutput output text = case output of
|
||||
Nothing -> do
|
||||
setEncoding
|
||||
TextIO.hPutStrLn stdout text
|
||||
Just path -> withFile path WriteMode (`TextIO.hPutStr` text)
|
||||
|
||||
where
|
||||
setEncoding = do
|
||||
lang <- lookupEnv "LANG"
|
||||
case lang of
|
||||
-- If LANG is set and isn't the empty string, leave the encoding.
|
||||
Just x | x /= "" -> pure ()
|
||||
-- Otherwise default to utf8.
|
||||
_ -> hSetEncoding stdout utf8
|
||||
|
||||
-- | Read the file and convert it to Unicode.
|
||||
readAndTranscodeFile :: FilePath -> IO Source
|
||||
readAndTranscodeFile path = do
|
||||
size <- fileSize path
|
||||
text <- case size of
|
||||
0 -> pure B1.empty
|
||||
_ -> B1.readFile path
|
||||
transcode text
|
||||
|
||||
-- From https://github.com/haskell/bytestring/pull/79/files
|
||||
fileSize :: FilePath -> IO Integer
|
||||
fileSize f = withBinaryFile f ReadMode $ \h -> do
|
||||
-- hFileSize fails if file is not regular file (like /dev/null). Catch
|
||||
-- exception and try reading anyway.
|
||||
filesz <- catch (hFileSize h) useZeroIfNotRegularFile
|
||||
pure $ fromIntegral filesz `max` 0
|
||||
where useZeroIfNotRegularFile :: IOException -> IO Integer
|
||||
useZeroIfNotRegularFile _ = pure 0
|
||||
|
||||
-- | Transcode a file to a unicode source.
|
||||
transcode :: B1.ByteString -> IO Source
|
||||
transcode text = fromText <$> do
|
||||
match <- Detect.detectCharset text
|
||||
converter <- Convert.open match Nothing
|
||||
pure $ Convert.toUnicode converter text
|
@ -2,6 +2,7 @@
|
||||
{-# OPTIONS_GHC -funbox-strict-fields #-}
|
||||
module Source where
|
||||
|
||||
import Prelude (FilePath, fromIntegral)
|
||||
import Prologue
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.Text as T
|
||||
@ -9,6 +10,10 @@ import Numeric
|
||||
import Range
|
||||
import SourceSpan
|
||||
import Test.LeanCheck
|
||||
import System.IO
|
||||
import Control.Exception (catch, IOException)
|
||||
import qualified Data.Text.ICU.Convert as Convert
|
||||
import qualified Data.Text.ICU.Detect as Detect
|
||||
|
||||
-- | The source, oid, path, and Maybe SourceKind of a blob in a Git repo.
|
||||
data SourceBlob = SourceBlob { source :: Source, oid :: T.Text, path :: FilePath, blobKind :: Maybe SourceKind }
|
||||
@ -22,12 +27,37 @@ newtype Source = Source { sourceText :: B.ByteString }
|
||||
data SourceKind = PlainBlob Word32 | ExecutableBlob Word32 | SymlinkBlob Word32
|
||||
deriving (Show, Eq)
|
||||
|
||||
-- | Read the file and convert it to Unicode.
|
||||
readAndTranscodeFile :: FilePath -> IO Source
|
||||
readAndTranscodeFile path = do
|
||||
size <- fileSize path
|
||||
text <- case size of
|
||||
0 -> pure B.empty
|
||||
_ -> B.readFile path
|
||||
transcode text
|
||||
|
||||
-- From https://github.com/haskell/bytestring/pull/79/files
|
||||
fileSize :: FilePath -> IO Integer
|
||||
fileSize f = withBinaryFile f ReadMode $ \h -> do
|
||||
-- hFileSize fails if file is not regular file (like /dev/null). Catch
|
||||
-- exception and try reading anyway.
|
||||
filesz <- catch (hFileSize h) useZeroIfNotRegularFile
|
||||
pure $ fromIntegral filesz `max` 0
|
||||
where useZeroIfNotRegularFile :: IOException -> IO Integer
|
||||
useZeroIfNotRegularFile _ = pure 0
|
||||
|
||||
-- | Transcode a file to a unicode source.
|
||||
transcode :: B.ByteString -> IO Source
|
||||
transcode text = fromText <$> do
|
||||
match <- Detect.detectCharset text
|
||||
converter <- Convert.open match Nothing
|
||||
pure $ Convert.toUnicode converter text
|
||||
|
||||
modeToDigits :: SourceKind -> Text
|
||||
modeToDigits (PlainBlob mode) = toS $ showOct mode ""
|
||||
modeToDigits (ExecutableBlob mode) = toS $ showOct mode ""
|
||||
modeToDigits (SymlinkBlob mode) = toS $ showOct mode ""
|
||||
|
||||
|
||||
-- | The default plain blob mode
|
||||
defaultPlainBlob :: SourceKind
|
||||
defaultPlainBlob = PlainBlob 0o100644
|
||||
|
@ -14,7 +14,6 @@ import Renderer
|
||||
import Renderer.SExpression as Renderer
|
||||
import Source
|
||||
import DiffCommand
|
||||
import SemanticDiff.IO (readAndTranscodeFile)
|
||||
import System.FilePath
|
||||
import System.FilePath.Glob
|
||||
import Test.Hspec (Spec, describe, it, SpecWith, runIO, parallel)
|
||||
|
@ -10,7 +10,6 @@ import Data.Record
|
||||
import Data.String
|
||||
import Diff
|
||||
import DiffCommand
|
||||
import SemanticDiff.IO (readAndTranscodeFile)
|
||||
import Info
|
||||
import Interpreter
|
||||
import ParseCommand
|
||||
|
Loading…
Reference in New Issue
Block a user