What are existing batteries-included project scaffolds?

Does anyone know of an opinionated project scaffold for Haskell (to quickly create a new project)? I’m familiar with summoner, but in a feature request thread, it’s explained that summoner’s goal is to not be too opinionated, which leaves many manual steps to get a complete project.

In my mind, a complete scaffold would include:

  • create a single cabal file with:
    • a library component, if requested
    • an executable component, if requested
    • a test component
  • uses a modern prelude
  • cabal build succeeds with no errors/warnings
  • cabal test succeeds no errors/warnings/test failures
  • a common testing library is configured. I’d be open to a different opinion on what this should include, but I would suggest:
    • tasty-discover
    • tasty-hspec
  • an example test in the style of the chosen test library
  • opening the project in VSCode with the haskell-language-server works with no errors/warnings
    • autocompletion works
    • inline warnings and errors work

I’ve been trying to document how create a new project like this, and it unfortunately takes over 30 minutes, even using summoner, and given I know all the undocumented gotchas like needing to generate hie.yaml, what the difference between stack and cabal is, and knowing all the libraries I’ll need to pull in.

If would be great if there were a quick way for folks (especially those new to haskell) to create a new project with modern conventions. Any additional thoughts about what other features a basic project scaffold should include and pointers to any existing solutions that solve or partially solve this problem are welcome. Thanks!

5 Likes

All of the above-mentioned features are supported by Summoner except the custom testing library. And, even with Summoner you can already specify additional custom files to create/copy from other places using the .summoner.toml file. So you can specify the content of a testing file somewhere, and it will be automatically added during the creation. The only thing you would miss is the specification of a dependency in the .cabal file, but I guess it should be possible to implement one more config option in Summoner, so in your config you can specify something like this:

extraDependencies =
    [ { stanza = "test", library = "tasty ^>= 1.4" }
    ]

So, the ideal project will be just Summoner + some custom opinionated configs. The tool can remain non-opinionated in many areas, if it allows creating opinionated and customizable configs :wink:

If we were going to add testing libraries by default, we would add hspec and hedgehog as we use them in all our projects. But we do understand that different people have different defaults. That’s why we are so focused on configurable settings.

Regarding times, creating a simple project with Summoner is instant using the --non-interactive flag:

$ summon new my-project --non-interactive

We usually spend about 1 minute creating the project in TUI, as we add a description, choose a license, adding relude and selecting stanzas, CIs, and GHCs.

There is an issue about the automatic generation of the .hie.yaml file:

If you have any thoughts about it, feel free to share under the issue in comments :slightly_smiling_face:

Also, I don’t think that you need to document the difference between Cabal and Stack, because Summoner supports both, and you can just choose whichever you’re more comfortable with.

6 Likes

As a beginner, I can tell you that choosing custom preludes, stack or cabal, or anything like that BEFORE I start my project is quite intimidating. those are not things that newcomers know about and are really specific to haskell.

it definitely sounds like something productive for people that already know about all of that, but for new haskallers it would be great to have something like @avh4 is suggesting. No questions asked upfront (but maybe make it easy to add extra features after starting the project, for more experienced users).

2 Likes

@georgesboris I see your point. Though, as a beginner, you don’t need to choose an alternative prelude. And you can skip the rest as well.

As I mentioned before, the following command can create a simple project with reasonable defaults quite suitable for Haskell beginners (which you can always adjust later), so you don’t need to worry about answering any questions:

$ summon new my-project-name --non-interactive

I don’t think this is the matter of tools features, but rather the general advertisement and promotion of known and recommend ways to scaffold projects. As maintainers of Summoner, not much we can do in this area. We are already doing our best and spending a lot of time to write documentation, implement features and answer users questions.

6 Likes