diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6024fa..b742948 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,13 +15,14 @@ jobs: strategy: matrix: stack-yaml: - - stack-nightly.yaml # ghc-9.4 - - stack.yaml # ghc-9.2 + - stack-nightly.yaml # ghc-9.4 + - stack.yaml # ghc-9.4 + - stack-lts-19.6.yaml # ghc-9.2 - stack-lts-18.28.yaml # ghc-8.10 - stack-lts-16.31.yaml # ghc-8.8 fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: freckle/stack-action@v4 with: stack-yaml: ${{ matrix.stack-yaml }} @@ -29,7 +30,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: haskell/actions/hlint-setup@v2 - uses: haskell/actions/hlint-run@v2 with: diff --git a/.restyled.yaml b/.restyled.yaml new file mode 100644 index 0000000..be7a0c0 --- /dev/null +++ b/.restyled.yaml @@ -0,0 +1,4 @@ +restylers: + - fourmolu + - "!stylish-haskell" + - "*" diff --git a/.stylish-haskell.yaml b/.stylish-haskell.yaml deleted file mode 100644 index 627f80a..0000000 --- a/.stylish-haskell.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- -steps: - - simple_align: - cases: false - top_level_patterns: false - records: false - - imports: - align: none - list_align: after_alias - pad_module_names: false - long_list_align: new_line_multiline - empty_list_align: right_after - list_padding: 2 - separate_lists: false - space_surround: false - - language_pragmas: - style: vertical - align: false - remove_redundant: false - - trailing_whitespace: {} -columns: 80 -newline: native -# For multi-package repositories this default-extensions must be set manually. -# For single package repos it can be inferred from the cabal file. -cabal: true diff --git a/brittany.yaml b/brittany.yaml deleted file mode 100644 index 086c336..0000000 --- a/brittany.yaml +++ /dev/null @@ -1,70 +0,0 @@ ---- -conf_debug: - dconf_roundtrip_exactprint_only: false - dconf_dump_bridoc_simpl_par: false - dconf_dump_ast_unknown: false - dconf_dump_bridoc_simpl_floating: false - dconf_dump_config: false - dconf_dump_bridoc_raw: false - dconf_dump_bridoc_final: false - dconf_dump_bridoc_simpl_alt: false - dconf_dump_bridoc_simpl_indent: false - dconf_dump_annotations: false - dconf_dump_bridoc_simpl_columns: false - dconf_dump_ast_full: false -conf_forward: - options_ghc: - - -XBangPatterns - - -XDataKinds - - -XDeriveAnyClass - - -XDeriveFoldable - - -XDeriveFunctor - - -XDeriveGeneric - - -XDeriveLift - - -XDeriveTraversable - - -XDerivingStrategies - - -XFlexibleContexts - - -XFlexibleInstances - - -XGADTs - - -XGeneralizedNewtypeDeriving - - -XLambdaCase - - -XMultiParamTypeClasses - - -XNoImplicitPrelude - - -XNoMonomorphismRestriction - - -XOverloadedStrings - - -XRankNTypes - - -XRecordWildCards - - -XScopedTypeVariables - - -XStandaloneDeriving - - -XTypeApplications - - -XTypeFamilies -conf_errorHandling: - econf_ExactPrintFallback: ExactPrintFallbackModeInline - econf_Werror: false - econf_omit_output_valid_check: false - econf_produceOutputOnErrors: false -conf_preprocessor: - ppconf_CPPMode: CPPModeAbort - ppconf_hackAroundIncludes: false -conf_obfuscate: false -conf_roundtrip_exactprint_only: false -conf_version: 1 -conf_layout: - lconfig_reformatModulePreamble: true - lconfig_altChooser: - tag: AltChooserBoundedSearch - contents: 3 - lconfig_allowSingleLineExportList: false - lconfig_importColumn: 60 - lconfig_hangingTypeSignature: false - lconfig_importAsColumn: 50 - lconfig_alignmentLimit: 1 - lconfig_indentListSpecial: true - lconfig_indentAmount: 2 - lconfig_alignmentBreakOnMultiline: true - lconfig_cols: 80 - lconfig_indentPolicy: IndentPolicyLeft - lconfig_indentWhereSpecial: true - lconfig_columnAlignMode: - tag: ColumnAlignModeDisabled - contents: 0.7 diff --git a/example/Hspec.hs b/example/Hspec.hs index f17fd4f..ccfd0e5 100644 --- a/example/Hspec.hs +++ b/example/Hspec.hs @@ -4,7 +4,7 @@ module Main import Prelude -import Module.Discover.Run (Module(..), run) +import Module.Discover.Run (Module (..), run) import System.Environment (getArgs) main :: IO () @@ -12,11 +12,11 @@ main = getArgs >>= run (pure . make) Nothing make :: [Module] -> String make modules = - unlines - $ ["module Main (main) where", ""] - <> (toQualifiedImport <$> modules) - <> ["", "main :: IO ()", "main = do"] - <> (toMainCall <$> modules) + unlines $ + ["module Main (main) where", ""] + <> (toQualifiedImport <$> modules) + <> ["", "main :: IO ()", "main = do"] + <> (toMainCall <$> modules) toQualifiedImport :: Module -> String toQualifiedImport Module {..} = "import qualified " <> moduleFullName diff --git a/example/Main.hs b/example/Main.hs index 862a28e..b7ade9e 100644 --- a/example/Main.hs +++ b/example/Main.hs @@ -4,7 +4,7 @@ module Main import Prelude -import Module.Discover.Run (Module(..), run) +import Module.Discover.Run (Module (..), run) import System.Environment (getArgs) main :: IO () @@ -12,11 +12,11 @@ main = getArgs >>= run (pure . make) Nothing make :: [Module] -> String make modules = - unlines - $ ["module Main (main) where", ""] - <> (toQualifiedImport <$> modules) - <> ["", "main :: IO ()", "main = do"] - <> (toMainCall <$> modules) + unlines $ + ["module Main (main) where", ""] + <> (toQualifiedImport <$> modules) + <> ["", "main :: IO ()", "main = do"] + <> (toMainCall <$> modules) toQualifiedImport :: Module -> String toQualifiedImport Module {..} = diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e7aabe9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,234 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "freckle": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs-23-05": "nixpkgs-23-05", + "nixpkgs-master-2023-05-06": "nixpkgs-master-2023-05-06", + "nixpkgs-master-2023-07-18": "nixpkgs-master-2023-07-18", + "nixpkgs-master-2023-09-15": "nixpkgs-master-2023-09-15", + "nixpkgs-stable": "nixpkgs-stable", + "nixpkgs-stable-2023-07-25": "nixpkgs-stable-2023-07-25", + "nixpkgs-unstable-2023-10-21": "nixpkgs-unstable-2023-10-21" + }, + "locked": { + "dir": "main", + "lastModified": 1705043131, + "narHash": "sha256-Hnf2wzvXBKznYEll8JILCQv4uAKfWTWU7jberWKE8RE=", + "owner": "freckle", + "repo": "flakes", + "rev": "9b0b7889579451fa3f45bf43dedd35d8c55e2617", + "type": "github" + }, + "original": { + "dir": "main", + "owner": "freckle", + "repo": "flakes", + "type": "github" + } + }, + "nixpkgs-23-05": { + "locked": { + "lastModified": 1701362232, + "narHash": "sha256-GVdzxL0lhEadqs3hfRLuj+L1OJFGiL/L7gCcelgBlsw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d2332963662edffacfddfad59ff4f709dde80ffe", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-master-2023-05-06": { + "locked": { + "lastModified": 1683392273, + "narHash": "sha256-pZTuxvcuDeBG+vvE1zczNyEUzlPbzXVh8Ed45Fzo+tQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "16b3b0c53b1ee8936739f8c588544e7fcec3fc60", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "16b3b0c53b1ee8936739f8c588544e7fcec3fc60", + "type": "github" + } + }, + "nixpkgs-master-2023-07-18": { + "locked": { + "lastModified": 1689680872, + "narHash": "sha256-brNix2+ihJSzCiKwLafbyejrHJZUP0Fy6z5+xMOC27M=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "08700de174bc6235043cb4263b643b721d936bdb", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "08700de174bc6235043cb4263b643b721d936bdb", + "type": "github" + } + }, + "nixpkgs-master-2023-09-15": { + "locked": { + "lastModified": 1694760568, + "narHash": "sha256-3G07BiXrp2YQKxdcdms22MUx6spc6A++MSePtatCYuI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "46688f8eb5cd6f1298d873d4d2b9cf245e09e88e", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "46688f8eb5cd6f1298d873d4d2b9cf245e09e88e", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1701263465, + "narHash": "sha256-lNXUIlkfyDyp9Ox21hr+wsEf/IBklLvb6bYcyeXbdRc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "50aa30a13c4ab5e7ba282da460a3e3d44e9d0eb3", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable-2023-07-25": { + "locked": { + "lastModified": 1690271650, + "narHash": "sha256-qwdsW8DBY1qH+9luliIH7VzgwvL+ZGI3LZWC0LTiDMI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6dc93f0daec55ee2f441da385aaf143863e3d671", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6dc93f0daec55ee2f441da385aaf143863e3d671", + "type": "github" + } + }, + "nixpkgs-unstable-2023-10-21": { + "locked": { + "lastModified": 1697793076, + "narHash": "sha256-02e7sCuqLtkyRgrZmdOyvAcQTQdcXj+vpyp9bca6cY4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "038b2922be3fc096e1d456f93f7d0f4090628729", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "038b2922be3fc096e1d456f93f7d0f4090628729", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "freckle": "freckle", + "stable": "stable" + } + }, + "stable": { + "locked": { + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..0814ade --- /dev/null +++ b/flake.nix @@ -0,0 +1,66 @@ +{ + inputs = { + stable.url = "github:nixos/nixpkgs/nixos-23.11"; + freckle.url = "github:freckle/flakes?dir=main"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = inputs: inputs.flake-utils.lib.eachDefaultSystem (system: + let + nixpkgsArgs = { inherit system; config = { }; }; + nixpkgs = { + stable = import inputs.stable nixpkgsArgs; + }; + freckle = inputs.freckle.packages.${system}; + freckleLib = inputs.freckle.lib.${system}; + in + rec { + packages = { + cabal = nixpkgs.stable.cabal-install; + + fourmolu = freckle.fourmolu-0-13-x; + + ghc = freckleLib.haskellBundle { + enableHLS = true; + ghcVersion = "ghc-9-4-8"; + packageSelection = p: [ + p.extra + ]; + }; + + hlint = + nixpkgs.stable.haskell.lib.justStaticExecutables + nixpkgs.stable.hlint; + + stack = nixpkgs.stable.writeShellApplication { + name = "stack"; + text = '' + ${nixpkgs.stable.stack}/bin/stack --system-ghc --no-nix "$@" + ''; + } + ; + }; + + devShells.default = nixpkgs.stable.mkShell { + buildInputs = with (nixpkgs.stable); [ + pcre + pcre.dev + zlib + zlib.dev + ]; + + nativeBuildInputs = with (packages); [ + cabal + fourmolu + ghc + hlint + stack + ]; + + LOCALE_ARCHIVE = "${nixpkgs.stable.glibcLocales}/lib/locale/locale-archive"; + + shellHook = '' + export STACK_YAML=stack.yaml + ''; + }; + }); +} diff --git a/fourmolu.yaml b/fourmolu.yaml new file mode 100644 index 0000000..ef571e8 --- /dev/null +++ b/fourmolu.yaml @@ -0,0 +1,15 @@ +indentation: 2 +column-limit: 80 # ignored until v12 / ghc-9.6 +function-arrows: leading +comma-style: leading # default +import-export-style: leading +indent-wheres: false # default +record-brace-space: true +newlines-between-decls: 1 # default +haddock-style: single-line +let-style: mixed +in-style: left-align +single-constraint-parens: never # ignored until v12 / ghc-9.6 +unicode: never # default +respectful: true # default +fixities: [] # default diff --git a/library/Module/Discover/Run.hs b/library/Module/Discover/Run.hs index 49a5a6d..407f293 100644 --- a/library/Module/Discover/Run.hs +++ b/library/Module/Discover/Run.hs @@ -1,6 +1,6 @@ module Module.Discover.Run ( run - , Module(..) + , Module (..) ) where import Prelude @@ -22,16 +22,20 @@ import System.FilePattern.Directory (FilePattern, getDirectoryFiles) import System.IO (hPutStrLn, stderr) run - :: ([Module] -> IO String) -- ^ Output function - -> Maybe FilePattern -- ^ Optional file Pattern - -> [String] -- ^ Processor arguments + :: ([Module] -> IO String) + -- ^ Output function + -> Maybe FilePattern + -- ^ Optional file Pattern + -> [String] + -- ^ Processor arguments -> IO () run output filePattern args = do case args of src : _ : dst : _args -> do let srcDir = takeDirectory src - modules <- fmap (toModule srcDir) - <$> getDirectoryFiles srcDir [fromMaybe "**/*.hs" filePattern] + modules <- + fmap (toModule srcDir) + <$> getDirectoryFiles srcDir [fromMaybe "**/*.hs" filePattern] out <- output modules writeFile dst out _ -> do @@ -39,23 +43,28 @@ run output filePattern args = do exitFailure toModule :: FilePath -> FilePath -> Module -toModule srcDir filePath = Module - { moduleName = dropExtension $ takeFileName filePath - , moduleFullName = toModuleFullName srcDir filePath - , moduleFilePath = srcDir filePath - } +toModule srcDir filePath = + Module + { moduleName = dropExtension $ takeFileName filePath + , moduleFullName = toModuleFullName srcDir filePath + , moduleFilePath = srcDir filePath + } toModuleFullName :: FilePath -> FilePath -> String -toModuleFullName srcDir filePath = +toModuleFullName srcDir = replace [pathSeparator] "." - $ dropExtension - $ joinPath - $ reverse - $ takeWhile (isUpper . head) - $ reverse - $ splitPath - $ srcDir - filePath + . dropExtension + . joinPath + . reverse + . takeWhile (startsWith isUpper) + . reverse + . splitPath + . (srcDir ) + +startsWith :: (a -> Bool) -> [a] -> Bool +startsWith f = \case + [] -> False + x : _ -> f x data Module = Module { moduleName :: String diff --git a/module-discover.cabal b/module-discover.cabal index 351dbc7..4a4f81b 100644 --- a/module-discover.cabal +++ b/module-discover.cabal @@ -1,6 +1,6 @@ cabal-version: 1.18 --- This file has been generated from package.yaml by hpack version 0.34.4. +-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack @@ -63,11 +63,11 @@ library , extra , filepath , filepattern + default-language: Haskell2010 if impl(ghc >= 8.10) ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module if impl(ghc >= 9.2) ghc-options: -Wno-missing-kind-signatures - default-language: Haskell2010 executable module-discover-example main-is: Main.hs @@ -102,11 +102,11 @@ executable module-discover-example build-depends: base <5 , module-discover + default-language: Haskell2010 if impl(ghc >= 8.10) ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module if impl(ghc >= 9.2) ghc-options: -Wno-missing-kind-signatures - default-language: Haskell2010 executable module-discover-hspec main-is: Hspec.hs @@ -141,11 +141,11 @@ executable module-discover-hspec build-depends: base <5 , module-discover + default-language: Haskell2010 if impl(ghc >= 8.10) ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module if impl(ghc >= 9.2) ghc-options: -Wno-missing-kind-signatures - default-language: Haskell2010 test-suite spec type: exitcode-stdio-1.0 @@ -185,8 +185,8 @@ test-suite spec base <5 , hspec , module-discover + default-language: Haskell2010 if impl(ghc >= 8.10) ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module if impl(ghc >= 9.2) ghc-options: -Wno-missing-kind-signatures - default-language: Haskell2010 diff --git a/stack-lts-19.6.yaml b/stack-lts-19.6.yaml new file mode 100644 index 0000000..82823e4 --- /dev/null +++ b/stack-lts-19.6.yaml @@ -0,0 +1 @@ +resolver: lts-19.6 diff --git a/stack-lts-19.6.yaml.lock b/stack-lts-19.6.yaml.lock new file mode 100644 index 0000000..d8ab114 --- /dev/null +++ b/stack-lts-19.6.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + size: 618876 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/6.yaml + sha256: fb634b19f31da06684bb07ce02a20c75a3162138f279b388905b03ebd57bb50f + original: lts-19.6 diff --git a/stack.yaml b/stack.yaml index 82823e4..377040a 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1 +1 @@ -resolver: lts-19.6 +resolver: lts-21.25 diff --git a/stack.yaml.lock b/stack.yaml.lock index d8ab114..f823d29 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - size: 618876 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/6.yaml - sha256: fb634b19f31da06684bb07ce02a20c75a3162138f279b388905b03ebd57bb50f - original: lts-19.6 + sha256: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd + size: 640086 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml + original: lts-21.25 diff --git a/tests/Module/Discover/RunSpec.hs b/tests/Module/Discover/RunSpec.hs index c21e607..55ae02a 100644 --- a/tests/Module/Discover/RunSpec.hs +++ b/tests/Module/Discover/RunSpec.hs @@ -17,26 +17,26 @@ spec = do ["example-dir/Some/Module/", "[unused]", "/tmp/foo.txt"] (read <$> readFile "/tmp/foo.txt") `shouldReturn` [ Module - { moduleName = "Name" - , moduleFullName = "Some.Module.Name" - , moduleFilePath = "example-dir/Some/Module/Name.hs" - } + { moduleName = "Name" + , moduleFullName = "Some.Module.Name" + , moduleFilePath = "example-dir/Some/Module/Name.hs" + } , Module - { moduleName = "Name1" - , moduleFullName = "Some.Module.Path.Name1" - , moduleFilePath = - "example-dir/Some/Module/Path/Name1.hs" - } + { moduleName = "Name1" + , moduleFullName = "Some.Module.Path.Name1" + , moduleFilePath = + "example-dir/Some/Module/Path/Name1.hs" + } , Module - { moduleName = "Name2" - , moduleFullName = "Some.Module.Path.Name2" - , moduleFilePath = - "example-dir/Some/Module/Path/Name2.hs" - } + { moduleName = "Name2" + , moduleFullName = "Some.Module.Path.Name2" + , moduleFilePath = + "example-dir/Some/Module/Path/Name2.hs" + } , Module - { moduleName = "Name3" - , moduleFullName = "Some.Module.Path.Name3" - , moduleFilePath = - "example-dir/Some/Module/Path/Name3.hs" - } + { moduleName = "Name3" + , moduleFullName = "Some.Module.Path.Name3" + , moduleFilePath = + "example-dir/Some/Module/Path/Name3.hs" + } ]