vaclavsvejcar / headroom

©️ Manager for license headers in source code files.
https://doc.norcane.com/headroom/latest/
BSD 3-Clause "New" or "Revised" License
48 stars 3 forks source link

Add support for Rust language #34

Closed vaclavsvejcar closed 4 years ago

vaclavsvejcar commented 4 years ago

Goal of this task is to add support for Rust language source files to Headroom.

mheinzel commented 4 years ago

Thanks for looking into this!

An idea to consider for for supporting different languages would be to not put any notion of specific languages into headroom's source code, but let it be pure config. This way, instead of having to change type definitions in headroom itself (+ makeing a new release etc.), end users themselves can just add a few lines of configuration and it's done.

I think this is also how it is done in licensure for example.

I had a look into the source code and have some ideas for it could work, feel free to ignore if you have others: This could involve turning HeadersConfig into something like a Map Language HeaderConfig, where Language is just a (newtyped) string. HeaderConfig already seem to contain the information about which file extensions they should be applied to, so instead of finding the right FileType for an extension and mapping that to a HeaderConfig again, you could find the right HeaderConfig directly.

Probably needs a bit of thought about how to keep supporting a default config, but making it both extensible (adding another language) and overridable (e.g. invoking the Haskell formatter also for .hsc files, which would actually be something we need at Wire).

I'm happy to discuss potential designs for this if you want, just ping me if there's anything you would like to ask or talk about. :slightly_smiling_face:

vaclavsvejcar commented 4 years ago

@mheinzel Thanks for sharing your ideas. Absolutely got the idea of making Headroom codebase unaware of supported file types and having everything defined in the YAML file, as that would make adding new language a matter of few moments, without need to change codebase of Headroom and waiting for next release. On the other hand, I also had some plans to make Headroom smarter in a way that it would be able to extract some variables from parsed file, which could be reused for rendering license header from template, as described in #25. For example in case of Haskell sources, this would allow the possibility that Headroom would automatically fill the module name into the Haddock module description template, as shown below:

Template file:

{-|
Module      : {{ __haskell_module }}
Description : SHORT_DESC
-}

Source file BEFORE running Headroom:

{-# LANGUAGE OverloadedStrings #-}
module Foo.Bar where

foo :: String
foo = undefined

Source file AFTER running Headroom:

{-|
Module      : Foo.Bar
Description : SHORT_DESC
-}
{-# LANGUAGE OverloadedStrings #-}
module Foo.Bar where

foo :: String
foo = undefined

Unfortunatelly cannot see any way how to combine these two approaches. What do you think about this functionality btw?

mheinzel commented 4 years ago

Ah, in that case it makes sense to have knowledge about some blessed languages in the tool itself (unless you make these per-file variables configurable too, e.g. via regexes, but that sounds messy).

I don't have a usecase for this personally (except the Haddock module header, which I currently don't use), but it seems like it could be useful for others.

vaclavsvejcar commented 4 years ago

@mheinzel Thanks to all changes done in #28, I can now add support for Rust to upcoming 0.2.0.0 release. But since I'm not familiar with Rust, I have no idea if there's some best practive/recommendation on which comment style (// vs /* */) to use for such license headers. Do you know if there's such guidelines? Headroom can support both for sure, but I need to chose one of them as default configuration.

mheinzel commented 4 years ago

I'm not sure either, I've seen both. I'd just pick one and people can luckily override it easily.

vaclavsvejcar commented 4 years ago

@mheinzel I've added initial support for Rust, default configuration expects block comment /* */ so you might want to use this custom configuration for the wire-server project:

rust:
  margin-after: 1
  margin-before: 1
  line-comment:
    prefixed-by: "//"

Unfortunate thing is that with replace mode, this configuration can cause that Headroom will also eat documentation comments starting with //!. I'm not yet decided if this should be handled on Headroom side (e.g. by allowing regular expressions in put-after/put-before and prefixed-by).

mheinzel commented 4 years ago

I tested the Rust support and it worked perfectly on wire-server. :+1:

For our usecase, Headroom now seems to be a drop-in replacement for licensure. Once a new release is on Hackage, I will suggest switching to that.

Headroom will also eat documentation comments starting with //!

In most cases, this could probably be solved by put-before: "//!", or not?

vaclavsvejcar commented 4 years ago

I tested the Rust support and it worked perfectly on wire-server. :+1:

Awesome, thanks for confirmation. Now I need to cleanup the code base, finish the documentation (as lot of things changed since 0.1.3.0) and do some testing, after that I'll release the final 0.2.0.0, hopefully in next few more days.

vaclavsvejcar commented 4 years ago

@mheinzel Today I released the final version 0.2.0.0 and it's available on hackage. Thanks for your help & ideas regarding new features in this release!