From fc4871c8400debed62652b7596b163b6c7788901 Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Sat, 29 Jun 2019 14:09:29 +0200 Subject: [PATCH] Add local run possibility (#33) Signed-off-by: Sascha Grunert --- README.md | 90 ++++++++++++++++++++++++++++++++++++++++++++-- app/Main.hs | 20 +++++------ src/Environment.hs | 4 +-- src/Github.hs | 7 ++-- src/Result.hs | 22 +++++++----- 5 files changed, 118 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9506f29..25f8488 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ During the run, Performabot needs some information about the local test environment before actually commenting to GitHub pull requests. These parameters can be specified either via local environment variables or the command line, where test runs within [CircleCI](https://circleci.com) should work out of the -box (except for the token). The needed information are: +box, except for the token. The needed environmental information are: | Flag | Environment Variable | Description | | --------------------- | ------------------------------------------- | --------------------------- | @@ -65,7 +65,91 @@ settings](https://github.com/settings/tokens), whereas only `public_repo` (Access public repositories) has to be activated in case of an open source project. -## Depdendencies +## Benchmark runs + +As already mentioned, right now only +[ginkgo](https://onsi.github.io/ginkgo/#benchmark-tests) benchmarks are +supported. The tests have to be executed with `--succinct` to let the parser +finally work. Succinct silences much of Ginkgo’s more verbose output. Test +suites that succeed basically get printed out on just one line! Succinct is +turned off, by default, when running tests for one package. It is turned on by +default when Ginkgo runs multiple test packages. + +Feel free to open an issue or pull request for additional parsing support. + +## Try it out + +If you want to give the latest master branch a quick try, then install a +container runtime like [podman](https://podman.io) and test it with the +[`test/sample`](test/sample) file: + +```shell +> cat test/sample | podman run -i saschagrunert/performabot -l +... +[NOTE]: Welcome to performabot! +... +[NOTE]: Processing done, found 16 results +[NOTE]: Local run specified +[NOTE]: The report: + +### Performabot Result 🤖 + +Nothing to compare against. + +@@ Performance Diff @@ +## Ø ± × ## +========================================================== + create PodSandbox 0.404s 0.471s 20 + PodSandbox status 0.000s 0.000s 20 + stop PodSandbox 0.240s 0.015s 20 + remove PodSandbox 0.056s 0.012s 20 + create PodSandbox and container 0.405s 0.049s 20 + list Container 0.002s 0.005s 20 + pull Image 6.498s 0.478s 20 + Image status 0.002s 0.001s 20 + remove Image 0.068s 0.044s 20 + create Container 0.122s 0.035s 20 + start Container 0.030s 0.012s 20 + Container status 0.002s 0.001s 20 + stop Container 0.048s 0.014s 20 + remove Container 0.026s 0.004s 20 + list PodSandbox 0.000s 0.000s 20 + list Container 0.000s 0.000s 20 +========================================================== +``` + +The `-l` `--local` flag specifies a local run. This means that there will be no +validation of the local environment variables nor any GitHub interaction at all. +Nevertheless, a local `performabot.sqlite` should now be available within the +current directory which contains the run. + +Further command line arguments are: + +``` +Usage: performabot [-c|--commit COMMIT] [-p|--pull-request PULL_REQUEST] + [-r|--repository REPOSITORY] [-o|--owner OWNER] + [-t|--token TOKEN] [-v|--verbose] [-l|--local] [--version] + +Available options: + -c,--commit COMMIT Commit hash - fallback environment variables: + $PB_COMMIT, $CIRCLE_SHA1 + -p,--pull-request PULL_REQUEST + Pull request number - fallback environment variables: + $PB_PULL_REQUEST, $CIRCLE_PR_NUMBER + -r,--repository REPOSITORY + GitHub repository - fallback environment variables: + $PB_REPOSITORY, $CIRCLE_PROJECT_REPONAME + -o,--owner OWNER GitHub owner - fallback environment variables: + $PB_OWNER, $CIRCLE_PROJECT_USERNAME + -t,--token TOKEN Token - fallback environment variable: $PB_TOKEN + -h,--help Show this help text + -v,--verbose Logging verbosity, can be specified up to 2x + -l,--local Run only locally and do not upload anything + --version Print the current version + -h,--help Show this help text +``` + +## Build dependencies There is only one dependency needed to get started with this project: [nix](https://nixos.org/nix) @@ -100,7 +184,7 @@ included in `$PATH`, then run: ``` There are other useful targets within the [Makefile](Makefile), which are used -by the CI and could be worth a look. If you don't want to use nix, then you're +by the CI and could be worth a look. If you don’t want to use nix, then you’re free to build the project with [stack](https://haskellstack.org) or [cabal](https://www.haskell.org/cabal) as well. diff --git a/app/Main.hs b/app/Main.hs index a476237..4fc2145 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -24,8 +24,8 @@ import Options.Applicative prefShowHelpOnEmpty, prefShowHelpOnError, prefBacktrack, prefColumns) , customExecParser, flag', footer, fullDesc, header, help - , helper, infoOption, internal, long, many, metavar, short - , short, strOption, switch, value ) + , helper, infoOption, long, many, metavar, short, short + , strOption, switch, value ) import Result ( amount, initParserStep, parseStepIO, save ) @@ -64,7 +64,7 @@ parser = ++ "")) arguments :: Parser Args -arguments = Args <$> environment <*> verbosity <*> devel +arguments = Args <$> environment <*> verbosity <*> local environment :: Parser Environment environment = Environment <$> strOption (long "commit" <> short 'c' @@ -91,16 +91,16 @@ verbosity :: Parser Priority verbosity = priority . length <$> many (flag' () (long "verbose" <> short 'v' - <> help ("the logging verbosity," - ++ " can be specified up to 2x"))) + <> help "Logging verbosity, can be specified up to 2x")) where priority a | a == 0 = NOTICE | a == 1 = INFO | otherwise = DEBUG -devel :: Parser Bool -devel = switch (internal <> long "devel" <> short 'd') +local :: Parser Bool +local = switch (long "local" <> short 'l' + <> help "Run only locally and do not upload anything") version :: Parser (a -> a) version = @@ -108,14 +108,14 @@ version = -- | The entry function after argument parsing run :: Args -> IO () -run (Args e v d) = do +run (Args e v l) = do -- Setup logging initLogger v notice "Welcome to performabot!" notice . printf "The logging verbosity is set to: %s" $ show v -- Prepare environment - env <- fillEnvironment e d + env <- fillEnvironment e l L.info . printf "Using commit: %s" $ env ^. commit L.info . printf "Using pull request: %s" $ env ^. pullRequest L.info . printf "Using repository: %s" $ env ^. repository @@ -132,7 +132,7 @@ run (Args e v d) = do notice . printf "Processing done, found %d result%s" c $ if c == 1 then "" else "s" :: String if c /= 0 - then save r env + then save l r env else do warn "Not saving anything because no results found" exitFailure diff --git a/src/Environment.hs b/src/Environment.hs index 2187aef..befc165 100644 --- a/src/Environment.hs +++ b/src/Environment.hs @@ -40,7 +40,7 @@ $(makeLenses ''Environment) -- | Try to fill the environment from local variables fillEnvironment :: Environment -> Bool -> IO Environment -fillEnvironment e d = do +fillEnvironment e l = do c <- getEnv (e ^. commit) "commit" commitEnvVars p <- getEnv (e ^. pullRequest) "pull request" pullRequestEnvVars r <- getEnv (e ^. repository) "repository" repositoryEnvVars @@ -48,7 +48,7 @@ fillEnvironment e d = do t <- getEnv (e ^. token) "token" tokenEnvVars -- Validate the other environment variables - if not d && any null [ c, p, r, t ] + if not l && any null [ c, p, r, t ] then exitFailure else return $ token .~ t $ pullRequest .~ p $ commit .~ c $ owner .~ o $ repository .~ r $ e diff --git a/src/Github.hs b/src/Github.hs index 1b917f9..ab1bd27 100644 --- a/src/Github.hs +++ b/src/Github.hs @@ -14,7 +14,7 @@ import Environment ( Environment, owner, pullRequest, repository, token ) import GitHub ( Auth(OAuth) ) -import GitHub.Data.Comments ( Comment, commentUrl ) +import GitHub.Data.Comments ( Comment, commentHtmlUrl ) import GitHub.Data.Definitions ( Error, IssueNumber(IssueNumber), Owner ) import GitHub.Data.Id ( Id(Id) ) @@ -82,7 +82,10 @@ handleCommentErr x t = case x of debug $ show f exitFailure Right c -> notice $ - printf "Comment %s successful: %s" t (getUrl $ commentUrl c) + printf "Comment %s successful: %s" t (urlOf $ commentHtmlUrl c) + where + urlOf Nothing = "Not found." + urlOf (Just u) = getUrl u -- | Finds comments from performabot isFromPerformabot :: [IssueComment] -> Maybe IssueComment diff --git a/src/Result.hs b/src/Result.hs index 02d3d36..1223556 100644 --- a/src/Result.hs +++ b/src/Result.hs @@ -72,16 +72,22 @@ debugResult :: Benchmarks -> IO () debugResult r = debug . printf "Current result: %s" $ show r -- | Sen the provided data to the given url including the environment -save :: Step -> Environment -> IO () -save (_, b) e = do - c <- baseCommit e - info "Base commit retrieval successful" +save :: Bool -> Step -> Environment -> IO () +save l (_, b) e = do insertInDB e b info "Database insertion successful" - pb <- entryForCommit c - let r = prettyPrint b pb - notice $ printf "The report: %s" r - comment e r + r <- if not l + then do + c <- baseCommit e + info "Base commit retrieval successful" + pb <- entryForCommit c + let r = prettyPrint b pb + comment e r + return r + else do + notice "Local run specified" + return $ prettyPrint b Nothing + notice $ printf "The report:\n\n%s" r -- | The database name db :: Text