From 6f8599e8c46c995b3d7bdadb540a3399a4c62fe5 Mon Sep 17 00:00:00 2001 From: ksaric Date: Fri, 27 Apr 2018 14:35:42 +0200 Subject: [PATCH] [CO-278] Migrate log-classifier to stack. --- .gitignore | 103 +++++++- .hindent.yaml | 3 + .stylish-haskell.yaml | 247 ++++++++++++++++++ ChangeLog.md | 3 + LICENSE | 30 +++ README.md | 1 + Setup.hs | 2 + app/Main.hs | 6 + fetch-nixpkgs.nix | 4 + fetchNixpkgs.nix | 41 +++ lib.nix | 19 ++ log-classifier.cabal | 103 ++++++++ nixpkgs-src.json | 5 + package.yaml | 59 +++++ shell.nix | 18 ++ Classify.hs => src/Classify.hs | 0 src/Lib.hs | 8 + .../LogAnalysis}/Classifier.hs | 0 .../LogAnalysis}/KnowledgeCSVParser.hs | 0 {LogAnalysis => src/LogAnalysis}/Types.hs | 0 Regex.hs => src/Regex.hs | 0 Types.hs => src/Types.hs | 0 Util.hs => src/Util.hs | 6 +- Zendesk.hs => src/Zendesk.hs | 16 +- stack.yaml | 70 +++++ test/Spec.hs | 2 + 26 files changed, 734 insertions(+), 12 deletions(-) create mode 100644 .hindent.yaml create mode 100644 .stylish-haskell.yaml create mode 100644 ChangeLog.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Setup.hs create mode 100644 app/Main.hs create mode 100644 fetch-nixpkgs.nix create mode 100644 fetchNixpkgs.nix create mode 100644 lib.nix create mode 100644 log-classifier.cabal create mode 100644 nixpkgs-src.json create mode 100644 package.yaml create mode 100644 shell.nix rename Classify.hs => src/Classify.hs (100%) create mode 100644 src/Lib.hs rename {LogAnalysis => src/LogAnalysis}/Classifier.hs (100%) rename {LogAnalysis => src/LogAnalysis}/KnowledgeCSVParser.hs (100%) rename {LogAnalysis => src/LogAnalysis}/Types.hs (100%) rename Regex.hs => src/Regex.hs (100%) rename Types.hs => src/Types.hs (100%) rename Util.hs => src/Util.hs (86%) rename Zendesk.hs => src/Zendesk.hs (98%) create mode 100644 stack.yaml create mode 100644 test/Spec.hs diff --git a/.gitignore b/.gitignore index 898a715..b713575 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,100 @@ -token -assign_to -emailAddress.txt \ No newline at end of file +# Cabal & Stack +.stack-work/ +*/dist + +# From daedalus-bridge +node_modules/* + +# Config files +.ghci + +# Our custom build script (util-scripts/build.sh) +b +.no-nix +.ram +.Werror + +# Various DBs +node-db* +wallet-db/ +wallet-new-db/ +db-*/ +wdb-*/ + +# Keys +*.key +*.key.lock +keys +!secrets/*.key +!scripts/tls-files/server.key +tmp-secrets/ + +# Node runtime data +logs +run + +# Emacs +*~ +*# +.#* +.dir-locals.el +GTAGS +GRTAGS +GPATH +TAGS + +# Vim +tags* + +# Intellij Idea & intellij-haskell +.idea +.ideaHaskellLib +*.iml + +# Atom +.haskell-ghc-mod.json + +# Misc +.DS_Store +*.swp + +# Compiled-scripts cruft +scripts/haskell/dependencies.hs +scripts/haskell/dependencies.hi +scripts/haskell/dependencies.o +scripts/haskell/dependencies + +# 'pkgs/stack2nix' is a symlink into the nix store, it can safely be ignored +pkgs/stack2nix +nixpkgs # in case generate.sh clones nixpkgs in here +pkgs/result + +# explorer +explorer-node.log.* +explorer-node.log +explorer.log +socket-io.log + +# importify +.importify + +# custom configuration +custom-wallet-config.nix + +# wallet web API benchmarking results +wallet-new/bench/results/*.csv +wallet-new/bench/results/*.txt + +# wallet web API golden tests +wallet-new/test/golden/*.txt.new + +# cardano-state-* for wallet data +cardano-state-* +state-* + +# exchange topology file +exchange-topology.yaml + +# launch scripts +launch_* +result* diff --git a/.hindent.yaml b/.hindent.yaml new file mode 100644 index 0000000..d28d833 --- /dev/null +++ b/.hindent.yaml @@ -0,0 +1,3 @@ +indent-size: 4 +line-length: 80 +force-trailing-newline: true diff --git a/.stylish-haskell.yaml b/.stylish-haskell.yaml new file mode 100644 index 0000000..3be07cd --- /dev/null +++ b/.stylish-haskell.yaml @@ -0,0 +1,247 @@ +# Stylish-haskell configuration file used for cardano-sl by Serokell. +# It's based on default config provided by `stylish-haskell --defaults` but has some changes +# ================================== + +# The stylish-haskell tool is mainly configured by specifying steps. These steps +# are a list, so they have an order, and one specific step may appear more than +# once (if needed). Each file is processed by these steps in the given order. +steps: + # Convert some ASCII sequences to their Unicode equivalents. This is disabled + # by default. + # - unicode_syntax: + # # In order to make this work, we also need to insert the UnicodeSyntax + # # language pragma. If this flag is set to true, we insert it when it's + # # not already present. You may want to disable it if you configure + # # language extensions using some other method than pragmas. Default: + # # true. + # add_language_pragma: true + + # Align the right hand side of some elements. This is quite conservative + # and only applies to statements where each element occupies a single + # line. + - simple_align: + cases: true + top_level_patterns: true + records: true + + # Import cleanup + - imports: + # There are different ways we can align names and lists. + # + # - global: Align the import names and import list throughout the entire + # file. + # + # - file: Like global, but don't add padding when there are no qualified + # imports in the file. + # + # - group: Only align the imports per group (a group is formed by adjacent + # import lines). + # + # - none: Do not perform any alignment. + # + # Default: global. + align: global + + # The following options affect only import list alignment. + # + # List align has following options: + # + # - after_alias: Import list is aligned with end of import including + # 'as' and 'hiding' keywords. + # + # > import qualified Data.List as List (concat, foldl, foldr, head, + # > init, last, length) + # + # - with_alias: Import list is aligned with start of alias or hiding. + # + # > import qualified Data.List as List (concat, foldl, foldr, head, + # > init, last, length) + # + # - new_line: Import list starts always on new line. + # + # > import qualified Data.List as List + # > (concat, foldl, foldr, head, init, last, length) + # + # Default: after_alias + list_align: after_alias + + # Right-pad the module names to align imports in a group: + # + # - true: a little more readable + # + # > import qualified Data.List as List (concat, foldl, foldr, + # > init, last, length) + # > import qualified Data.List.Extra as List (concat, foldl, foldr, + # > init, last, length) + # + # - false: diff-safe + # + # > import qualified Data.List as List (concat, foldl, foldr, init, + # > last, length) + # > import qualified Data.List.Extra as List (concat, foldl, foldr, + # > init, last, length) + # + # Default: true + + # Note: we intentionally disable it to make diffs less verbose and avoid + # merge conflicts in some cases. + pad_module_names: false + + # Long list align style takes effect when import is too long. This is + # determined by 'columns' setting. + # + # - inline: This option will put as much specs on same line as possible. + # + # - new_line: Import list will start on new line. + # + # - new_line_multiline: Import list will start on new line when it's + # short enough to fit to single line. Otherwise it'll be multiline. + # + # - multiline: One line per import list entry. + # Type with constructor list acts like single import. + # + # > import qualified Data.Map as M + # > ( empty + # > , singleton + # > , ... + # > , delete + # > ) + # + # Default: inline + long_list_align: inline + + # Align empty list (importing instances) + # + # Empty list align has following options + # + # - inherit: inherit list_align setting + # + # - right_after: () is right after the module name: + # + # > import Vector.Instances () + # + # Default: inherit + empty_list_align: inherit + + # List padding determines indentation of import list on lines after import. + # This option affects 'long_list_align'. + # + # - : constant value + # + # - module_name: align under start of module name. + # Useful for 'file' and 'group' align settings. + list_padding: 4 + + # Separate lists option affects formatting of import list for type + # or class. The only difference is single space between type and list + # of constructors, selectors and class functions. + # + # - true: There is single space between Foldable type and list of it's + # functions. + # + # > import Data.Foldable (Foldable (fold, foldl, foldMap)) + # + # - false: There is no space between Foldable type and list of it's + # functions. + # + # > import Data.Foldable (Foldable(fold, foldl, foldMap)) + # + # Default: true + separate_lists: true + + # Space surround option affects formatting of import lists on a single + # line. The only difference is single space after the initial + # parenthesis and a single space before the terminal parenthesis. + # + # - true: There is single space associated with the enclosing + # parenthesis. + # + # > import Data.Foo ( foo ) + # + # - false: There is no space associated with the enclosing parenthesis + # + # > import Data.Foo (foo) + # + # Default: false + space_surround: false + + # Language pragmas + - language_pragmas: + # We can generate different styles of language pragma lists. + # + # - vertical: Vertical-spaced language pragmas, one per line. + # + # - compact: A more compact style. + # + # - compact_line: Similar to compact, but wrap each line with + # `{-#LANGUAGE #-}'. + # + # Default: vertical. + style: vertical + + # stylish-haskell can detect redundancy of some language pragmas. If this + # is set to true, it will remove those redundant pragmas. Default: true. + remove_redundant: true + + # Replace tabs by spaces. This is disabled by default. + # - tabs: + # # Number of spaces to use for each tab. Default: 8, as specified by the + # # Haskell report. + # spaces: 8 + + # Remove trailing whitespace + - trailing_whitespace: {} + +# A common setting is the number of columns (parts of) code will be wrapped +# to. Different steps take this into account. Default: 80. +# +# Note: we tend to write code which fits into 80 characters, in some cases +# 100 is acceptable. For imports we always permit 100 characters because it +# decreases verbosity of diffs and makes merging easier. +columns: 100 + +# By default, line endings are converted according to the OS. You can override +# preferred format here. +# +# - native: Native newline format. CRLF on Windows, LF on other OSes. +# +# - lf: Convert to LF ("\n"). +# +# - crlf: Convert to CRLF ("\r\n"). +# +# Default: native. +newline: native + +# These syntax-affecting language extensions are enabled so that +# stylish-haskell wouldn't fail with parsing errors when processing files +# in projects that have those extensions enabled in the .cabal file +# rather than locally. +# +# To my best knowledge, no harm should result from enabling an extension +# that isn't actually used in the file/project. —@neongreen +language_extensions: + - BangPatterns + - ConstraintKinds + - DataKinds + - DefaultSignatures + - DeriveDataTypeable + - DeriveGeneric + - FlexibleContexts + - FlexibleInstances + - FunctionalDependencies + - GADTs + - GeneralizedNewtypeDeriving + - LambdaCase + - MultiParamTypeClasses + - MultiWayIf + - NoImplicitPrelude + - OverloadedStrings + - PolyKinds + - RecordWildCards + - ScopedTypeVariables + - StandaloneDeriving + - TemplateHaskell + - TupleSections + - TypeApplications + - TypeFamilies + - ViewPatterns diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 0000000..72f3347 --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,3 @@ +# Changelog for log-classifier + +## Unreleased changes diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e037c72 --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +Copyright Author name here (c) 2018 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Author name here nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b632c46 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# log-classifier diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/app/Main.hs b/app/Main.hs new file mode 100644 index 0000000..cb655e3 --- /dev/null +++ b/app/Main.hs @@ -0,0 +1,6 @@ +module Main where + +import Zendesk + +main :: IO () +main = runZendeskMain diff --git a/fetch-nixpkgs.nix b/fetch-nixpkgs.nix new file mode 100644 index 0000000..becc075 --- /dev/null +++ b/fetch-nixpkgs.nix @@ -0,0 +1,4 @@ +let + spec = builtins.fromJSON (builtins.readFile ./nixpkgs-src.json); +in + import ./fetchNixpkgs.nix spec diff --git a/fetchNixpkgs.nix b/fetchNixpkgs.nix new file mode 100644 index 0000000..6978965 --- /dev/null +++ b/fetchNixpkgs.nix @@ -0,0 +1,41 @@ +{ rev # The Git revision of nixpkgs to fetch +, sha256 # The SHA256 of the downloaded data +, sha256unpacked +, system ? builtins.currentSystem # This is overridable if necessary +}: + +if 0 <= builtins.compareVersions builtins.nixVersion "1.12" +then + builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; + sha256 = sha256unpacked; + } +else + (rec { + tarball = import { + url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; + inherit sha256; + }; + + builtin-paths = import ; + + script = builtins.toFile "nixpkgs-unpacker" '' + "$coreutils/mkdir" "$out" + cd "$out" + "$gzip" --decompress < "$tarball" | "$tar" -x --strip-components=1 + ''; + + nixpkgs = builtins.derivation { + name = "nixpkgs-${builtins.substring 0 6 rev}"; + + builder = builtins.storePath builtin-paths.shell; + + args = [ script ]; + + inherit tarball system; + + tar = builtins.storePath builtin-paths.tar; + gzip = builtins.storePath builtin-paths.gzip; + coreutils = builtins.storePath builtin-paths.coreutils; + }; + }).nixpkgs diff --git a/lib.nix b/lib.nix new file mode 100644 index 0000000..d58eb9c --- /dev/null +++ b/lib.nix @@ -0,0 +1,19 @@ +let + # Allow overriding pinned nixpkgs for debugging purposes via cardano_pkgs + fetchNixPkgs = let try = builtins.tryEval ; + in if try.success + then builtins.trace "using host " try.value + else import ./fetch-nixpkgs.nix; + + maybeEnv = env: default: + let + result = builtins.getEnv env; + in if result != "" + then result + else default; + + pkgs = import fetchNixPkgs {}; + lib = pkgs.lib; +in lib // (rec { + inherit fetchNixPkgs; +}) diff --git a/log-classifier.cabal b/log-classifier.cabal new file mode 100644 index 0000000..c910fa9 --- /dev/null +++ b/log-classifier.cabal @@ -0,0 +1,103 @@ +-- This file has been generated from package.yaml by hpack version 0.20.0. +-- +-- see: https://github.com/sol/hpack +-- +-- hash: ccf6237cef81dc21f25e3efdca48f9e04e5c47ee8ad73f59acf1a8357d3a7f88 + +name: log-classifier +version: 0.1.0.0 +description: Please see the README on Github at +homepage: https://github.com/githubuser/log-classifier#readme +bug-reports: https://github.com/githubuser/log-classifier/issues +author: Author name here +maintainer: example@example.com +copyright: 2018 Author name here +license: BSD3 +license-file: LICENSE +build-type: Simple +cabal-version: >= 1.10 + +extra-source-files: + ChangeLog.md + README.md + +source-repository head + type: git + location: https://github.com/githubuser/log-classifier + +library + hs-source-dirs: + src + build-depends: + aeson + , array + , attoparsec + , base >=4.7 && <5 + , bytestring + , containers + , http-conduit + , mtl + , reflection + , regex-tdfa + , text + , zip-archive + exposed-modules: + Classify + Lib + LogAnalysis.Classifier + LogAnalysis.KnowledgeCSVParser + LogAnalysis.Types + Regex + Types + Util + Zendesk + other-modules: + Paths_log_classifier + default-language: Haskell2010 + +executable log-classifier-exe + main-is: Main.hs + hs-source-dirs: + app + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: + aeson + , array + , attoparsec + , base >=4.7 && <5 + , bytestring + , containers + , http-conduit + , log-classifier + , mtl + , reflection + , regex-tdfa + , text + , zip-archive + other-modules: + Paths_log_classifier + default-language: Haskell2010 + +test-suite log-classifier-test + type: exitcode-stdio-1.0 + main-is: Spec.hs + hs-source-dirs: + test + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: + aeson + , array + , attoparsec + , base >=4.7 && <5 + , bytestring + , containers + , http-conduit + , log-classifier + , mtl + , reflection + , regex-tdfa + , text + , zip-archive + other-modules: + Paths_log_classifier + default-language: Haskell2010 diff --git a/nixpkgs-src.json b/nixpkgs-src.json new file mode 100644 index 0000000..8dba749 --- /dev/null +++ b/nixpkgs-src.json @@ -0,0 +1,5 @@ +{ + "rev": "5c09cdc187b014143302551e62d4973b5bf52814", + "sha256": "1qzba4apgm9v1vnvmar89b1g9h2z741daiimrc0d3idxv1q97im0", + "sha256unpacked": "1qzba4apgm9v1vnvmar89b1g9h2z741daiimrc0d3idxv1q97im0" +} diff --git a/package.yaml b/package.yaml new file mode 100644 index 0000000..5c08b19 --- /dev/null +++ b/package.yaml @@ -0,0 +1,59 @@ +name: log-classifier +version: 0.1.0.0 +github: "githubuser/log-classifier" +license: BSD3 +author: "Author name here" +maintainer: "example@example.com" +copyright: "2018 Author name here" + +extra-source-files: +- README.md +- ChangeLog.md + +# Metadata used when publishing your package +# synopsis: Short description of your package +# category: Web + +# To avoid duplicated efforts in documentation and dealing with the +# complications of embedding Haddock markup inside cabal files, it is +# common to point users to the README.md file. +description: Please see the README on Github at + +dependencies: +- base >= 4.7 && < 5 +- zip-archive +- regex-tdfa +- reflection +- aeson +- http-conduit +- attoparsec +- bytestring +- containers +- text +- mtl +- array + +library: + source-dirs: src + +executables: + log-classifier-exe: + main: Main.hs + source-dirs: app + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - log-classifier + +tests: + log-classifier-test: + main: Spec.hs + source-dirs: test + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - log-classifier diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..7fe2033 --- /dev/null +++ b/shell.nix @@ -0,0 +1,18 @@ +with import ((import ./lib.nix).fetchNixPkgs) { }; + +let + hsPkgs = haskell.packages.ghc822; +in + haskell.lib.buildStackProject { + name = "log-classifier"; + ghc = hsPkgs.ghc; + buildInputs = [ + zlib unzip openssh autoreconfHook openssl + gmp rocksdb git bsdiff ncurses + hsPkgs.happy hsPkgs.cpphs lzma + perl bash + # cabal-install and stack pull in lots of dependencies on OSX so skip them + # See https://github.com/NixOS/nixpkgs/issues/21200 + ] ++ (lib.optionals stdenv.isLinux [ cabal-install stack ]) + ++ (lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Cocoa CoreServices libcxx libiconv ])); + } diff --git a/Classify.hs b/src/Classify.hs similarity index 100% rename from Classify.hs rename to src/Classify.hs diff --git a/src/Lib.hs b/src/Lib.hs new file mode 100644 index 0000000..2b221f8 --- /dev/null +++ b/src/Lib.hs @@ -0,0 +1,8 @@ +module Lib + ( someFunc + ) where + + +-- TODO(ks): Here we want to import the functionality we require in cardano-report-server. +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/LogAnalysis/Classifier.hs b/src/LogAnalysis/Classifier.hs similarity index 100% rename from LogAnalysis/Classifier.hs rename to src/LogAnalysis/Classifier.hs diff --git a/LogAnalysis/KnowledgeCSVParser.hs b/src/LogAnalysis/KnowledgeCSVParser.hs similarity index 100% rename from LogAnalysis/KnowledgeCSVParser.hs rename to src/LogAnalysis/KnowledgeCSVParser.hs diff --git a/LogAnalysis/Types.hs b/src/LogAnalysis/Types.hs similarity index 100% rename from LogAnalysis/Types.hs rename to src/LogAnalysis/Types.hs diff --git a/Regex.hs b/src/Regex.hs similarity index 100% rename from Regex.hs rename to src/Regex.hs diff --git a/Types.hs b/src/Types.hs similarity index 100% rename from Types.hs rename to src/Types.hs diff --git a/Util.hs b/src/Util.hs similarity index 86% rename from Util.hs rename to src/Util.hs index fcc255b..3370bbf 100644 --- a/Util.hs +++ b/src/Util.hs @@ -18,8 +18,10 @@ tshow = T.pack . show extractLogsFromZip :: Int -> LBS.ByteString -> Either String [LBS.ByteString] extractLogsFromZip numberOfFiles file = do zipMap <- readZip file -- Read File - let extractedLogs = Map.elems $ Map.take numberOfFiles zipMap -- Extract selected logs + let extractedLogs = Map.elems $ mTake numberOfFiles zipMap -- Extract selected logs return extractedLogs + where + mTake n = Map.fromDistinctAscList . take n . Map.toAscList readZip :: LBS.ByteString -> Either String (Map FilePath LBS.ByteString) readZip rawzip = case Zip.toArchiveOrFail rawzip of @@ -29,4 +31,4 @@ readZip rawzip = case Zip.toArchiveOrFail rawzip of finishProcessing :: Zip.Archive -> Map FilePath LBS.ByteString finishProcessing = Map.fromList . map handleEntry . Zip.zEntries handleEntry :: Zip.Entry -> (FilePath, LBS.ByteString) - handleEntry entry = (Zip.eRelativePath entry, Zip.fromEntry entry) \ No newline at end of file + handleEntry entry = (Zip.eRelativePath entry, Zip.fromEntry entry) diff --git a/Zendesk.hs b/src/Zendesk.hs similarity index 98% rename from Zendesk.hs rename to src/Zendesk.hs index 74f4672..e03dd03 100644 --- a/Zendesk.hs +++ b/src/Zendesk.hs @@ -2,9 +2,10 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} -module Main - ( main - ) where +module Zendesk where + -- module Main + -- ( main + -- ) where import Control.Monad (guard) import Control.Monad.Reader (ReaderT, ask, runReaderT, MonadReader) @@ -70,7 +71,8 @@ newtype App a = App (ReaderT Config IO a) , Functor , Monad , MonadReader Config - , MonadIO) + , MonadIO + ) runApp :: App a -> Config -> IO a runApp (App a) = runReaderT a @@ -89,8 +91,8 @@ tokenPath = "token" assignToPath :: FilePath assignToPath = "assign_to" -main :: IO () -main = do +runZendeskMain :: IO () +runZendeskMain = do putStrLn "Welcome to Zendesk classifier!" token <- B8.readFile tokenPath -- Zendesk token assignto <- B8.readFile assignToPath -- Select assignee @@ -170,7 +172,7 @@ printTicketCountMessage tickets email = do sortTickets :: [TicketInfo] -> [(Text, Int)] sortTickets ts = let extractedTags = foldr (\TicketInfo{..} acc -> ticketTags <> acc) [] ts -- Extract tags from tickets - filteredTags = filter (`notElem` ["s3", "s2", "cannot-sync", "closed-by-merge", + filteredTags = filter (`notElem` ["s3", "s2", "cannot-sync", "closed-by-merge", "web_widget", "analyzed-by-script"]) extractedTags -- Filter tags groupByTags :: [ Text ] -> [(Text, Int)] groupByTags ts = map (\l@(x:xs) -> (x, length l)) (group $ sort ts) -- Group them diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..1e820dc --- /dev/null +++ b/stack.yaml @@ -0,0 +1,70 @@ +# This file was automatically generated by 'stack init' +# +# Some commonly used options have been documented as comments in this file. +# For advanced use and comprehensive documentation of the format, please see: +# https://docs.haskellstack.org/en/stable/yaml_configuration/ + +# Resolver to choose a 'specific' stackage snapshot or a compiler version. +# A snapshot resolver dictates the compiler version and the set of packages +# to be used for project dependencies. For example: +# +# resolver: lts-3.5 +# resolver: nightly-2015-09-21 +# resolver: ghc-7.10.2 +# resolver: ghcjs-0.1.0_ghc-7.10.2 +# resolver: +# name: custom-snapshot +# location: "./custom-snapshot.yaml" + +resolver: lts-11.2 + +# User packages to be built. +# Various formats can be used as shown in the example below. +# +# packages: +# - some-directory +# - https://example.com/foo/bar/baz-0.0.2.tar.gz +# - location: +# git: https://github.com/commercialhaskell/stack.git +# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# extra-dep: true +# subdirs: +# - auto-update +# - wai +# +# A package marked 'extra-dep: true' will only be built if demanded by a +# non-dependency (i.e. a user package), and its test suites and benchmarks +# will not be run. This is useful for tweaking upstream packages. +packages: +- . +# Dependency packages to be pulled from upstream that are not in the resolver +# (e.g., acme-missiles-0.3) +# extra-deps: [] + +# Override default flag values for local packages and extra-deps +# flags: {} + +# Extra package databases containing global packages +# extra-package-dbs: [ ] + +nix: + shell-file: shell.nix + +# Control whether we use the GHC we find on the path +# system-ghc: true +# +# Require a specific version of stack, using version ranges +# require-stack-version: -any # Default +# require-stack-version: ">=1.6" +# +# Override the architecture used by stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor diff --git a/test/Spec.hs b/test/Spec.hs new file mode 100644 index 0000000..cd4753f --- /dev/null +++ b/test/Spec.hs @@ -0,0 +1,2 @@ +main :: IO () +main = putStrLn "Test suite not yet implemented"