2022-12-05 05:14:40 +03:00
{- # OPTIONS_GHC - Wno - unrecognised - pragmas # -}
{- # HLINT ignore "Use commaSeparated" # -}
{- # HLINT ignore "Use tshow" # -}
2022-04-10 07:47:15 +03:00
module Command
( Command ( .. ) ,
2022-12-05 05:14:40 +03:00
TestOptions ( .. ) ,
SensitiveOutputHandling ( .. ) ,
SandwichArguments ( .. ) ,
2022-09-28 02:41:21 +03:00
TestConfig ( .. ) ,
2022-12-05 05:14:40 +03:00
AgentOptions ( .. ) ,
2023-02-02 07:26:29 +03:00
AgentConfig ( .. ) ,
2022-10-06 02:23:49 +03:00
NameCasing ( .. ) ,
2022-10-24 05:09:16 +03:00
ExportDataConfig ( .. ) ,
ExportFormat ( .. ) ,
2022-04-10 07:47:15 +03:00
parseCommandLine ,
)
where
import Control.Arrow ( left )
2022-09-28 02:41:21 +03:00
import Data.Aeson ( FromJSON ( .. ) , eitherDecodeStrict' )
2022-12-05 05:14:40 +03:00
import Data.List ( intercalate )
2022-04-10 07:47:15 +03:00
import Data.Text ( Text )
import Data.Text qualified as Text
2022-05-02 02:01:11 +03:00
import Data.Text.Encoding qualified as Text
2022-04-10 07:47:15 +03:00
import Data.Version ( showVersion )
2022-05-02 08:03:12 +03:00
import Hasura.Backends.DataConnector.API qualified as API
2022-04-10 07:47:15 +03:00
import Options.Applicative
2022-09-27 10:20:46 +03:00
import Paths_dc_api qualified as PackageInfo
2022-04-10 07:47:15 +03:00
import Servant.Client ( BaseUrl , parseBaseUrl )
import Prelude
data Command
2022-12-05 05:14:40 +03:00
= Test TestOptions SandwichArguments
2022-04-10 07:47:15 +03:00
| ExportOpenAPISpec
2022-10-24 05:09:16 +03:00
| ExportData ExportDataConfig
2022-04-10 07:47:15 +03:00
2022-12-05 05:14:40 +03:00
data TestOptions = TestOptions
{ _toAgentOptions :: AgentOptions ,
_toTestConfig :: TestConfig ,
_toSensitiveOutputHandling :: SensitiveOutputHandling
}
newtype SandwichArguments = SandwichArguments [ String ]
2022-09-28 02:41:21 +03:00
data TestConfig = TestConfig
2022-10-06 02:23:49 +03:00
{ _tcTableNamePrefix :: [ Text ] ,
_tcTableNameCasing :: NameCasing ,
_tcColumnNameCasing :: NameCasing
}
2022-12-05 05:14:40 +03:00
data SensitiveOutputHandling
= AllowSensitiveOutput
| DisallowSensitiveOutput
data AgentOptions = AgentOptions
{ _aoAgentBaseUrl :: BaseUrl ,
2023-02-02 07:26:29 +03:00
_aoAgentConfig :: AgentConfig
2022-12-05 05:14:40 +03:00
}
2023-02-02 07:26:29 +03:00
data AgentConfig
= ManualConfig API . Config
| DatasetConfig ( Maybe API . Config )
2022-10-06 02:23:49 +03:00
data NameCasing
= PascalCase
| Lowercase
2022-11-15 02:06:57 +03:00
| Uppercase
2023-02-02 08:46:56 +03:00
deriving stock ( Eq , Show , Read , Enum , Bounded )
2022-04-10 07:47:15 +03:00
2022-10-24 05:09:16 +03:00
data ExportDataConfig = ExportDataConfig
{ _edcDirectory :: FilePath ,
_edcFormat :: ExportFormat ,
_edcDateTimeFormat :: Maybe String
}
data ExportFormat
= JSON
| JSONLines
2023-03-24 17:33:13 +03:00
| SingleJSONFile
2023-02-02 08:46:56 +03:00
deriving stock ( Eq , Show , Read )
2022-10-24 05:09:16 +03:00
2022-04-10 07:47:15 +03:00
parseCommandLine :: IO Command
parseCommandLine =
execParser $
info
( helper <*> version <*> commandParser )
( fullDesc
2022-05-02 08:03:12 +03:00
<> header " Hasura Data Connector Agent Test Utility "
2022-04-10 07:47:15 +03:00
)
version :: Parser ( a -> a )
version =
infoOption
displayText
( long " version "
<> short 'v'
<> help " Prints the version of the application and quits "
<> hidden
)
where
displayText = " Version " <> showVersion PackageInfo . version
commandParser :: Parser Command
commandParser =
subparser
2022-10-24 05:09:16 +03:00
( testCommand <> exportOpenApiSpecCommand <> exportData )
2022-04-10 07:47:15 +03:00
where
testCommand =
command
" test "
( info
( helper <*> testCommandParser )
( progDesc " Executes a suite of tests against an agent to ensure its correct function " )
)
exportOpenApiSpecCommand =
command
" export-openapi-spec "
( info
( helper <*> pure ExportOpenAPISpec )
2022-05-02 08:03:12 +03:00
( progDesc " Exports the OpenAPI specification of the Data Connector API that agents must implement " )
2022-04-10 07:47:15 +03:00
)
2022-10-24 05:09:16 +03:00
exportData =
command
" export-data "
( info
( helper <*> ( ExportData <$> exportDataConfigParser ) )
( progDesc " Exports the Chinook dataset to files in the specified directory " )
)
2022-04-10 07:47:15 +03:00
2022-12-05 05:14:40 +03:00
testCommandParser :: Parser Command
testCommandParser = Test <$> testOptionsParser <*> sandwichArgumentsParser
testOptionsParser :: Parser TestOptions
testOptionsParser =
TestOptions
<$> agentOptionsParser
<*> testConfigParser
<*> flag
DisallowSensitiveOutput
AllowSensitiveOutput
( long " allow-sensitive-output "
<> help " Allows sensitive values (such as the X-Hasura-DataConnector-Config header) to appear in test debug output "
)
sandwichArgumentsParser :: Parser SandwichArguments
sandwichArgumentsParser =
subparser ( command " sandwich " ( info ( SandwichArguments <$> many ( strArgument mempty ) ) forwardOptions ) )
<|> pure ( SandwichArguments [] )
2022-09-28 02:41:21 +03:00
testConfigParser :: Parser TestConfig
testConfigParser =
TestConfig
<$> option
jsonValue
( long " table-name-prefix "
<> short 't'
<> metavar " PREFIX "
<> help " The prefix to use for all table names, as a JSON array of strings "
<> value []
)
2022-10-06 02:23:49 +03:00
<*> option
auto
( long " table-name-casing "
<> metavar " CASING "
2022-12-05 05:14:40 +03:00
<> help ( " The casing style to use for table names ( " <> casingOptions <> " ). Default: PascalCase " )
2022-10-06 02:23:49 +03:00
<> value PascalCase
)
<*> option
auto
( long " column-name-casing "
<> metavar " CASING "
2022-12-05 05:14:40 +03:00
<> help ( " The casing style to use for column names ( " <> casingOptions <> " ). Default: PascalCase " )
2022-10-06 02:23:49 +03:00
<> value PascalCase
)
2022-12-05 05:14:40 +03:00
where
casingOptions = intercalate " , " $ show <$> enumFromTo @ NameCasing minBound maxBound
2022-09-28 02:41:21 +03:00
2022-12-05 05:14:40 +03:00
agentOptionsParser :: Parser AgentOptions
agentOptionsParser =
AgentOptions
2022-04-10 07:47:15 +03:00
<$> option
baseUrl
( long " agent-base-url "
<> short 'u'
<> metavar " URL "
2022-05-02 08:03:12 +03:00
<> help " The base URL of the Data Connector agent to be tested "
2022-04-10 07:47:15 +03:00
)
2023-02-02 07:26:29 +03:00
<*> ( ManualConfig
<$> option
configValue
( long " agent-config "
<> metavar " JSON "
<> help " The configuration JSON to be sent to the agent via the X-Hasura-DataConnector-Config header. If omitted, datasets will be used to load test data and provide this configuration dynamically "
)
<|> DatasetConfig
<$> optional
( option
configValue
( long " merge-agent-config "
<> metavar " JSON "
<> help " Datasets will be used to load test data and provide configuration JSON to be sent to the agent via the X-Hasura-DataConnector-Config header. This config will be merged with the dataset-provided config before being sent to the agent. "
)
)
)
2022-04-10 07:47:15 +03:00
2022-10-24 05:09:16 +03:00
exportDataConfigParser :: Parser ExportDataConfig
exportDataConfigParser =
ExportDataConfig
<$> strOption
( long " directory "
<> short 'd'
<> metavar " DIR "
<> help " The directory to export the data files into "
)
<*> option
auto
( long " format "
<> short 'f'
<> metavar " FORMAT "
<> help " The format to export (JSON or JSONLines) "
)
<*> optional
( strOption
( long " datetime-format "
<> metavar " FORMAT "
<> help " Format string to use when formatting DateTime columns (use format syntax from https://hackage.haskell.org/package/time-1.12.2/docs/Data-Time-Format.html#v:formatTime) "
)
)
2022-04-10 07:47:15 +03:00
baseUrl :: ReadM BaseUrl
baseUrl = eitherReader $ left show . parseBaseUrl
2022-05-02 02:01:11 +03:00
configValue :: ReadM API . Config
2022-09-28 02:41:21 +03:00
configValue = fmap API . Config jsonValue
jsonValue :: FromJSON v => ReadM v
jsonValue = eitherReader ( eitherDecodeStrict' . Text . encodeUtf8 . Text . pack )