Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract dynamic variables from Haskell source code files #25

Closed
vaclavsvejcar opened this issue Mar 22, 2020 · 5 comments
Closed

Extract dynamic variables from Haskell source code files #25

vaclavsvejcar opened this issue Mar 22, 2020 · 5 comments
Assignees
Labels
feature New feature or request
Milestone

Comments

@vaclavsvejcar
Copy link
Owner

vaclavsvejcar commented Mar 22, 2020

Goal of this task is to support extracting extra dynamic template variables for Haskell source code files, which would singinicantly simplify work with Haddock module headers.

The Problem

Imagine following template file for Haskell source code files:

{-|
Module      : MODULE NAME ???
Description : SHORT MODULE DESCRIPTION ???
Copyright   : (c) {{ year }} {{ author }}
License     : BSD-3
Maintainer  : {{ email }}
Stability   : experimental
Portability : POSIX

LONG MODULE DESCRIPTION ???
-}

Current version of Headroom will fill in the static variables, such as year and author since those are same for all source code files, but there's no way to define variable values such as Haskell module name or Haddock description, as these differs file by file. This is fine when header is added to the file, as you need to fill these by hand, but when you try to replace this header with Headroom, it will overwrite your hand-written fields again with initial values.

The Solution

This task adds functionality that will support extracting Haskell module name and selected fields from Haddock module header, from the currently processed Haskell source code file. If no such Haddock module is present (i.e. adding header for very first time), you'll need to fill these by hand, but next time you use Headroom to replace header, it will correctly extract and fill these variables from already present header.

In order to apply these changes, header example from above will change to:

{-|
Module      : {{{ _haskell_module_name }}}
Description : {{{ _haskell_module_shortdesc }}}
Copyright   : (c) {{ year }} {{ author }}
License     : BSD-3
Maintainer  : {{ email }}
Stability   : experimental
Portability : POSIX

{{{ _haskell_module_longdesc }}}
-}

where:

  • _haskell_module_name - name of the Haskell module
  • _haskell_module_longdesc - long description of Haddock module
  • _haskell_module_shortdesc - Description field of Haddock module header
@vaclavsvejcar vaclavsvejcar added the research Some research must be done before implementation label Mar 22, 2020
@chshersh
Copy link

chshersh commented Mar 24, 2020

Thanks for writing this project! That would be a really nice feature!

I've tried to run headroom on summoner and here is the diff:

diff --git a/summoner-cli/src/Summoner/License.hs b/summoner-cli/src/Summoner/License.hs
index 1afb6ac..e61a0e5 100644
--- a/summoner-cli/src/Summoner/License.hs
+++ b/summoner-cli/src/Summoner/License.hs
@@ -1,12 +1,14 @@
-{- |
-Copyright: (c) 2017-2020 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
-
-Data types that represent license names and license content and functions
-to work with them.
+{-|
+Module      : MODULE_NAME
+Description : SHORT_DESC
+Copyright   : (c) 2020 Kowainik
+License     : MIT
+Maintainer  : xrom.xkov@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+LONG_DESC
 -}

You can notice that it completely removes the top-level module comment, and this makes the tool unusable at the moment.

@vaclavsvejcar
Copy link
Owner Author

@chshersh Thank you for your feedback! If I understand correctly your problem, you'd like to keep the very top Haddock module comment untouched by Headroom and instead Headroom should put somewhere second comment containing that license text only? Because right now the built in Haskell support actually renders the top level module Haddock comment, with the license mentioned on the License row (as you can see in the diff). Question is then, what should be the default behaviour, do we want to keep only one comment, which will serve as both Haddock module and license comment, or do we want to manage two different comments, where Headroom will ignore the Haddock one and manage its own license comment placed somewhere below? Do you have any opinion on this?

@chshersh
Copy link

@vaclavsvejcar I'd like to have a single top-level Haddock comment which contains both license information and top-level Haddock. Licensing information renders nicely on Hackage, so I'd like to keep it. At the same time, I don't want to have the same information duplicated in the module. So in the best case, it would be nice if Headroom could recognize existing top-level Haddock and update it.

To be more precise, a diff like below would be the most desirable:

diff --git a/summoner-cli/src/Summoner/License.hs b/summoner-cli/src/Summoner/License.hs
index 1afb6ac..e61a0e5 100644
--- a/summoner-cli/src/Summoner/License.hs
+++ b/summoner-cli/src/Summoner/License.hs
@@ -1,12 +1,14 @@
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Copyright               : (c) 2017-2020 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>

Ability to specify/ignore the Stability and Portability (and other fields) would be nice as well.

@vaclavsvejcar
Copy link
Owner Author

vaclavsvejcar commented Mar 25, 2020

@chshersh Speaking about the Stability and Portability fields, you can do this right now by adding them to your haskell.mustache template (either the generated one or custom one) so you can have:

Template

{-|
Copyright               : (c) {{ year }} {{ author }}
SPDX-License-Identifier : MPL-2.0
Maintainer              : {{ email }}
Stability               : {{ stability }}
Portability             : {{ portability}}
-}

YAML config

variables:
  year: "2017-2020"
  author: Kowainik
  email: "Kowainik <xrom.xkov@gmail.com>"
  portability: POSIX
  stability: stable

But to your main point - right now, the current logic for replacing headers is unfortunately pretty dumb and works in these steps:

  1. correct file type is detected (Haskell in this case)
  2. selected implementation (Headroom.Header.Impl.Haskell) check if any license header is present and if yes, returns the integer with number of lines from the file start that contains the license header (this is the dumb part)
  3. That number of lines is drop at the beginning of the file, new license header is generated using the correct template file and variables from YAML file and this one is pasted that the very first line of the file.

So not only that Headroom cannot do any partial replacements of existing license header, it also cannot work with license headers that are in between the code, not before any code (I think this will be issue for #28). Unfortunately for Haskell the situation is more complex than for many other languages (Java, Scala), where the license header is usually just dummy very first comment of the source code file.

Surely I'm willing to fix/extend/enhance this detection logic, but haven't yet found any nice generic approach that would cover at least these requirements:

  • detect template that is not at the beginning of the file (any code precedes it)
  • partial replacement of the template / extracting fields from old template that would be placed into the new one

@vaclavsvejcar vaclavsvejcar self-assigned this Mar 31, 2020
@vaclavsvejcar vaclavsvejcar added this to To do in Headroom Next via automation Mar 31, 2020
@vaclavsvejcar vaclavsvejcar added this to the 0.2.0.0 milestone Mar 31, 2020
@vaclavsvejcar vaclavsvejcar added the feature New feature or request label Mar 31, 2020
@vaclavsvejcar vaclavsvejcar modified the milestones: 0.2.0.0, 0.2.1.0, 0.2.2.0 Apr 20, 2020
@vaclavsvejcar vaclavsvejcar removed this from the 0.2.2.0 milestone Apr 30, 2020
@vaclavsvejcar vaclavsvejcar changed the title Support for content-aware templates Support for content-aware templates for Haskell file type May 18, 2020
@vaclavsvejcar vaclavsvejcar removed the research Some research must be done before implementation label May 18, 2020
@vaclavsvejcar vaclavsvejcar added this to the v0.2.3.0 milestone May 18, 2020
@vaclavsvejcar vaclavsvejcar changed the title Support for content-aware templates for Haskell file type Extract template variables from Haskell source code files May 21, 2020
@vaclavsvejcar vaclavsvejcar changed the title Extract template variables from Haskell source code files Extract dynamic variables from Haskell source code files May 21, 2020
vaclavsvejcar added a commit that referenced this issue May 24, 2020
- allow default values to be set in user-defined configuration
- allow variable values to contain templates
- code improvements, introduce 'Variables' data type
@vaclavsvejcar vaclavsvejcar moved this from To do to In progress in Headroom Next May 25, 2020
@vaclavsvejcar
Copy link
Owner Author

Implemented and released as part of v0.3.0.0.

Headroom Next automation moved this from In progress to Done Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
Headroom Next
  
Done
Development

No branches or pull requests

2 participants