headroom 0.3.0.0 → 0.3.1.0
raw patch · 33 files changed
+1092/−480 lines, 33 filesdep ~QuickCheckdep ~aesondep ~data-default-classPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: QuickCheck, aeson, data-default-class, doctest, either, file-embed, hspec, microlens, microlens-th, mustache, optparse-applicative, pcre-heavy, pcre-light, rio, template-haskell, time, yaml
API changes (from Hackage documentation)
- Headroom.Configuration.Types: cExcludedPathsL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) ((:::) p_aoQ6 [Regex])
- Headroom.Configuration.Types: cHeaderFnConfigsL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) (HeaderFnConfigs p_aoQ6)
- Headroom.Configuration.Types: cLicenseHeadersL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) (HeadersConfig p_aoQ6)
- Headroom.Configuration.Types: cRunModeL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) ((:::) p_aoQ6 RunMode)
- Headroom.Configuration.Types: cSourcePathsL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) ((:::) p_aoQ6 [FilePath])
- Headroom.Configuration.Types: cTemplateSourceL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) ((:::) p_aoQ6 TemplateSource)
- Headroom.Configuration.Types: cVariablesL :: forall p_aoQ6. Lens' (Configuration p_aoQ6) Variables
- Headroom.Configuration.Types: hfcConfigL :: forall p_aoQZ c_aoR0 c_aqSE. Lens (HeaderFnConfig p_aoQZ c_aoR0) (HeaderFnConfig p_aoQZ c_aqSE) (c_aoR0 p_aoQZ) (c_aqSE p_aoQZ)
- Headroom.Configuration.Types: hfcEnabledL :: forall p_aoQZ c_aoR0. Lens' (HeaderFnConfig p_aoQZ c_aoR0) ((:::) p_aoQZ Bool)
- Headroom.Configuration.Types: hfcsUpdateCopyrightL :: forall p_aoQW p_aqU6. Lens (HeaderFnConfigs p_aoQW) (HeaderFnConfigs p_aqU6) (HeaderFnConfig p_aoQW UpdateCopyrightConfig) (HeaderFnConfig p_aqU6 UpdateCopyrightConfig)
- Headroom.Configuration.Types: instance GHC.Classes.Eq (c 'Headroom.Configuration.Types.Complete) => GHC.Classes.Eq (Headroom.Configuration.Types.CtHeaderFnConfig c)
- Headroom.Configuration.Types: instance GHC.Classes.Eq (c 'Headroom.Configuration.Types.Partial) => GHC.Classes.Eq (Headroom.Configuration.Types.PtHeaderFnConfig c)
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.CtConfiguration
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.CtHeaderConfig
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.CtHeaderFnConfigs
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.CtHeadersConfig
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.CtUpdateCopyrightConfig
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.PtConfiguration
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.PtHeaderConfig
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.PtHeaderFnConfigs
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.PtHeadersConfig
- Headroom.Configuration.Types: instance GHC.Classes.Eq Headroom.Configuration.Types.PtUpdateCopyrightConfig
- Headroom.Configuration.Types: instance GHC.Show.Show (c 'Headroom.Configuration.Types.Complete) => GHC.Show.Show (Headroom.Configuration.Types.CtHeaderFnConfig c)
- Headroom.Configuration.Types: instance GHC.Show.Show (c 'Headroom.Configuration.Types.Partial) => GHC.Show.Show (Headroom.Configuration.Types.PtHeaderFnConfig c)
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.CtConfiguration
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.CtHeaderConfig
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.CtHeaderFnConfigs
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.CtHeadersConfig
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.CtUpdateCopyrightConfig
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.PtConfiguration
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.PtHeaderConfig
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.PtHeaderFnConfigs
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.PtHeadersConfig
- Headroom.Configuration.Types: instance GHC.Show.Show Headroom.Configuration.Types.PtUpdateCopyrightConfig
- Headroom.Configuration.Types: uccSelectedAuthorsL :: forall p_aoR1 p_aqRS. Lens (UpdateCopyrightConfig p_aoR1) (UpdateCopyrightConfig p_aqRS) ((:::) p_aoR1 (Maybe (NonEmpty Text))) ((:::) p_aqRS (Maybe (NonEmpty Text)))
- Headroom.FileSupport.Types: fiFileTypeL :: Lens' FileInfo FileType
- Headroom.FileSupport.Types: fiHeaderConfigL :: Lens' FileInfo CtHeaderConfig
- Headroom.FileSupport.Types: fiHeaderPosL :: Lens' FileInfo (Maybe (Int, Int))
- Headroom.FileSupport.Types: fiVariablesL :: Lens' FileInfo Variables
- Headroom.FileSystem: createDirectory :: MonadIO m => FilePath -> m ()
- Headroom.FileSystem: doesFileExist :: MonadIO m => FilePath -> m Bool
- Headroom.FileSystem: getCurrentDirectory :: MonadIO m => m FilePath
- Headroom.HeaderFn: ceCurrentYearL :: Lens' ConfiguredEnv CurrentYear
- Headroom.HeaderFn: ceHeaderFnConfigsL :: Lens' ConfiguredEnv CtHeaderFnConfigs
- Headroom.HeaderFn: ceUpdateCopyrightModeL :: Lens' ConfiguredEnv UpdateCopyrightMode
+ Headroom.Command.Init: [envFileSystem] :: Env -> FileSystem (RIO Env)
+ Headroom.Command.Init: instance Headroom.Data.Has.Has (Headroom.FileSystem.FileSystem (RIO.Prelude.RIO.RIO Headroom.Command.Init.Env)) Headroom.Command.Init.Env
+ Headroom.Command.Run: instance Headroom.Data.Has.Has (Headroom.FileSystem.FileSystem (RIO.Prelude.RIO.RIO Headroom.Command.Run.Env)) Headroom.Command.Run.Env
+ Headroom.Configuration.Types: [hscPureScript] :: HeadersConfig -> HeaderConfig p
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.Configuration 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.Configuration 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.HeaderConfig 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.HeaderConfig 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.HeaderFnConfigs 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.HeaderFnConfigs 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.HeadersConfig 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.HeadersConfig 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.UpdateCopyrightConfig 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (Headroom.Configuration.Types.UpdateCopyrightConfig 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (c 'Headroom.Configuration.Types.Complete) => GHC.Classes.Eq (Headroom.Configuration.Types.HeaderFnConfig 'Headroom.Configuration.Types.Complete c)
+ Headroom.Configuration.Types: instance GHC.Classes.Eq (c 'Headroom.Configuration.Types.Partial) => GHC.Classes.Eq (Headroom.Configuration.Types.HeaderFnConfig 'Headroom.Configuration.Types.Partial c)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.Configuration 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.Configuration 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.HeaderConfig 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.HeaderConfig 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.HeaderFnConfigs 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.HeaderFnConfigs 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.HeadersConfig 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.HeadersConfig 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.UpdateCopyrightConfig 'Headroom.Configuration.Types.Complete)
+ Headroom.Configuration.Types: instance GHC.Show.Show (Headroom.Configuration.Types.UpdateCopyrightConfig 'Headroom.Configuration.Types.Partial)
+ Headroom.Configuration.Types: instance GHC.Show.Show (c 'Headroom.Configuration.Types.Complete) => GHC.Show.Show (Headroom.Configuration.Types.HeaderFnConfig 'Headroom.Configuration.Types.Complete c)
+ Headroom.Configuration.Types: instance GHC.Show.Show (c 'Headroom.Configuration.Types.Partial) => GHC.Show.Show (Headroom.Configuration.Types.HeaderFnConfig 'Headroom.Configuration.Types.Partial c)
+ Headroom.Data.Regex: compileUnsafe :: Text -> Regex
+ Headroom.Embedded.TH: embedConfigFile :: Q Exp
+ Headroom.Embedded.TH: embedDefaultConfig :: Q Exp
+ Headroom.Embedded.TH: embedTemplate :: LicenseType -> FileType -> Q Exp
+ Headroom.Ext.Java: extractPackageName :: Text -> Maybe Text
+ Headroom.Ext.Java: extractVariables :: CtHeaderConfig -> Maybe TemplateMeta -> Maybe (Int, Int) -> Text -> Variables
+ Headroom.Ext.PureScript: extractVariables :: CtHeaderConfig -> Maybe TemplateMeta -> Maybe (Int, Int) -> Text -> Variables
+ Headroom.FileSystem: FileSystem :: CreateDirectoryFn m -> DoesFileExistFn m -> FindFilesFn m -> FindFilesByExtsFn m -> FindFilesByTypesFn m -> GetCurrentDirectoryFn m -> ListFilesFn m -> LoadFileFn m -> FileSystem m
+ Headroom.FileSystem: [fsCreateDirectory] :: FileSystem m -> CreateDirectoryFn m
+ Headroom.FileSystem: [fsDoesFileExist] :: FileSystem m -> DoesFileExistFn m
+ Headroom.FileSystem: [fsFindFilesByExts] :: FileSystem m -> FindFilesByExtsFn m
+ Headroom.FileSystem: [fsFindFilesByTypes] :: FileSystem m -> FindFilesByTypesFn m
+ Headroom.FileSystem: [fsFindFiles] :: FileSystem m -> FindFilesFn m
+ Headroom.FileSystem: [fsGetCurrentDirectory] :: FileSystem m -> GetCurrentDirectoryFn m
+ Headroom.FileSystem: [fsListFiles] :: FileSystem m -> ListFilesFn m
+ Headroom.FileSystem: [fsLoadFile] :: FileSystem m -> LoadFileFn m
+ Headroom.FileSystem: data FileSystem m
+ Headroom.FileSystem: mkFileSystem :: MonadIO m => FileSystem m
+ Headroom.FileSystem: type CreateDirectoryFn m = FilePath " path of new directory" -> m () " /IO/ action result"
+ Headroom.FileSystem: type DoesFileExistFn m = FilePath " path to check" -> m Bool " whether the given path is existing file"
+ Headroom.FileSystem: type FindFilesByExtsFn m = FilePath " path to search" -> [Text] " list of file extensions (without dot)" -> m [FilePath] " list of found files"
+ Headroom.FileSystem: type FindFilesByTypesFn m = CtHeadersConfig " configuration of license headers" -> [FileType] " list of file types" -> FilePath " path to search" -> m [FilePath] " list of found files"
+ Headroom.FileSystem: type FindFilesFn m = FilePath " path to search" -> (FilePath -> Bool) " predicate to match filename" -> m [FilePath] " found files"
+ Headroom.FileSystem: type GetCurrentDirectoryFn m = m FilePath
+ Headroom.FileSystem: type ListFilesFn m = FilePath " path to search" -> m [FilePath] " list of found files"
+ Headroom.FileSystem: type LoadFileFn m = FilePath " file path" -> m Text " file content"
+ Headroom.FileType.Types: PureScript :: FileType
- Headroom.Command.Init: Env :: !LogFunc -> !CommandInitOptions -> !Paths -> Env
+ Headroom.Command.Init: Env :: LogFunc -> FileSystem (RIO Env) -> CommandInitOptions -> Paths -> Env
- Headroom.Command.Init: Paths :: !FilePath -> !FilePath -> Paths
+ Headroom.Command.Init: Paths :: FilePath -> FilePath -> Paths
- Headroom.Command.Init: [envInitOptions] :: Env -> !CommandInitOptions
+ Headroom.Command.Init: [envInitOptions] :: Env -> CommandInitOptions
- Headroom.Command.Init: [envLogFunc] :: Env -> !LogFunc
+ Headroom.Command.Init: [envLogFunc] :: Env -> LogFunc
- Headroom.Command.Init: [envPaths] :: Env -> !Paths
+ Headroom.Command.Init: [envPaths] :: Env -> Paths
- Headroom.Command.Init: [pConfigFile] :: Paths -> !FilePath
+ Headroom.Command.Init: [pConfigFile] :: Paths -> FilePath
- Headroom.Command.Init: [pTemplatesDir] :: Paths -> !FilePath
+ Headroom.Command.Init: [pTemplatesDir] :: Paths -> FilePath
- Headroom.Command.Init: doesAppConfigExist :: (HasLogFunc env, Has Paths env) => RIO env Bool
+ Headroom.Command.Init: doesAppConfigExist :: (HasLogFunc env, Has (FileSystem (RIO env)) env, Has Paths env) => RIO env Bool
- Headroom.Command.Run: loadTemplateFiles :: HasLogFunc env => [FilePath] -> RIO env (Map FileType TemplateType)
+ Headroom.Command.Run: loadTemplateFiles :: (Has (FileSystem (RIO env)) env, HasLogFunc env) => [FilePath] -> RIO env (Map FileType TemplateType)
- Headroom.Configuration.Types: BlockComment :: !Text -> !Text -> HeaderSyntax
+ Headroom.Configuration.Types: BlockComment :: Text -> Text -> HeaderSyntax
- Headroom.Configuration.Types: CkFileExtensions :: !FileType -> ConfigurationKey
+ Headroom.Configuration.Types: CkFileExtensions :: FileType -> ConfigurationKey
- Headroom.Configuration.Types: CkHeaderSyntax :: !FileType -> ConfigurationKey
+ Headroom.Configuration.Types: CkHeaderSyntax :: FileType -> ConfigurationKey
- Headroom.Configuration.Types: CkMarginAfter :: !FileType -> ConfigurationKey
+ Headroom.Configuration.Types: CkMarginAfter :: FileType -> ConfigurationKey
- Headroom.Configuration.Types: CkMarginBefore :: !FileType -> ConfigurationKey
+ Headroom.Configuration.Types: CkMarginBefore :: FileType -> ConfigurationKey
- Headroom.Configuration.Types: CkPutAfter :: !FileType -> ConfigurationKey
+ Headroom.Configuration.Types: CkPutAfter :: FileType -> ConfigurationKey
- Headroom.Configuration.Types: CkPutBefore :: !FileType -> ConfigurationKey
+ Headroom.Configuration.Types: CkPutBefore :: FileType -> ConfigurationKey
- Headroom.Configuration.Types: Configuration :: !p ::: RunMode -> !p ::: [FilePath] -> !p ::: [Regex] -> !p ::: TemplateSource -> !Variables -> !HeadersConfig p -> !HeaderFnConfigs p -> Configuration (p :: Phase)
+ Headroom.Configuration.Types: Configuration :: (p ::: RunMode) -> (p ::: [FilePath]) -> (p ::: [Regex]) -> (p ::: TemplateSource) -> Variables -> HeadersConfig p -> HeaderFnConfigs p -> Configuration
- Headroom.Configuration.Types: GenLicense :: !(LicenseType, FileType) -> GenMode
+ Headroom.Configuration.Types: GenLicense :: (LicenseType, FileType) -> GenMode
- Headroom.Configuration.Types: HeaderConfig :: !p ::: [Text] -> !p ::: Int -> !p ::: Int -> !p ::: [Regex] -> !p ::: [Regex] -> !p ::: HeaderSyntax -> HeaderConfig (p :: Phase)
+ Headroom.Configuration.Types: HeaderConfig :: (p ::: [Text]) -> (p ::: Int) -> (p ::: Int) -> (p ::: [Regex]) -> (p ::: [Regex]) -> (p ::: HeaderSyntax) -> HeaderConfig
- Headroom.Configuration.Types: HeaderFnConfig :: !p ::: Bool -> !c p -> HeaderFnConfig (p :: Phase) c
+ Headroom.Configuration.Types: HeaderFnConfig :: (p ::: Bool) -> c p -> HeaderFnConfig c
- Headroom.Configuration.Types: HeaderFnConfigs :: !HeaderFnConfig p UpdateCopyrightConfig -> HeaderFnConfigs (p :: Phase)
+ Headroom.Configuration.Types: HeaderFnConfigs :: HeaderFnConfig p UpdateCopyrightConfig -> HeaderFnConfigs
- Headroom.Configuration.Types: HeadersConfig :: !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> !HeaderConfig p -> HeadersConfig (p :: Phase)
+ Headroom.Configuration.Types: HeadersConfig :: HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeaderConfig p -> HeadersConfig
- Headroom.Configuration.Types: LineComment :: !Text -> HeaderSyntax
+ Headroom.Configuration.Types: LineComment :: Text -> HeaderSyntax
- Headroom.Configuration.Types: MissingConfiguration :: !ConfigurationKey -> ConfigurationError
+ Headroom.Configuration.Types: MissingConfiguration :: ConfigurationKey -> ConfigurationError
- Headroom.Configuration.Types: UpdateCopyrightConfig :: !p ::: Maybe (NonEmpty Text) -> UpdateCopyrightConfig (p :: Phase)
+ Headroom.Configuration.Types: UpdateCopyrightConfig :: (p ::: Maybe (NonEmpty Text)) -> UpdateCopyrightConfig
- Headroom.Configuration.Types: [cExcludedPaths] :: Configuration (p :: Phase) -> !p ::: [Regex]
+ Headroom.Configuration.Types: [cExcludedPaths] :: Configuration -> p ::: [Regex]
- Headroom.Configuration.Types: [cHeaderFnConfigs] :: Configuration (p :: Phase) -> !HeaderFnConfigs p
+ Headroom.Configuration.Types: [cHeaderFnConfigs] :: Configuration -> HeaderFnConfigs p
- Headroom.Configuration.Types: [cLicenseHeaders] :: Configuration (p :: Phase) -> !HeadersConfig p
+ Headroom.Configuration.Types: [cLicenseHeaders] :: Configuration -> HeadersConfig p
- Headroom.Configuration.Types: [cRunMode] :: Configuration (p :: Phase) -> !p ::: RunMode
+ Headroom.Configuration.Types: [cRunMode] :: Configuration -> p ::: RunMode
- Headroom.Configuration.Types: [cSourcePaths] :: Configuration (p :: Phase) -> !p ::: [FilePath]
+ Headroom.Configuration.Types: [cSourcePaths] :: Configuration -> p ::: [FilePath]
- Headroom.Configuration.Types: [cTemplateSource] :: Configuration (p :: Phase) -> !p ::: TemplateSource
+ Headroom.Configuration.Types: [cTemplateSource] :: Configuration -> p ::: TemplateSource
- Headroom.Configuration.Types: [cVariables] :: Configuration (p :: Phase) -> !Variables
+ Headroom.Configuration.Types: [cVariables] :: Configuration -> Variables
- Headroom.Configuration.Types: [hcFileExtensions] :: HeaderConfig (p :: Phase) -> !p ::: [Text]
+ Headroom.Configuration.Types: [hcFileExtensions] :: HeaderConfig -> p ::: [Text]
- Headroom.Configuration.Types: [hcHeaderSyntax] :: HeaderConfig (p :: Phase) -> !p ::: HeaderSyntax
+ Headroom.Configuration.Types: [hcHeaderSyntax] :: HeaderConfig -> p ::: HeaderSyntax
- Headroom.Configuration.Types: [hcMarginAfter] :: HeaderConfig (p :: Phase) -> !p ::: Int
+ Headroom.Configuration.Types: [hcMarginAfter] :: HeaderConfig -> p ::: Int
- Headroom.Configuration.Types: [hcMarginBefore] :: HeaderConfig (p :: Phase) -> !p ::: Int
+ Headroom.Configuration.Types: [hcMarginBefore] :: HeaderConfig -> p ::: Int
- Headroom.Configuration.Types: [hcPutAfter] :: HeaderConfig (p :: Phase) -> !p ::: [Regex]
+ Headroom.Configuration.Types: [hcPutAfter] :: HeaderConfig -> p ::: [Regex]
- Headroom.Configuration.Types: [hcPutBefore] :: HeaderConfig (p :: Phase) -> !p ::: [Regex]
+ Headroom.Configuration.Types: [hcPutBefore] :: HeaderConfig -> p ::: [Regex]
- Headroom.Configuration.Types: [hfcConfig] :: HeaderFnConfig (p :: Phase) c -> !c p
+ Headroom.Configuration.Types: [hfcConfig] :: HeaderFnConfig c -> c p
- Headroom.Configuration.Types: [hfcEnabled] :: HeaderFnConfig (p :: Phase) c -> !p ::: Bool
+ Headroom.Configuration.Types: [hfcEnabled] :: HeaderFnConfig c -> p ::: Bool
- Headroom.Configuration.Types: [hfcsUpdateCopyright] :: HeaderFnConfigs (p :: Phase) -> !HeaderFnConfig p UpdateCopyrightConfig
+ Headroom.Configuration.Types: [hfcsUpdateCopyright] :: HeaderFnConfigs -> HeaderFnConfig p UpdateCopyrightConfig
- Headroom.Configuration.Types: [hscC] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscC] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscCpp] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscCpp] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscCss] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscCss] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscHaskell] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscHaskell] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscHtml] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscHtml] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscJava] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscJava] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscJs] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscJs] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscRust] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscRust] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscScala] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscScala] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [hscShell] :: HeadersConfig (p :: Phase) -> !HeaderConfig p
+ Headroom.Configuration.Types: [hscShell] :: HeadersConfig -> HeaderConfig p
- Headroom.Configuration.Types: [uccSelectedAuthors] :: UpdateCopyrightConfig (p :: Phase) -> !p ::: Maybe (NonEmpty Text)
+ Headroom.Configuration.Types: [uccSelectedAuthors] :: UpdateCopyrightConfig -> p ::: Maybe (NonEmpty Text)
- Headroom.Configuration.Types: type CtConfiguration = Configuration 'Complete
+ Headroom.Configuration.Types: type CtConfiguration = Configuration 'Complete
- Headroom.Configuration.Types: type CtHeaderConfig = HeaderConfig 'Complete
+ Headroom.Configuration.Types: type CtHeaderConfig = HeaderConfig 'Complete
- Headroom.Configuration.Types: type CtHeaderFnConfig c = HeaderFnConfig 'Complete c
+ Headroom.Configuration.Types: type CtHeaderFnConfig c = HeaderFnConfig 'Complete c
- Headroom.Configuration.Types: type CtHeaderFnConfigs = HeaderFnConfigs 'Complete
+ Headroom.Configuration.Types: type CtHeaderFnConfigs = HeaderFnConfigs 'Complete
- Headroom.Configuration.Types: type CtHeadersConfig = HeadersConfig 'Complete
+ Headroom.Configuration.Types: type CtHeadersConfig = HeadersConfig 'Complete
- Headroom.Configuration.Types: type CtUpdateCopyrightConfig = UpdateCopyrightConfig 'Complete
+ Headroom.Configuration.Types: type CtUpdateCopyrightConfig = UpdateCopyrightConfig 'Complete
- Headroom.Configuration.Types: type PtConfiguration = Configuration 'Partial
+ Headroom.Configuration.Types: type PtConfiguration = Configuration 'Partial
- Headroom.Configuration.Types: type PtHeaderConfig = HeaderConfig 'Partial
+ Headroom.Configuration.Types: type PtHeaderConfig = HeaderConfig 'Partial
- Headroom.Configuration.Types: type PtHeaderFnConfig c = HeaderFnConfig 'Partial c
+ Headroom.Configuration.Types: type PtHeaderFnConfig c = HeaderFnConfig 'Partial c
- Headroom.Configuration.Types: type PtHeaderFnConfigs = HeaderFnConfigs 'Partial
+ Headroom.Configuration.Types: type PtHeaderFnConfigs = HeaderFnConfigs 'Partial
- Headroom.Configuration.Types: type PtHeadersConfig = HeadersConfig 'Partial
+ Headroom.Configuration.Types: type PtHeadersConfig = HeadersConfig 'Partial
- Headroom.Configuration.Types: type PtUpdateCopyrightConfig = UpdateCopyrightConfig 'Partial
+ Headroom.Configuration.Types: type PtUpdateCopyrightConfig = UpdateCopyrightConfig 'Partial
- Headroom.FileSystem: findFiles :: MonadIO m => FilePath -> (FilePath -> Bool) -> m [FilePath]
+ Headroom.FileSystem: findFiles :: MonadIO m => FindFilesFn m
- Headroom.FileSystem: findFilesByExts :: MonadIO m => FilePath -> [Text] -> m [FilePath]
+ Headroom.FileSystem: findFilesByExts :: MonadIO m => FindFilesByExtsFn m
- Headroom.FileSystem: findFilesByTypes :: MonadIO m => CtHeadersConfig -> [FileType] -> FilePath -> m [FilePath]
+ Headroom.FileSystem: findFilesByTypes :: MonadIO m => FindFilesByTypesFn m
- Headroom.FileSystem: listFiles :: MonadIO m => FilePath -> m [FilePath]
+ Headroom.FileSystem: listFiles :: MonadIO m => ListFilesFn m
- Headroom.FileSystem: loadFile :: MonadIO m => FilePath -> m Text
+ Headroom.FileSystem: loadFile :: MonadIO m => LoadFileFn m
Files
- CHANGELOG.md +6/−0
- embedded/default-config.yaml +14/−4
- embedded/license/apache2/purescript.mustache +14/−0
- embedded/license/bsd3/purescript.mustache +27/−0
- embedded/license/gpl2/purescript.mustache +17/−0
- embedded/license/gpl3/purescript.mustache +15/−0
- embedded/license/mit/purescript.mustache +22/−0
- embedded/license/mpl2/purescript.mustache +6/−0
- headroom.cabal +159/−156
- src/Headroom/Command/Init.hs +34/−14
- src/Headroom/Command/Run.hs +46/−27
- src/Headroom/Configuration.hs +18/−15
- src/Headroom/Configuration/Types.hs +65/−81
- src/Headroom/Data/Regex.hs +11/−4
- src/Headroom/Embedded.hs +73/−64
- src/Headroom/Embedded/TH.hs +64/−0
- src/Headroom/Ext.hs +10/−4
- src/Headroom/Ext/Haskell.hs +1/−1
- src/Headroom/Ext/Java.hs +68/−0
- src/Headroom/Ext/PureScript.hs +47/−0
- src/Headroom/FileSupport.hs +7/−4
- src/Headroom/FileSupport/Types.hs +0/−9
- src/Headroom/FileSystem.hs +145/−43
- src/Headroom/FileType.hs +11/−10
- src/Headroom/FileType/Types.hs +2/−0
- src/Headroom/HeaderFn.hs +10/−9
- src/Headroom/Meta.hs +0/−1
- test-data/code-samples/purescript/full.purs +9/−0
- test/Headroom/Command/InitSpec.hs +58/−12
- test/Headroom/Command/RunSpec.hs +49/−22
- test/Headroom/Ext/JavaSpec.hs +36/−0
- test/Headroom/Ext/PureScriptSpec.hs +30/−0
- test/Headroom/ExtSpec.hs +18/−0
CHANGELOG.md view
@@ -1,6 +1,12 @@ # Changelog All notable changes to this project will be documented in this file. +## 0.3.1.0 (released 2020-08-18)+- [#48] Decouple IO actions for easier testing+- [#53] Add support for _PureScript_ source code files+- [#54] Extract _dynamic variables_ from _Java_ source code files+- Bump _LTS Haskell_ to `16.10`+ ## 0.3.0.0 (released 2020-06-28) - [#25] Extract _dynamic variables_ from Haskell source code files - [#29] Add _dynamic variable_ for current year and add support for updating years
embedded/default-config.yaml view
@@ -45,6 +45,8 @@ _haskell_module_portability: "!!! INSERT MODULE PORTABILITY !!!" _haskell_module_longdesc: "!!! INSERT MODULE LONG DESCRIPTION !!!" _haskell_module_shortdesc: "!!! INSERT MODULE SHORT DESCRIPTION !!!"+ _java_package_name: "!!! UNKNOWN JAVA PACKAGE NAME !!!"+ _purescript_module_name: "!!! INSERT PURESCRIPT MODULE NAME !!!" ## Allows to change behaviour of license header detection and placement. Such ## configuration is defined for every supported file type, where individual@@ -151,6 +153,16 @@ starts-with: "/*" ends-with: "*/" + ## PureScript configuration+ purescript:+ file-extensions: ["purs"]+ margin-after: 0+ margin-before: 0+ put-after: []+ put-before: ["^module"]+ line-comment:+ prefixed-by: "--"+ ## Rust configuration rust: file-extensions: ["rs"]@@ -183,13 +195,11 @@ line-comment: prefixed-by: "#" - ## Configuration for post-processing license header functions. These functions ## allows to modify/enhance already rendered license headers, e.g. update years ## in copyright statements, etc. Each function can be enabled/disabled using the ## 'enabled' key and eventually customized using the 'config' key. post-process:- ## License header function that updates years in copyright statements in ## rendered license header. If you need to update copyright year only for ## selected author(s), define them in 'selected-authors-only' key, otherwise@@ -198,5 +208,5 @@ update-copyright: enabled: false config:- ## If used, updates copyright statements of selected authors only.- # selected-authors-only: ["John Smith"]+ ## If used, updates copyright statements of selected authors only.+ # selected-authors-only: ["John Smith"]
+ embedded/license/apache2/purescript.mustache view
@@ -0,0 +1,14 @@+-- {{ project }}+-- Copyright {{ year }} {{ author }}+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +-- http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express+-- or implied. See the License for the specific language governing+-- permissions and limitations under the License.
+ embedded/license/bsd3/purescript.mustache view
@@ -0,0 +1,27 @@+-- {{ project }}+-- Copyright (c) {{ year }} {{ author }}+-- All rights reserved.+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are met:+--+-- 1. Redistributions of source code must retain the above copyright notice,+-- this list of conditions and the following disclaimer.+-- 2. 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.+-- 3. Neither the name of copyright holder nor the names of its+-- 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.
+ embedded/license/gpl2/purescript.mustache view
@@ -0,0 +1,17 @@+-- {{ project }}+-- Copyright (c) {{ year }} {{ author }}+-- +-- This program is free software; you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation; either version 2 of the License, or (at+-- your option) any later version.+-- +-- This program is distributed in the hope that it will be useful, but+-- WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU+-- General Public License for more details.+-- +-- You should have received a copy of the GNU General Public License+-- along with this program; if not, write to the Free Software+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307+-- USA.
+ embedded/license/gpl3/purescript.mustache view
@@ -0,0 +1,15 @@+-- {{ project }}+-- Copyright (C) {{ year }} {{ author }}+-- +-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+-- +-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.+-- +-- You should have received a copy of the GNU General Public License+-- along with this program. If not, see http://www.gnu.org/licenses/.
+ embedded/license/mit/purescript.mustache view
@@ -0,0 +1,22 @@+-- The MIT License+--+-- {{ project }}+-- Copyright (c) {{ year }} {{ author }}+--+-- Permission is hereby granted, free of charge, to any person obtaining a copy+-- of this software and associated documentation files (the "Software"), to deal+-- in the Software without restriction, including without limitation the rights+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+-- copies of the Software, and to permit persons to whom the Software is+-- furnished to do so, subject to the following conditions:+--+-- The above copyright notice and this permission notice shall be included in+-- all copies or substantial portions of the Software.+--+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+-- THE SOFTWARE.
+ embedded/license/mpl2/purescript.mustache view
@@ -0,0 +1,6 @@+-- {{ project }}+-- Copyright (c) {{ year }} {{ author }}+--+-- This Source Code Form is subject to the terms of the Mozilla Public+-- License, version 2.0. If a copy of the MPL was not distributed with this+-- file, You can obtain one at http://mozilla.org/MPL/2.0/.
headroom.cabal view
@@ -1,19 +1,24 @@-cabal-version: 2.2-name: headroom-version: 0.3.0.0-license: BSD-3-Clause-license-file: LICENSE-copyright: Copyright (c) 2019-2020 Vaclav Svejcar-maintainer: vaclav.svejcar@gmail.com-author: Vaclav Svejcar-homepage: https://github.com/vaclavsvejcar/headroom-bug-reports: https://github.com/vaclavsvejcar/headroom/issues-synopsis: License Header Manager-description:- Would you like to have nice, up-to-date license/copyright headers in your source code files but hate to manage them by hand? Then Headroom is the right tool for you! Now you can define your license header as Mustache template, put all the variables (such as author's name, year, etc.) into the YAML config file and Headroom will take care to add such license headers to all your source code files.+cabal-version: 2.2 -category: Utils-build-type: Simple+-- This file has been generated from package.yaml by hpack version 0.33.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: f49109b0113a73a61d4c99db85698fd193e3cbc6ffd87671cebaed06bcaa61f4++name: headroom+version: 0.3.1.0+synopsis: License Header Manager+description: Would you like to have nice, up-to-date license/copyright headers in your source code files but hate to manage them by hand? Then Headroom is the right tool for you! Now you can define your license header as Mustache template, put all the variables (such as author's name, year, etc.) into the YAML config file and Headroom will take care to add such license headers to all your source code files.+category: Utils+homepage: https://github.com/vaclavsvejcar/headroom+bug-reports: https://github.com/vaclavsvejcar/headroom/issues+author: Vaclav Svejcar+maintainer: vaclav.svejcar@gmail.com+copyright: Copyright (c) 2019-2020 Vaclav Svejcar+license: BSD-3-Clause+license-file: LICENSE+build-type: Simple extra-source-files: CHANGELOG.md LICENSE@@ -27,6 +32,7 @@ embedded/license/apache2/html.mustache embedded/license/apache2/java.mustache embedded/license/apache2/js.mustache+ embedded/license/apache2/purescript.mustache embedded/license/apache2/rust.mustache embedded/license/apache2/scala.mustache embedded/license/apache2/shell.mustache@@ -37,6 +43,7 @@ embedded/license/bsd3/html.mustache embedded/license/bsd3/java.mustache embedded/license/bsd3/js.mustache+ embedded/license/bsd3/purescript.mustache embedded/license/bsd3/rust.mustache embedded/license/bsd3/scala.mustache embedded/license/bsd3/shell.mustache@@ -47,6 +54,7 @@ embedded/license/gpl2/html.mustache embedded/license/gpl2/java.mustache embedded/license/gpl2/js.mustache+ embedded/license/gpl2/purescript.mustache embedded/license/gpl2/rust.mustache embedded/license/gpl2/scala.mustache embedded/license/gpl2/shell.mustache@@ -57,6 +65,7 @@ embedded/license/gpl3/html.mustache embedded/license/gpl3/java.mustache embedded/license/gpl3/js.mustache+ embedded/license/gpl3/purescript.mustache embedded/license/gpl3/rust.mustache embedded/license/gpl3/scala.mustache embedded/license/gpl3/shell.mustache@@ -67,6 +76,7 @@ embedded/license/mit/html.mustache embedded/license/mit/java.mustache embedded/license/mit/js.mustache+ embedded/license/mit/purescript.mustache embedded/license/mit/rust.mustache embedded/license/mit/scala.mustache embedded/license/mit/shell.mustache@@ -77,6 +87,7 @@ embedded/license/mpl2/html.mustache embedded/license/mpl2/java.mustache embedded/license/mpl2/js.mustache+ embedded/license/mpl2/purescript.mustache embedded/license/mpl2/rust.mustache embedded/license/mpl2/scala.mustache embedded/license/mpl2/shell.mustache@@ -97,6 +108,7 @@ test-data/code-samples/java/sample2.java test-data/code-samples/js/sample1.js test-data/code-samples/js/sample2.js+ test-data/code-samples/purescript/full.purs test-data/code-samples/rust/sample1.rs test-data/code-samples/scala/sample1.scala test-data/code-samples/scala/sample2.scala@@ -109,152 +121,143 @@ test-data/test-traverse/foo/bar/c.html source-repository head- type: git- location: https://github.com/vaclavsvejcar/headroom+ type: git+ location: https://github.com/vaclavsvejcar/headroom library- exposed-modules:- Headroom.Command- Headroom.Command.Gen- Headroom.Command.Init- Headroom.Command.Readers- Headroom.Command.Run- Headroom.Command.Types- Headroom.Command.Utils- Headroom.Configuration- Headroom.Configuration.Types- Headroom.Data.EnumExtra- Headroom.Data.Has- Headroom.Data.Lens- Headroom.Data.Regex- Headroom.Data.TextExtra- Headroom.Embedded- Headroom.Ext- Headroom.Ext.Haskell- Headroom.Ext.Haskell.Haddock- Headroom.FileSupport- Headroom.FileSupport.Types- Headroom.FileSystem- Headroom.FileType- Headroom.FileType.Types- Headroom.HeaderFn- Headroom.HeaderFn.Types- Headroom.HeaderFn.UpdateCopyright- Headroom.Meta- Headroom.Serialization- Headroom.Template- Headroom.Template.Mustache- Headroom.Types- Headroom.UI- Headroom.UI.Progress- Headroom.Variables- Headroom.Variables.Types-- hs-source-dirs: src- other-modules: Paths_headroom- autogen-modules: Paths_headroom- default-language: Haskell2010- ghc-options:- -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities- -Wincomplete-record-updates -Wincomplete-uni-patterns- -Wpartial-fields -Wredundant-constraints- -Werror=incomplete-patterns-- build-depends:- aeson >=1.4.7.1,- base >=4.7 && <5,- data-default-class >=0.1.2.0,- either >=5.0.1.1,- file-embed >=0.0.11.2,- microlens >=0.4.11.2,- microlens-th >=0.4.3.5,- mustache >=2.3.1,- optparse-applicative >=0.15.1.0,- pcre-heavy >=1.0.0.2,- pcre-light >=0.4.1.0,- rio >=0.1.17.0,- template-haskell >=2.15.0.0,- time >=1.9.3,- yaml >=0.11.4.0+ exposed-modules:+ Headroom.Command+ Headroom.Command.Gen+ Headroom.Command.Init+ Headroom.Command.Readers+ Headroom.Command.Run+ Headroom.Command.Types+ Headroom.Command.Utils+ Headroom.Configuration+ Headroom.Configuration.Types+ Headroom.Data.EnumExtra+ Headroom.Data.Has+ Headroom.Data.Lens+ Headroom.Data.Regex+ Headroom.Data.TextExtra+ Headroom.Embedded+ Headroom.Embedded.TH+ Headroom.Ext+ Headroom.Ext.Haskell+ Headroom.Ext.Haskell.Haddock+ Headroom.Ext.Java+ Headroom.Ext.PureScript+ Headroom.FileSupport+ Headroom.FileSupport.Types+ Headroom.FileSystem+ Headroom.FileType+ Headroom.FileType.Types+ Headroom.HeaderFn+ Headroom.HeaderFn.Types+ Headroom.HeaderFn.UpdateCopyright+ Headroom.Meta+ Headroom.Serialization+ Headroom.Template+ Headroom.Template.Mustache+ Headroom.Types+ Headroom.UI+ Headroom.UI.Progress+ Headroom.Variables+ Headroom.Variables.Types+ other-modules:+ Paths_headroom+ autogen-modules:+ Paths_headroom+ hs-source-dirs:+ src+ ghc-options: -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -Werror=incomplete-patterns+ build-depends:+ aeson+ , base >=4.7 && <5+ , data-default-class+ , either+ , file-embed+ , microlens+ , microlens-th+ , mustache+ , optparse-applicative+ , pcre-heavy+ , pcre-light+ , rio+ , template-haskell+ , time+ , yaml+ default-language: Haskell2010 executable headroom- main-is: Main.hs- hs-source-dirs: app- other-modules: Paths_headroom- default-language: Haskell2010- ghc-options:- -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities- -Wincomplete-record-updates -Wincomplete-uni-patterns- -Wpartial-fields -Wredundant-constraints- -Werror=incomplete-patterns -threaded -rtsopts -with-rtsopts=-N-- build-depends:- base >=4.7 && <5,- headroom -any,- optparse-applicative >=0.15.1.0,- rio >=0.1.17.0+ main-is: Main.hs+ other-modules:+ Paths_headroom+ hs-source-dirs:+ app+ ghc-options: -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -Werror=incomplete-patterns -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.7 && <5+ , headroom+ , optparse-applicative+ , rio+ default-language: Haskell2010 test-suite doctest- type: exitcode-stdio-1.0- main-is: Main.hs- hs-source-dirs: doctest- other-modules: Paths_headroom- default-language: Haskell2010- ghc-options:- -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities- -Wincomplete-record-updates -Wincomplete-uni-patterns- -Wpartial-fields -Wredundant-constraints- -Werror=incomplete-patterns-- build-depends:- base >=4.7 && <5,- doctest >=0.16.3,- optparse-applicative >=0.15.1.0,- rio >=0.1.17.0+ type: exitcode-stdio-1.0+ main-is: Main.hs+ other-modules:+ Paths_headroom+ hs-source-dirs:+ doctest+ ghc-options: -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -Werror=incomplete-patterns+ build-depends:+ base >=4.7 && <5+ , doctest+ , optparse-applicative+ , rio+ default-language: Haskell2010 test-suite spec- type: exitcode-stdio-1.0- main-is: Spec.hs- hs-source-dirs: test- other-modules:- Headroom.Command.InitSpec- Headroom.Command.ReadersSpec- Headroom.Command.RunSpec- Headroom.ConfigurationSpec- Headroom.Data.EnumExtraSpec- Headroom.Data.RegexSpec- Headroom.Data.TextExtraSpec- Headroom.Ext.Haskell.HaddockSpec- Headroom.Ext.HaskellSpec- Headroom.ExtSpec- Headroom.FileSupportSpec- Headroom.FileSystemSpec- Headroom.FileTypeSpec- Headroom.HeaderFn.TypesSpec- Headroom.HeaderFn.UpdateCopyrightSpec- Headroom.HeaderFnSpec- Headroom.SerializationSpec- Headroom.Template.MustacheSpec- Headroom.TypesSpec- Headroom.UI.ProgressSpec- Headroom.VariablesSpec- Test.Utils- Paths_headroom-- default-language: Haskell2010- ghc-options:- -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities- -Wincomplete-record-updates -Wincomplete-uni-patterns- -Wpartial-fields -Wredundant-constraints- -Werror=incomplete-patterns-- build-depends:- QuickCheck >=2.13.2,- aeson >=1.4.7.1,- base >=4.7 && <5,- headroom -any,- hspec >=2.7.1,- optparse-applicative >=0.15.1.0,- pcre-light >=0.4.1.0,- rio >=0.1.17.0,- time >=1.9.3+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Headroom.Command.InitSpec+ Headroom.Command.ReadersSpec+ Headroom.Command.RunSpec+ Headroom.ConfigurationSpec+ Headroom.Data.EnumExtraSpec+ Headroom.Data.RegexSpec+ Headroom.Data.TextExtraSpec+ Headroom.Ext.Haskell.HaddockSpec+ Headroom.Ext.HaskellSpec+ Headroom.Ext.JavaSpec+ Headroom.Ext.PureScriptSpec+ Headroom.ExtSpec+ Headroom.FileSupportSpec+ Headroom.FileSystemSpec+ Headroom.FileTypeSpec+ Headroom.HeaderFn.TypesSpec+ Headroom.HeaderFn.UpdateCopyrightSpec+ Headroom.HeaderFnSpec+ Headroom.SerializationSpec+ Headroom.Template.MustacheSpec+ Headroom.TypesSpec+ Headroom.UI.ProgressSpec+ Headroom.VariablesSpec+ Test.Utils+ Paths_headroom+ hs-source-dirs:+ test+ ghc-options: -optP-Wno-nonportable-include-path -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -Werror=incomplete-patterns+ build-depends:+ QuickCheck+ , aeson+ , base >=4.7 && <5+ , headroom+ , hspec+ , optparse-applicative+ , pcre-light+ , rio+ , time+ default-language: Haskell2010
src/Headroom/Command/Init.hs view
@@ -1,9 +1,11 @@ {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-}@@ -45,10 +47,10 @@ , defaultConfig , licenseTemplate )-import Headroom.FileSystem ( createDirectory- , doesFileExist+import Headroom.FileSystem ( FileSystem(..) , fileExtension , findFiles+ , mkFileSystem ) import Headroom.FileType ( fileTypeByExt ) import Headroom.FileType.Types ( FileType(..) )@@ -73,15 +75,16 @@ -- | /RIO/ Environment for the @init@ command. data Env = Env- { envLogFunc :: !LogFunc- , envInitOptions :: !CommandInitOptions- , envPaths :: !Paths+ { envLogFunc :: LogFunc+ , envFileSystem :: FileSystem (RIO Env)+ , envInitOptions :: CommandInitOptions+ , envPaths :: Paths } -- | Paths to various locations of file system. data Paths = Paths- { pConfigFile :: !FilePath- , pTemplatesDir :: !FilePath+ { pConfigFile :: FilePath+ , pTemplatesDir :: FilePath } suffixLenses ''Env@@ -92,6 +95,9 @@ instance Has CommandInitOptions Env where hasLens = envInitOptionsL +instance Has (FileSystem (RIO Env)) Env where+ hasLens = envFileSystemL+ instance Has Paths Env where hasLens = envPathsL @@ -102,7 +108,11 @@ let paths = Paths { pConfigFile = ".headroom.yaml" , pTemplatesDir = "headroom-templates" }- pure $ Env { envLogFunc = logFunc, envInitOptions = opts, envPaths = paths }+ pure $ Env { envLogFunc = logFunc+ , envFileSystem = mkFileSystem+ , envInitOptions = opts+ , envPaths = paths+ } -- | Handler for @init@ command. commandInit :: CommandInitOptions@@ -182,18 +192,28 @@ T.stripEnd . prettyPrintYAML $ M.fromList [(field :: Text, list)] -- | Checks whether application config file already exists.-doesAppConfigExist :: (HasLogFunc env, Has Paths env) => RIO env Bool+doesAppConfigExist :: ( HasLogFunc env+ , Has (FileSystem (RIO env)) env+ , Has Paths env+ )+ => RIO env Bool doesAppConfigExist = do- Paths {..} <- viewL+ FileSystem {..} <- viewL+ Paths {..} <- viewL logInfo "Verifying that there's no existing Headroom configuration..."- doesFileExist pConfigFile+ fsDoesFileExist pConfigFile -- | Creates directory for template files.-makeTemplatesDir :: (HasLogFunc env, Has Paths env) => RIO env ()+makeTemplatesDir :: ( HasLogFunc env+ , Has (FileSystem (RIO env)) env+ , Has Paths env+ )+ => RIO env () makeTemplatesDir = do- Paths {..} <- viewL+ FileSystem {..} <- viewL+ Paths {..} <- viewL logInfo $ "Creating directory for templates in " <> fromString pTemplatesDir- createDirectory pTemplatesDir+ fsCreateDirectory pTemplatesDir --------------------------------- Error Types --------------------------------
src/Headroom/Command/Run.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-}@@ -54,11 +55,12 @@ , PtConfiguration , RunMode(..) , TemplateSource(..)- , cHeaderFnConfigsL ) import Headroom.Data.EnumExtra ( EnumExtra(..) ) import Headroom.Data.Has ( Has(..) )-import Headroom.Data.Lens ( suffixLenses )+import Headroom.Data.Lens ( suffixLenses+ , suffixLensesFor+ ) import Headroom.Data.TextExtra ( mapLines ) import Headroom.Embedded ( defaultConfig , licenseTemplate@@ -70,11 +72,10 @@ , replaceHeader ) import Headroom.FileSupport.Types ( FileInfo(..) )-import Headroom.FileSystem ( excludePaths+import Headroom.FileSystem ( FileSystem(..)+ , excludePaths , fileExtension- , findFilesByExts- , findFilesByTypes- , loadFile+ , mkFileSystem ) import Headroom.FileType ( configByFileType , fileTypeByExt@@ -105,26 +106,29 @@ import qualified RIO.Text as T +suffixLensesFor ["cHeaderFnConfigs"] ''Configuration++ type TemplatesMap = Map FileType (Maybe TemplateMeta, TemplateType) -- | Action to be performed based on the selected 'RunMode'. data RunAction = RunAction- { raProcessed :: !Bool+ { raProcessed :: Bool -- ^ whether the given file was processed- , raFunc :: !(Text -> Text)+ , raFunc :: Text -> Text -- ^ function to process the file- , raProcessedMsg :: !Text+ , raProcessedMsg :: Text -- ^ message to show when file was processed- , raSkippedMsg :: !Text+ , raSkippedMsg :: Text -- ^ message to show when file was skipped } -- | Initial /RIO/ startup environment for the /Run/ command. data StartupEnv = StartupEnv- { envLogFunc :: !LogFunc+ { envLogFunc :: LogFunc -- ^ logging function- , envRunOptions :: !CommandRunOptions+ , envRunOptions :: CommandRunOptions -- ^ options } @@ -132,12 +136,14 @@ -- | Full /RIO/ environment for the /Run/ command. data Env = Env- { envEnv :: !StartupEnv+ { envEnv :: StartupEnv -- ^ startup /RIO/ environment- , envConfiguration :: !CtConfiguration+ , envConfiguration :: CtConfiguration -- ^ application configuration- , envCurrentYear :: !CurrentYear+ , envCurrentYear :: CurrentYear -- ^ current year+ , envFileSystem :: FileSystem (RIO Env)+ -- ^ file system operations } suffixLenses ''Env@@ -169,10 +175,14 @@ instance Has CurrentYear Env where hasLens = envCurrentYearL +instance Has (FileSystem (RIO Env)) Env where+ hasLens = envFileSystemL + env' :: CommandRunOptions -> LogFunc -> IO Env env' opts logFunc = do- let envEnv = StartupEnv { envLogFunc = logFunc, envRunOptions = opts }+ let envEnv = StartupEnv { envLogFunc = logFunc, envRunOptions = opts }+ envFileSystem = mkFileSystem envConfiguration <- runRIO envEnv finalConfiguration envCurrentYear <- currentYear pure Env { .. }@@ -214,13 +224,18 @@ when croDryRun $ logWarn "[!] Running with '--dry-run', no files are changed!" -findSourceFiles :: (Has CtConfiguration env, HasLogFunc env)+findSourceFiles :: ( Has CtConfiguration env+ , Has (FileSystem (RIO env)) env+ , HasLogFunc env+ ) => [FileType] -> RIO env [FilePath] findSourceFiles fileTypes = do Configuration {..} <- viewL+ FileSystem {..} <- viewL logDebug $ "Using source paths: " <> displayShow cSourcePaths- files <- mconcat <$> mapM (findFiles' cLicenseHeaders) cSourcePaths+ files <-+ mconcat <$> mapM (fsFindFilesByTypes cLicenseHeaders fileTypes) cSourcePaths let files' = excludePaths cExcludedPaths files logInfo $ mconcat [ "Found "@@ -230,7 +245,6 @@ , " file(s))" ] pure files'- where findFiles' licenseHeaders = findFilesByTypes licenseHeaders fileTypes processSourceFiles :: ( Has CtConfiguration env@@ -332,23 +346,25 @@ -- | Loads templates from the given paths.-loadTemplateFiles :: (HasLogFunc env)+loadTemplateFiles :: (Has (FileSystem (RIO env)) env, HasLogFunc env) => [FilePath] -- ^ paths to template files -> RIO env (Map FileType TemplateType) -- ^ map of file types and templates loadTemplateFiles paths' = do- paths <- mconcat <$> mapM (`findFilesByExts` extensions) paths'+ FileSystem {..} <- viewL+ paths <- mconcat <$> mapM (`fsFindFilesByExts` extensions) paths' logDebug $ "Using template paths: " <> displayShow paths withTypes <- catMaybes <$> mapM (\p -> fmap (, p) <$> typeOfTemplate p) paths- parsed <- mapM (\(t, p) -> (t, ) <$> load p) withTypes+ parsed <- mapM+ (\(t, p) ->+ (t, ) <$> ((T.strip <$> fsLoadFile p) >>= parseTemplate (Just $ T.pack p))+ )+ withTypes logInfo $ mconcat ["Found ", display $ L.length parsed, " license template(s)"] pure $ M.fromList parsed- where- extensions = toList $ templateExtensions @TemplateType- load path =- liftIO $ (T.strip <$> loadFile path) >>= parseTemplate (Just $ T.pack path)+ where extensions = toList $ templateExtensions @TemplateType -- | Loads built-in templates, stored in "Headroom.Embedded", for the given@@ -367,7 +383,10 @@ template = licenseTemplate licenseType -loadTemplates :: (Has CtConfiguration env, HasLogFunc env)+loadTemplates :: ( Has CtConfiguration env+ , Has (FileSystem (RIO env)) env+ , HasLogFunc env+ ) => RIO env (Map FileType TemplateType) loadTemplates = do Configuration {..} <- viewL @CtConfiguration
src/Headroom/Configuration.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-} {-| Module : Headroom.Configuration@@ -52,17 +53,18 @@ , PtHeadersConfig , PtUpdateCopyrightConfig , UpdateCopyrightConfig(..)- , hfcConfigL- , hfcEnabledL- , hfcsUpdateCopyrightL- , hfcsUpdateCopyrightL- , uccSelectedAuthorsL )+import Headroom.Data.Lens ( suffixLenses ) import Headroom.FileType.Types ( FileType(..) ) import RIO import qualified RIO.ByteString as B +suffixLenses ''HeaderFnConfig+suffixLenses ''HeaderFnConfigs+suffixLenses ''UpdateCopyrightConfig++ -- | Loads and parses application configuration from given /YAML/ file. loadConfiguration :: MonadIO m => FilePath@@ -105,16 +107,17 @@ -> m CtHeadersConfig -- ^ full 'CtHeadersConfig' makeHeadersConfig pt = do- hscC <- makeHeaderConfig C (hscC pt)- hscCpp <- makeHeaderConfig CPP (hscCpp pt)- hscCss <- makeHeaderConfig CSS (hscCss pt)- hscHaskell <- makeHeaderConfig Haskell (hscHaskell pt)- hscHtml <- makeHeaderConfig HTML (hscHtml pt)- hscJava <- makeHeaderConfig Java (hscJava pt)- hscJs <- makeHeaderConfig JS (hscJs pt)- hscRust <- makeHeaderConfig Rust (hscRust pt)- hscScala <- makeHeaderConfig Scala (hscScala pt)- hscShell <- makeHeaderConfig Shell (hscShell pt)+ hscC <- makeHeaderConfig C (hscC pt)+ hscCpp <- makeHeaderConfig CPP (hscCpp pt)+ hscCss <- makeHeaderConfig CSS (hscCss pt)+ hscHaskell <- makeHeaderConfig Haskell (hscHaskell pt)+ hscHtml <- makeHeaderConfig HTML (hscHtml pt)+ hscJava <- makeHeaderConfig Java (hscJava pt)+ hscJs <- makeHeaderConfig JS (hscJs pt)+ hscPureScript <- makeHeaderConfig PureScript (hscPureScript pt)+ hscRust <- makeHeaderConfig Rust (hscRust pt)+ hscScala <- makeHeaderConfig Scala (hscScala pt)+ hscShell <- makeHeaderConfig Shell (hscShell pt) pure HeadersConfig { .. }
src/Headroom/Configuration/Types.hs view
@@ -8,7 +8,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-}@@ -66,18 +66,6 @@ , LicenseType(..) , RunMode(..) , TemplateSource(..)- -- * Lenses- , cRunModeL- , cSourcePathsL- , cExcludedPathsL- , cTemplateSourceL- , cVariablesL- , cLicenseHeadersL- , cHeaderFnConfigsL- , uccSelectedAuthorsL- , hfcEnabledL- , hfcConfigL- , hfcsUpdateCopyrightL ) where @@ -91,7 +79,6 @@ ) import Data.Monoid ( Last(..) ) import Headroom.Data.EnumExtra ( EnumExtra(..) )-import Headroom.Data.Lens ( suffixLenses ) import Headroom.Data.Regex ( Regex(..) ) import Headroom.FileType.Types ( FileType ) import Headroom.Serialization ( aesonOptions )@@ -125,17 +112,17 @@ -- | Syntax of the license header comment. data HeaderSyntax- = BlockComment !Text !Text+ = BlockComment Text Text -- ^ block (multi-line) comment syntax (e.g. @/* */@)- | LineComment !Text+ | LineComment Text -- ^ single line comment syntax (e.g. @//@) deriving (Eq, Show) -- | Internal representation of the block style of 'HeaderSyntax'. data BlockComment' = BlockComment'- { bcStartsWith :: !Text+ { bcStartsWith :: Text -- ^ starting pattern (e.g. @/*@)- , bcEndsWith :: !Text+ , bcEndsWith :: Text -- ^ ending pattern (e.g. @*/@) } deriving (Eq, Generic, Show)@@ -203,7 +190,7 @@ data GenMode = GenConfigFile -- ^ generate /YAML/ config file stub- | GenLicense !(LicenseType, FileType)+ | GenLicense (LicenseType, FileType) -- ^ generate license header template deriving (Eq, Show) @@ -224,7 +211,7 @@ -- | Main configuration for the "Headroom.HeaderFn.UpdateCopyright" -- /license header function/. data UpdateCopyrightConfig (p :: Phase) = UpdateCopyrightConfig- { uccSelectedAuthors :: !(p ::: Maybe (NonEmpty Text))+ { uccSelectedAuthors :: p ::: Maybe (NonEmpty Text) -- ^ if specified, years will be updated only in copyright statements of -- given authors }@@ -258,9 +245,9 @@ -- | Configuration for selected /license header function/. data HeaderFnConfig (p :: Phase) c = HeaderFnConfig- { hfcEnabled :: !(p ::: Bool)+ { hfcEnabled :: p ::: Bool -- ^ whether this function is enabled or not- , hfcConfig :: !(c p)+ , hfcConfig :: c p -- ^ custom configuration of the /license header function/ } @@ -295,7 +282,7 @@ -- | Configuration of all known /license header functions/. data HeaderFnConfigs (p :: Phase) = HeaderFnConfigs- { hfcsUpdateCopyright :: !(HeaderFnConfig p UpdateCopyrightConfig)+ { hfcsUpdateCopyright :: HeaderFnConfig p UpdateCopyrightConfig -- ^ configuration for the "Headroom.HeaderFn.UpdateCopyright" -- /license header function/ }@@ -329,19 +316,19 @@ -- | Application configuration. data Configuration (p :: Phase) = Configuration- { cRunMode :: !(p ::: RunMode)+ { cRunMode :: p ::: RunMode -- ^ mode of the @run@ command- , cSourcePaths :: !(p ::: [FilePath])+ , cSourcePaths :: p ::: [FilePath] -- ^ paths to source code files- , cExcludedPaths :: !(p ::: [Regex])+ , cExcludedPaths :: p ::: [Regex] -- ^ excluded source paths- , cTemplateSource :: !(p ::: TemplateSource)+ , cTemplateSource :: p ::: TemplateSource -- ^ source of license templates- , cVariables :: !Variables+ , cVariables :: Variables -- ^ variable values for templates- , cLicenseHeaders :: !(HeadersConfig p)+ , cLicenseHeaders :: HeadersConfig p -- ^ configuration of license headers- , cHeaderFnConfigs :: !(HeaderFnConfigs p)+ , cHeaderFnConfigs :: HeaderFnConfigs p -- ^ configuration of license header functions } @@ -387,17 +374,17 @@ -- | Configuration for specific license header. data HeaderConfig (p :: Phase) = HeaderConfig- { hcFileExtensions :: !(p ::: [Text])+ { hcFileExtensions :: p ::: [Text] -- ^ list of file extensions (without dot)- , hcMarginAfter :: !(p ::: Int)+ , hcMarginAfter :: p ::: Int -- ^ number of empty lines to put after header- , hcMarginBefore :: !(p ::: Int)+ , hcMarginBefore :: p ::: Int -- ^ number of empty lines to put before header- , hcPutAfter :: !(p ::: [Regex])+ , hcPutAfter :: p ::: [Regex] -- ^ /regexp/ patterns after which to put the header- , hcPutBefore :: !(p ::: [Regex])+ , hcPutBefore :: p ::: [Regex] -- ^ /regexp/ patterns before which to put the header- , hcHeaderSyntax :: !(p ::: HeaderSyntax)+ , hcHeaderSyntax :: p ::: HeaderSyntax -- ^ syntax of the license header comment } @@ -447,25 +434,27 @@ -- | Group of 'HeaderConfig' configurations for supported file types. data HeadersConfig (p :: Phase) = HeadersConfig- { hscC :: !(HeaderConfig p)+ { hscC :: HeaderConfig p -- ^ configuration for /C/ programming language- , hscCpp :: !(HeaderConfig p)+ , hscCpp :: HeaderConfig p -- ^ configuration for /C++/ programming language- , hscCss :: !(HeaderConfig p)+ , hscCss :: HeaderConfig p -- ^ configuration for /CSS/- , hscHaskell :: !(HeaderConfig p)+ , hscHaskell :: HeaderConfig p -- ^ configuration for /Haskell/ programming language- , hscHtml :: !(HeaderConfig p)+ , hscHtml :: HeaderConfig p -- ^ configuration for /HTML/- , hscJava :: !(HeaderConfig p)+ , hscJava :: HeaderConfig p -- ^ configuration for /Java/ programming language- , hscJs :: !(HeaderConfig p)+ , hscJs :: HeaderConfig p -- ^ configuration for /JavaScript/ programming language- , hscRust :: !(HeaderConfig p)+ , hscPureScript :: HeaderConfig p+ -- ^ configuration for /PureScript/ programming language+ , hscRust :: HeaderConfig p -- ^ configuration for /Rust/ programming language- , hscScala :: !(HeaderConfig p)+ , hscScala :: HeaderConfig p -- ^ configuration for /Scala/ programming language- , hscShell :: !(HeaderConfig p)+ , hscShell :: HeaderConfig p -- ^ configuration for /Shell/ } @@ -482,30 +471,32 @@ instance FromJSON PtHeadersConfig where parseJSON = withObject "PartialHeadersConfig" $ \obj -> do- hscC <- obj .:? "c" .!= mempty- hscCpp <- obj .:? "cpp" .!= mempty- hscCss <- obj .:? "css" .!= mempty- hscHaskell <- obj .:? "haskell" .!= mempty- hscHtml <- obj .:? "html" .!= mempty- hscJava <- obj .:? "java" .!= mempty- hscJs <- obj .:? "js" .!= mempty- hscRust <- obj .:? "rust" .!= mempty- hscScala <- obj .:? "scala" .!= mempty- hscShell <- obj .:? "shell" .!= mempty+ hscC <- obj .:? "c" .!= mempty+ hscCpp <- obj .:? "cpp" .!= mempty+ hscCss <- obj .:? "css" .!= mempty+ hscHaskell <- obj .:? "haskell" .!= mempty+ hscHtml <- obj .:? "html" .!= mempty+ hscJava <- obj .:? "java" .!= mempty+ hscJs <- obj .:? "js" .!= mempty+ hscPureScript <- obj .:? "purescript" .!= mempty+ hscRust <- obj .:? "rust" .!= mempty+ hscScala <- obj .:? "scala" .!= mempty+ hscShell <- obj .:? "shell" .!= mempty pure HeadersConfig { .. } instance Semigroup PtHeadersConfig where- x <> y = HeadersConfig { hscC = hscC x <> hscC y- , hscCpp = hscCpp x <> hscCpp y- , hscCss = hscCss x <> hscCss y- , hscHaskell = hscHaskell x <> hscHaskell y- , hscHtml = hscHtml x <> hscHtml y- , hscJava = hscJava x <> hscJava y- , hscJs = hscJs x <> hscJs y- , hscRust = hscRust x <> hscRust y- , hscScala = hscScala x <> hscScala y- , hscShell = hscShell x <> hscShell y+ x <> y = HeadersConfig { hscC = hscC x <> hscC y+ , hscCpp = hscCpp x <> hscCpp y+ , hscCss = hscCss x <> hscCss y+ , hscHaskell = hscHaskell x <> hscHaskell y+ , hscHtml = hscHtml x <> hscHtml y+ , hscJava = hscJava x <> hscJava y+ , hscJs = hscJs x <> hscJs y+ , hscPureScript = hscPureScript x <> hscPureScript y+ , hscRust = hscRust x <> hscRust y+ , hscScala = hscScala x <> hscScala y+ , hscShell = hscShell x <> hscShell y } @@ -520,23 +511,24 @@ mempty mempty mempty+ mempty --------------------------------- Error Types -------------------------------- -- | Represents single key in the configuration. data ConfigurationKey- = CkFileExtensions !FileType+ = CkFileExtensions FileType -- ^ no configuration for @file-extensions@- | CkHeaderSyntax !FileType+ | CkHeaderSyntax FileType -- ^ no configuration for header syntax- | CkMarginAfter !FileType+ | CkMarginAfter FileType -- ^ no configuration for @margin-after@- | CkMarginBefore !FileType+ | CkMarginBefore FileType -- ^ no configuration for @margin-before@- | CkPutAfter !FileType+ | CkPutAfter FileType -- ^ no configuration for @put-after@- | CkPutBefore !FileType+ | CkPutBefore FileType -- ^ no configuration for @put-before@ | CkRunMode -- ^ no configuration for @run-mode@@@ -555,7 +547,7 @@ -- | Exception specific to the "Headroom.Configuration" module. data ConfigurationError- = MissingConfiguration !ConfigurationKey+ = MissingConfiguration ConfigurationKey -- ^ some of the required configuration keys has not been specified | MixedHeaderSyntax -- ^ illegal configuration for 'HeaderSyntax'@@ -631,11 +623,3 @@ cliText = fmap (\c -> "command line option '" <> c <> "'") cli yamlText = fmap (\y -> "YAML option '" <> y <> "'") yaml options = T.intercalate " or " . catMaybes $ [cliText, yamlText]-------------------------------------- LENSES -------------------------------------suffixLenses ''Configuration-suffixLenses ''UpdateCopyrightConfig-suffixLenses ''HeaderFnConfig-suffixLenses ''HeaderFnConfigs
src/Headroom/Data/Regex.hs view
@@ -28,6 +28,8 @@ , re , replace , scan+ -- * Unsafe Functions+ , compileUnsafe ) where @@ -111,14 +113,19 @@ scan (Regex regex) = PH.scan regex ------------------------------- PRIVATE FUNCTIONS --------------------------------compileUnsafe :: Text -> Regex+-- | Compiles the given text into /regex/ in runtime. Note that if the /regex/+-- cannot be compiled, it will throw runtime error. Do not use this function+-- unless you know what you're doing.+compileUnsafe :: Text+ -- ^ /regex/ to compile+ -> Regex+ -- ^ compiled /regex/ or runtime exception compileUnsafe raw = case compile raw of Left err -> error . displayException $ err Right res -> res ++------------------------------ PRIVATE FUNCTIONS ----------------------------- quoteExpRegex :: String -> ExpQ quoteExpRegex txt = [| compileUnsafe . T.pack $ txt |]
src/Headroom/Embedded.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TemplateHaskell #-} @@ -20,21 +21,23 @@ ) where -import Data.FileEmbed ( embedStringFile ) import Headroom.Configuration.Types ( LicenseType(..) )+import Headroom.Embedded.TH ( embedConfigFile+ , embedDefaultConfig+ , embedTemplate+ ) import Headroom.FileType.Types ( FileType(..) ) import RIO - -- | Content of dummy /YAML/ configuration file for the application. configFileStub :: IsString a => a-configFileStub = $(embedStringFile "embedded/config-file.yaml")+configFileStub = $(embedConfigFile) -- | Default /YAML/ configuration. defaultConfig :: IsString a => a-defaultConfig = $(embedStringFile "embedded/default-config.yaml")+defaultConfig = $(embedDefaultConfig) -- | License template for given license.@@ -47,68 +50,74 @@ -- ^ template text licenseTemplate licenseType fileType = case licenseType of Apache2 -> case fileType of- C -> $(embedStringFile "embedded/license/apache2/c.mustache")- CPP -> $(embedStringFile "embedded/license/apache2/cpp.mustache")- CSS -> $(embedStringFile "embedded/license/apache2/css.mustache")- Haskell -> $(embedStringFile "embedded/license/apache2/haskell.mustache")- HTML -> $(embedStringFile "embedded/license/apache2/html.mustache")- Java -> $(embedStringFile "embedded/license/apache2/java.mustache")- JS -> $(embedStringFile "embedded/license/apache2/js.mustache")- Rust -> $(embedStringFile "embedded/license/apache2/rust.mustache")- Scala -> $(embedStringFile "embedded/license/apache2/scala.mustache")- Shell -> $(embedStringFile "embedded/license/apache2/shell.mustache")+ C -> $(embedTemplate Apache2 C)+ CPP -> $(embedTemplate Apache2 CPP)+ CSS -> $(embedTemplate Apache2 CSS)+ Haskell -> $(embedTemplate Apache2 Haskell)+ HTML -> $(embedTemplate Apache2 HTML)+ Java -> $(embedTemplate Apache2 Java)+ JS -> $(embedTemplate Apache2 JS)+ PureScript -> $(embedTemplate Apache2 PureScript)+ Rust -> $(embedTemplate Apache2 Rust)+ Scala -> $(embedTemplate Apache2 Scala)+ Shell -> $(embedTemplate Apache2 Shell) BSD3 -> case fileType of- C -> $(embedStringFile "embedded/license/bsd3/c.mustache")- CPP -> $(embedStringFile "embedded/license/bsd3/cpp.mustache")- CSS -> $(embedStringFile "embedded/license/bsd3/css.mustache")- Haskell -> $(embedStringFile "embedded/license/bsd3/haskell.mustache")- HTML -> $(embedStringFile "embedded/license/bsd3/html.mustache")- Java -> $(embedStringFile "embedded/license/bsd3/java.mustache")- JS -> $(embedStringFile "embedded/license/bsd3/js.mustache")- Rust -> $(embedStringFile "embedded/license/bsd3/rust.mustache")- Scala -> $(embedStringFile "embedded/license/bsd3/scala.mustache")- Shell -> $(embedStringFile "embedded/license/bsd3/shell.mustache")+ C -> $(embedTemplate BSD3 C)+ CPP -> $(embedTemplate BSD3 CPP)+ CSS -> $(embedTemplate BSD3 CSS)+ Haskell -> $(embedTemplate BSD3 Haskell)+ HTML -> $(embedTemplate BSD3 HTML)+ Java -> $(embedTemplate BSD3 Java)+ JS -> $(embedTemplate BSD3 JS)+ PureScript -> $(embedTemplate BSD3 PureScript)+ Rust -> $(embedTemplate BSD3 Rust)+ Scala -> $(embedTemplate BSD3 Scala)+ Shell -> $(embedTemplate BSD3 Shell) GPL2 -> case fileType of- C -> $(embedStringFile "embedded/license/gpl2/c.mustache")- CPP -> $(embedStringFile "embedded/license/gpl2/cpp.mustache")- CSS -> $(embedStringFile "embedded/license/gpl2/css.mustache")- Haskell -> $(embedStringFile "embedded/license/gpl2/haskell.mustache")- HTML -> $(embedStringFile "embedded/license/gpl2/html.mustache")- Java -> $(embedStringFile "embedded/license/gpl2/java.mustache")- JS -> $(embedStringFile "embedded/license/gpl2/js.mustache")- Rust -> $(embedStringFile "embedded/license/gpl2/rust.mustache")- Scala -> $(embedStringFile "embedded/license/gpl2/scala.mustache")- Shell -> $(embedStringFile "embedded/license/gpl2/shell.mustache")+ C -> $(embedTemplate GPL2 C)+ CPP -> $(embedTemplate GPL2 CPP)+ CSS -> $(embedTemplate GPL2 CSS)+ Haskell -> $(embedTemplate GPL2 Haskell)+ HTML -> $(embedTemplate GPL2 HTML)+ Java -> $(embedTemplate GPL2 Java)+ JS -> $(embedTemplate GPL2 JS)+ PureScript -> $(embedTemplate GPL2 PureScript)+ Rust -> $(embedTemplate GPL2 Rust)+ Scala -> $(embedTemplate GPL2 Scala)+ Shell -> $(embedTemplate GPL2 Shell) GPL3 -> case fileType of- C -> $(embedStringFile "embedded/license/gpl3/c.mustache")- CPP -> $(embedStringFile "embedded/license/gpl3/cpp.mustache")- CSS -> $(embedStringFile "embedded/license/gpl3/css.mustache")- Haskell -> $(embedStringFile "embedded/license/gpl3/haskell.mustache")- HTML -> $(embedStringFile "embedded/license/gpl3/html.mustache")- Java -> $(embedStringFile "embedded/license/gpl3/java.mustache")- JS -> $(embedStringFile "embedded/license/gpl3/js.mustache")- Rust -> $(embedStringFile "embedded/license/gpl3/rust.mustache")- Scala -> $(embedStringFile "embedded/license/gpl3/scala.mustache")- Shell -> $(embedStringFile "embedded/license/gpl3/shell.mustache")+ C -> $(embedTemplate GPL3 C)+ CPP -> $(embedTemplate GPL3 CPP)+ CSS -> $(embedTemplate GPL3 CSS)+ Haskell -> $(embedTemplate GPL3 Haskell)+ HTML -> $(embedTemplate GPL3 HTML)+ Java -> $(embedTemplate GPL3 Java)+ JS -> $(embedTemplate GPL3 JS)+ PureScript -> $(embedTemplate GPL3 PureScript)+ Rust -> $(embedTemplate GPL3 Rust)+ Scala -> $(embedTemplate GPL3 Scala)+ Shell -> $(embedTemplate GPL3 Shell) MIT -> case fileType of- C -> $(embedStringFile "embedded/license/mit/c.mustache")- CPP -> $(embedStringFile "embedded/license/mit/cpp.mustache")- CSS -> $(embedStringFile "embedded/license/mit/css.mustache")- Haskell -> $(embedStringFile "embedded/license/mit/haskell.mustache")- HTML -> $(embedStringFile "embedded/license/mit/html.mustache")- Java -> $(embedStringFile "embedded/license/mit/java.mustache")- JS -> $(embedStringFile "embedded/license/mit/js.mustache")- Rust -> $(embedStringFile "embedded/license/mit/rust.mustache")- Scala -> $(embedStringFile "embedded/license/mit/scala.mustache")- Shell -> $(embedStringFile "embedded/license/mit/shell.mustache")+ C -> $(embedTemplate MIT C)+ CPP -> $(embedTemplate MIT CPP)+ CSS -> $(embedTemplate MIT CSS)+ Haskell -> $(embedTemplate MIT Haskell)+ HTML -> $(embedTemplate MIT HTML)+ Java -> $(embedTemplate MIT Java)+ JS -> $(embedTemplate MIT JS)+ PureScript -> $(embedTemplate MIT PureScript)+ Rust -> $(embedTemplate MIT Rust)+ Scala -> $(embedTemplate MIT Scala)+ Shell -> $(embedTemplate MIT Shell) MPL2 -> case fileType of- C -> $(embedStringFile "embedded/license/mpl2/c.mustache")- CPP -> $(embedStringFile "embedded/license/mpl2/cpp.mustache")- CSS -> $(embedStringFile "embedded/license/mpl2/css.mustache")- Haskell -> $(embedStringFile "embedded/license/mpl2/haskell.mustache")- HTML -> $(embedStringFile "embedded/license/mpl2/html.mustache")- Java -> $(embedStringFile "embedded/license/mpl2/java.mustache")- JS -> $(embedStringFile "embedded/license/mpl2/js.mustache")- Rust -> $(embedStringFile "embedded/license/mpl2/rust.mustache")- Scala -> $(embedStringFile "embedded/license/mpl2/scala.mustache")- Shell -> $(embedStringFile "embedded/license/mpl2/shell.mustache")+ C -> $(embedTemplate MPL2 C)+ CPP -> $(embedTemplate MPL2 CPP)+ CSS -> $(embedTemplate MPL2 CSS)+ Haskell -> $(embedTemplate MPL2 Haskell)+ HTML -> $(embedTemplate MPL2 HTML)+ Java -> $(embedTemplate MPL2 Java)+ JS -> $(embedTemplate MPL2 JS)+ PureScript -> $(embedTemplate MPL2 PureScript)+ Rust -> $(embedTemplate MPL2 Rust)+ Scala -> $(embedTemplate MPL2 Scala)+ Shell -> $(embedTemplate MPL2 Shell)
+ src/Headroom/Embedded/TH.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeApplications #-}++{-|+Module : Headroom.Embedded.TH+Description : /Template Haskell/ functions for "Headroom.Embedded"+Copyright : (c) 2019-2020 Vaclav Svejcar+License : BSD-3-Clause+Maintainer : vaclav.svejcar@gmail.com+Stability : experimental+Portability : POSIX++This module contains some /Template Haskell/ powered functions, used by+"Headroom.Embedded" module, that needs to be placed in separated module, due to+/GHC/ stage restriction.+-}++module Headroom.Embedded.TH+ ( embedConfigFile+ , embedDefaultConfig+ , embedTemplate+ )+where++import Data.FileEmbed ( embedStringFile )+import Headroom.Configuration.Types ( LicenseType(..) )+import Headroom.Data.EnumExtra ( EnumExtra(..) )+import Headroom.FileType.Types ( FileType(..) )+import Headroom.Meta ( TemplateType )+import Headroom.Template ( Template(..) )+import Language.Haskell.TH.Syntax ( Exp+ , Q+ )+import RIO+import qualified RIO.NonEmpty as NE+import qualified RIO.Text as T+++-- | Embeds stub configuration file to source code.+embedConfigFile :: Q Exp+embedConfigFile = embedStringFile "embedded/config-file.yaml"+++-- | Embeds default configuration file to source code.+embedDefaultConfig :: Q Exp+embedDefaultConfig = embedStringFile "embedded/default-config.yaml"+++-- | Embeds /template file/ to the source code.+embedTemplate :: LicenseType+ -- ^ type of the /license/+ -> FileType+ -- ^ type of the source code file+ -> Q Exp+ -- ^ content of the appropriate /template/ file+embedTemplate lt ft = (embedStringFile . mconcat)+ ["embedded/license/", toStringLC lt, "/", toStringLC ft, ".", ext]+ where ext = T.unpack . NE.head $ templateExtensions @TemplateType+++------------------------------ PRIVATE FUNCTIONS -----------------------------++toStringLC :: EnumExtra a => a -> String+toStringLC = T.unpack . T.toLower . enumToText
src/Headroom/Ext.hs view
@@ -25,6 +25,8 @@ import Headroom.Configuration.Types ( CtHeaderConfig ) import qualified Headroom.Ext.Haskell as Haskell+import qualified Headroom.Ext.Java as Java+import qualified Headroom.Ext.PureScript as PureScript import Headroom.FileType.Types ( FileType(..) ) import Headroom.Template ( Template(..) ) import Headroom.Types ( TemplateMeta(..) )@@ -35,7 +37,9 @@ -- | Extracts variables specific to the file type (if supported), e.g. module -- name for /Haskell/ source code. Currently supported file types are: ----- * /Haskell/ - implemented in "Headroom.FileSupport.Haskell"+-- * /Haskell/ - implemented in "Headroom.Ext.Haskell"+-- * /Java/ - implemented in "Headroom.Ext.Java"+-- * /PureScript/ - implemented in "Headroom.Ext.PureScript" extractVariables :: FileType -- ^ type of the file -> CtHeaderConfig@@ -48,9 +52,11 @@ -- ^ text of the source code file -> Variables -- ^ extracted variables-extractVariables fileType config meta headerPos text = case fileType of- Haskell -> Haskell.extractVariables config meta headerPos text- _ -> mempty+extractVariables fileType = case fileType of+ Haskell -> Haskell.extractVariables+ Java -> Java.extractVariables+ PureScript -> PureScript.extractVariables+ _ -> mempty -- | Extracts medatata from given /template/ for selected /file type/, which
src/Headroom/Ext/Haskell.hs view
@@ -7,7 +7,7 @@ {-| Module : Headroom.Ext.Haskell-Description : Extraction of /Haskell/-specific template variables+Description : Extended support for /Haskell/ source code files Copyright : (c) 2019-2020 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com
+ src/Headroom/Ext/Java.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TupleSections #-}++{-|+Module : Headroom.Ext.Java+Description : Extended support for /Java/ source code files+Copyright : (c) 2019-2020 Vaclav Svejcar+License : BSD-3-Clause+Maintainer : vaclav.svejcar@gmail.com+Stability : experimental+Portability : POSIX++This module provides /extended support/ for /Java/ source code files. Current+implementation includes extracting of /package name/ from currently processed+/Java/ source code file.+-}++module Headroom.Ext.Java+ ( extractVariables+ , extractPackageName+ )+where++import Headroom.Configuration.Types ( CtHeaderConfig )+import Headroom.Data.Regex ( match+ , re+ )+import Headroom.Data.TextExtra ( toLines )+import Headroom.Types ( TemplateMeta(..) )+import Headroom.Variables ( mkVariables )+import Headroom.Variables.Types ( Variables(..) )+import RIO+import RIO.Lens ( ix )+++-- | Extracts name of /Java/ package from given source code file content.+--+-- >>> extractPackageName "package mypackage;\nclass Foo {}"+-- Just "mypackage"+extractPackageName :: Text+ -- ^ input text+ -> Maybe Text+ -- ^ extracted package name+extractPackageName = go . toLines+ where+ go [] = Nothing+ go (x : xs) = maybe (go xs) (^? ix 1) (match [re|^package (.*);$|] x)+++-- | Extracts variables from /Java/ source code.+--+-- __List of Extracted Variables:__+--+-- * @___java_package_name__@ - name of the /Java/ package+extractVariables :: CtHeaderConfig+ -- ^ license header configuration+ -> Maybe TemplateMeta+ -- ^ extracted metadata from corresponding /template/+ -> Maybe (Int, Int)+ -- ^ license header position @(startLine, endLine)@+ -> Text+ -- ^ input text+ -> Variables+ -- ^ extracted variables+extractVariables _ _ _ text = (mkVariables . catMaybes)+ [("_java_package_name", ) <$> extractPackageName text]
+ src/Headroom/Ext/PureScript.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TupleSections #-}++{-|+Module : Headroom.Ext.PureScript+Description : Extended support for /PureScript/ source code files+Copyright : (c) 2019-2020 Vaclav Svejcar+License : BSD-3-Clause+Maintainer : vaclav.svejcar@gmail.com+Stability : experimental+Portability : POSIX++This module provides /extended support/ for /PureScript/ source code files.+Current implementation includes extracting of /module name/ from currently+processed /PureScript/ source code file.+-}++module Headroom.Ext.PureScript where++import Headroom.Configuration.Types ( CtHeaderConfig )+import Headroom.Ext.Haskell ( extractModuleName )+import Headroom.Types ( TemplateMeta(..) )+import Headroom.Variables ( mkVariables )+import Headroom.Variables.Types ( Variables(..) )+import RIO+++-- | Extracts variables from /PureScript/ source code.+--+-- __List of Extracted Variables:__+--+-- * @___purescript_module_name__@ - name of the /PureScript/ module+extractVariables :: CtHeaderConfig+ -- ^ license header configuration+ -> Maybe TemplateMeta+ -- ^ extracted metadata from corresponding /template/+ -> Maybe (Int, Int)+ -- ^ license header position @(startLine, endLine)@+ -> Text+ -- ^ input text+ -> Variables+ -- ^ extracted variables+extractVariables _ _ _ text = (mkVariables . catMaybes)+ [("_purescript_module_name", ) <$> extractModuleName text]++
src/Headroom/FileSupport.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-} {-| Module : Headroom.FileSupport@@ -36,6 +37,7 @@ , HeaderConfig(..) , HeaderSyntax(..) )+import Headroom.Data.Lens ( suffixLensesFor ) import Headroom.Data.Regex ( Regex , match )@@ -43,9 +45,7 @@ , toLines ) import Headroom.Ext ( extractVariables )-import Headroom.FileSupport.Types ( FileInfo(..)- , fiHeaderPosL- )+import Headroom.FileSupport.Types ( FileInfo(..) ) import Headroom.FileType.Types ( FileType(..) ) import Headroom.Types ( TemplateMeta(..) ) import RIO@@ -53,6 +53,9 @@ import qualified RIO.Text as T +suffixLensesFor ["fiHeaderPos"] ''FileInfo++ -- | Extracts info about the processed file to be later used by the header -- detection/manipulation functions. extractFileInfo :: FileType@@ -68,7 +71,7 @@ extractFileInfo fiFileType fiHeaderConfig meta text = let fiHeaderPos = findHeader fiHeaderConfig text fiVariables =- extractVariables fiFileType fiHeaderConfig meta fiHeaderPos text+ extractVariables fiFileType fiHeaderConfig meta fiHeaderPos text in FileInfo { .. }
src/Headroom/FileSupport/Types.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE TemplateHaskell #-} {-| Module : Headroom.FileSupport.Types@@ -16,16 +15,10 @@ module Headroom.FileSupport.Types ( -- * Data Types FileInfo(..)- -- * Lenses- , fiFileTypeL- , fiHeaderConfigL- , fiHeaderPosL- , fiVariablesL ) where import Headroom.Configuration.Types ( CtHeaderConfig )-import Headroom.Data.Lens ( suffixLenses ) import Headroom.FileType.Types ( FileType ) import Headroom.Variables.Types ( Variables ) import RIO@@ -43,5 +36,3 @@ -- ^ additional extracted variables } deriving (Eq, Show)--suffixLenses ''FileInfo
src/Headroom/FileSystem.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ViewPatterns #-} {-| Module : Headroom.FileSystem@@ -14,16 +15,24 @@ -} module Headroom.FileSystem- ( -- * Traversing the File System- findFiles+ ( -- * Type Aliases+ CreateDirectoryFn+ , DoesFileExistFn+ , FindFilesFn+ , FindFilesByExtsFn+ , FindFilesByTypesFn+ , GetCurrentDirectoryFn+ , ListFilesFn+ , LoadFileFn+ -- * Polymorphic Record+ , FileSystem(..)+ , mkFileSystem+ -- * Traversing the File System+ , findFiles , findFilesByExts , findFilesByTypes , listFiles , loadFile- -- * Working with Files/Directories- , doesFileExist- , getCurrentDirectory- , createDirectory -- * Working with Files Metadata , fileExtension -- * Other@@ -52,51 +61,146 @@ import qualified RIO.Text as T +-------------------------------- TYPE ALIASES -------------------------------- +-- | Type of a function that creates new empty directory on the given path.+type CreateDirectoryFn m+ = FilePath+ -- ^ path of new directory+ -> m ()+ -- ^ /IO/ action result+++-- | Type of a function that returns 'True' if the argument file exists and is+-- not a directory, and 'False' otherwise.+type DoesFileExistFn m+ = FilePath+ -- ^ path to check+ -> m Bool+ -- ^ whether the given path is existing file+++-- | Type of a function that recursively finds files on given path whose+-- filename matches the predicate.+type FindFilesFn m+ = FilePath+ -- ^ path to search+ -> (FilePath -> Bool)+ -- ^ predicate to match filename+ -> m [FilePath]+ -- ^ found files+++-- | Type of a function that recursively finds files on given path by file+-- extensions.+type FindFilesByExtsFn m+ = FilePath+ -- ^ path to search+ -> [Text]+ -- ^ list of file extensions (without dot)+ -> m [FilePath]+ -- ^ list of found files+++-- | Type of a function that recursively find files on given path by their+-- file types.+type FindFilesByTypesFn m+ = CtHeadersConfig+ -- ^ configuration of license headers+ -> [FileType]+ -- ^ list of file types+ -> FilePath+ -- ^ path to search+ -> m [FilePath]+ -- ^ list of found files+++-- | Type of a function that obtains the current working directory as an+-- absolute path.+type GetCurrentDirectoryFn m = m FilePath+++-- | Type of a function that recursively find all files on given path. If file+-- reference is passed instead of directory, such file path is returned.+type ListFilesFn m+ = FilePath+ -- ^ path to search+ -> m [FilePath]+ -- ^ list of found files++-- | Type of a function that loads file content in UTF8 encoding.+type LoadFileFn m+ = FilePath+ -- ^ file path+ -> m Text+ -- ^ file content++----------------------------- POLYMORPHIC RECORD -----------------------------++-- | /Polymorphic record/ composed of file system /IO/ function types, allowing+-- to abstract over concrete implementation. Whenever you need to use effectful+-- functions from this module, consider using this record instead of using them+-- directly, as it allows you to use different records for production code and+-- for testing, which is not as easy if you wire some of the provided functions+-- directly.+data FileSystem m = FileSystem+ { fsCreateDirectory :: CreateDirectoryFn m+ -- ^ Function that creates new empty directory on the given path.+ , fsDoesFileExist :: DoesFileExistFn m+ -- ^ Function that returns 'True' if the argument file exists and is not+ -- a directory, and 'False' otherwise.+ , fsFindFiles :: FindFilesFn m+ -- ^ Function that recursively finds files on given path whose filename+ -- matches the predicate.+ , fsFindFilesByExts :: FindFilesByExtsFn m+ -- ^ Function that recursively finds files on given path by file extensions.+ , fsFindFilesByTypes :: FindFilesByTypesFn m+ -- ^ Function that recursively find files on given path by their file types.+ , fsGetCurrentDirectory :: GetCurrentDirectoryFn m+ -- ^ Function that obtains the current working directory as an absolute path.+ , fsListFiles :: ListFilesFn m+ -- ^ Function that recursively find all files on given path. If file reference+ -- is passed instead of directory, such file path is returned.+ , fsLoadFile :: LoadFileFn m+ -- ^ Function that loads file content in UTF8 encoding.+ }+++-- | Creates new 'FileSystem' that performs actual disk /IO/ operations.+mkFileSystem :: MonadIO m => FileSystem m+mkFileSystem = FileSystem { fsCreateDirectory = createDirectory+ , fsDoesFileExist = doesFileExist+ , fsFindFiles = findFiles+ , fsFindFilesByExts = findFilesByExts+ , fsFindFilesByTypes = findFilesByTypes+ , fsGetCurrentDirectory = getCurrentDirectory+ , fsListFiles = listFiles+ , fsLoadFile = loadFile+ }+++------------------------------ PUBLIC FUNCTIONS ------------------------------+ -- | Recursively finds files on given path whose filename matches the predicate.-findFiles :: MonadIO m- => FilePath- -- ^ path to search- -> (FilePath -> Bool)- -- ^ predicate to match filename- -> m [FilePath]- -- ^ found files+findFiles :: MonadIO m => FindFilesFn m findFiles path predicate = fmap (filter predicate) (listFiles path) -- | Recursively finds files on given path by file extensions.-findFilesByExts :: MonadIO m- => FilePath- -- ^ path to search- -> [Text]- -- ^ list of file extensions (without dot)- -> m [FilePath]- -- ^ list of found files+findFilesByExts :: MonadIO m => FindFilesByExtsFn m findFilesByExts path exts = findFiles path predicate where predicate p = any (`isExtensionOf` p) (fmap T.unpack exts) -- | Recursively find files on given path by their file types.-findFilesByTypes :: MonadIO m- => CtHeadersConfig- -- ^ configuration of license headers- -> [FileType]- -- ^ list of file types- -> FilePath- -- ^ path to search- -> m [FilePath]- -- ^ list of found files+findFilesByTypes :: MonadIO m => FindFilesByTypesFn m findFilesByTypes headersConfig types path = findFilesByExts path (types >>= listExtensions headersConfig) -- | Recursively find all files on given path. If file reference is passed -- instead of directory, such file path is returned.-listFiles :: MonadIO m- => FilePath- -- ^ path to search- -> m [FilePath]- -- ^ list of found files+listFiles :: MonadIO m => ListFilesFn m listFiles fileOrDir = do isDir <- doesDirectoryExist fileOrDir if isDir then listDirectory fileOrDir else pure [fileOrDir]@@ -115,18 +219,16 @@ -- -- >>> fileExtension "path/to/some/file.txt" -- Just "txt"-fileExtension :: FilePath -> Maybe Text-fileExtension path = case takeExtension path of- '.' : xs -> Just $ T.pack xs- _ -> Nothing+fileExtension :: FilePath+ -- ^ path from which to extract file extension+ -> Maybe Text+ -- ^ extracted file extension+fileExtension (takeExtension -> '.' : xs) = Just $ T.pack xs+fileExtension _ = Nothing -- | Loads file content in UTF8 encoding.-loadFile :: MonadIO m- => FilePath- -- ^ file path- -> m Text- -- ^ file content+loadFile :: MonadIO m => LoadFileFn m loadFile = readFileUtf8
src/Headroom/FileType.hs view
@@ -67,13 +67,14 @@ -> CtHeaderConfig -- ^ appropriate 'HeaderConfig' configByFileType HeadersConfig {..} fileType = case fileType of- C -> hscC- CPP -> hscCpp- CSS -> hscCss- Haskell -> hscHaskell- HTML -> hscHtml- Java -> hscJava- JS -> hscJs- Rust -> hscRust- Scala -> hscScala- Shell -> hscShell+ C -> hscC+ CPP -> hscCpp+ CSS -> hscCss+ Haskell -> hscHaskell+ HTML -> hscHtml+ Java -> hscJava+ JS -> hscJs+ PureScript -> hscPureScript+ Rust -> hscRust+ Scala -> hscScala+ Shell -> hscShell
src/Headroom/FileType/Types.hs view
@@ -34,6 +34,8 @@ -- ^ support for /Java/ programming language | JS -- ^ support for /JavaScript/ programming language+ | PureScript+ -- ^ support for /PureScript/ programming language | Rust -- ^ support for /Rust/ programming language | Scala
src/Headroom/HeaderFn.hs view
@@ -31,22 +31,18 @@ -- * Environment Data Types , ConfiguredEnv(..) , mkConfiguredEnv- -- * Lenses- , ceCurrentYearL- , ceHeaderFnConfigsL- , ceUpdateCopyrightModeL ) where import Headroom.Configuration.Types ( CtHeaderFnConfigs , HeaderFnConfig(..) , HeaderFnConfigs(..)- , hfcConfigL- , hfcsUpdateCopyrightL- , uccSelectedAuthorsL+ , UpdateCopyrightConfig(..) ) import Headroom.Data.Has ( Has(..) )-import Headroom.Data.Lens ( suffixLenses )+import Headroom.Data.Lens ( suffixLenses+ , suffixLensesFor+ ) import Headroom.HeaderFn.Types ( HeaderFn(..) ) import Headroom.HeaderFn.UpdateCopyright ( SelectedAuthors(..)@@ -61,6 +57,11 @@ import RIO +suffixLenses ''HeaderFnConfigs+suffixLenses ''UpdateCopyrightConfig+suffixLensesFor ["hfcConfig"] ''HeaderFnConfig++ -- | Runs the /license header function/ using the given /environment/ and text -- of rendered /license header/ as input. runHeaderFn :: HeaderFn env@@ -113,7 +114,7 @@ } deriving (Eq, Show) -suffixLenses ''ConfiguredEnv+suffixLensesFor ["ceCurrentYear", "ceUpdateCopyrightMode"] ''ConfiguredEnv instance Has CurrentYear ConfiguredEnv where hasLens = ceCurrentYearL
src/Headroom/Meta.hs view
@@ -31,7 +31,6 @@ import qualified RIO.Text as T - -- | Type of the template format used for license headers. type TemplateType = Mustache
+ test-data/code-samples/purescript/full.purs view
@@ -0,0 +1,9 @@++-- Some module header here++-- Some comment here++module Test where++foo :: String+foo = "Hello, world!"
test/Headroom/Command/InitSpec.hs view
@@ -1,4 +1,10 @@-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StrictData #-}+{-# LANGUAGE TemplateHaskell #-}+ module Headroom.Command.InitSpec ( spec )@@ -7,6 +13,11 @@ import Headroom.Command.Init import Headroom.Command.Types ( CommandInitOptions(..) ) import Headroom.Configuration.Types ( LicenseType(..) )+import Headroom.Data.Has ( Has(..) )+import Headroom.Data.Lens ( suffixLenses+ , suffixLensesFor+ )+import Headroom.FileSystem ( FileSystem(..) ) import Headroom.FileType.Types ( FileType(..) ) import RIO import RIO.FilePath ( (</>) )@@ -14,27 +25,62 @@ import Test.Hspec +data TestEnv = TestEnv+ { envLogFunc :: LogFunc+ , envFileSystem :: FileSystem (RIO TestEnv)+ , envInitOptions :: CommandInitOptions+ , envPaths :: Paths+ }++suffixLenses ''TestEnv+suffixLensesFor ["fsDoesFileExist"] ''FileSystem+suffixLensesFor ["pConfigFile"] ''Paths++instance HasLogFunc TestEnv where+ logFuncL = envLogFuncL++instance Has CommandInitOptions TestEnv where+ hasLens = envInitOptionsL++instance Has (FileSystem (RIO TestEnv)) TestEnv where+ hasLens = envFileSystemL++instance Has Paths TestEnv where+ hasLens = envPathsL++ spec :: Spec spec = do describe "doesAppConfigExist" $ do- it "checks that '.headroom.yaml' exists in selected directory" $ do- result <- runRIO env doesAppConfigExist+ it "checks that configuration file exists in selected directory" $ do+ let env' = env & envFileSystemL . fsDoesFileExistL .~ check+ check path = pure $ env' ^. envPathsL . pConfigFileL == path+ result <- runRIO env' doesAppConfigExist result `shouldBe` True describe "findSupportedFileTypes" $ do it "recursively finds all known file types present in given path" $ do result <- runRIO env findSupportedFileTypes- let expected = [HTML]- L.sort result `shouldBe` L.sort expected+ L.sort result `shouldBe` L.sort [HTML] -env :: Env-env = Env { envLogFunc = logFunc, envInitOptions = opts, envPaths = paths }+env :: TestEnv+env = TestEnv { .. } where- logFunc = mkLogFunc (\_ _ _ _ -> pure ())- opts = CommandInitOptions+ envLogFunc = mkLogFunc (\_ _ _ _ -> pure ())+ envInitOptions = CommandInitOptions { cioSourcePaths = ["test-data" </> "test-traverse"] , cioLicenseType = BSD3 }- paths = Paths { pConfigFile = "test-data" </> "configs" </> "full.yaml"- , pTemplatesDir = "headroom-templates"- }+ envPaths = Paths { pConfigFile = "test-data" </> "configs" </> "full.yaml"+ , pTemplatesDir = "headroom-templates"+ }+ envFileSystem = FileSystem { fsCreateDirectory = undefined+ , fsDoesFileExist = undefined+ , fsFindFiles = undefined+ , fsFindFilesByExts = undefined+ , fsFindFilesByTypes = undefined+ , fsGetCurrentDirectory = undefined+ , fsListFiles = undefined+ , fsLoadFile = undefined+ }+
test/Headroom/Command/RunSpec.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-}@@ -22,15 +23,17 @@ ) import Headroom.Data.EnumExtra ( EnumExtra(..) ) import Headroom.Data.Has ( Has(..) )-import Headroom.Data.Lens ( suffixLenses )+import Headroom.Data.Lens ( suffixLenses+ , suffixLensesFor+ ) import Headroom.Data.TextExtra ( fromLines )+import Headroom.FileSystem ( FileSystem(..) ) import Headroom.FileType.Types ( FileType(..) ) import Headroom.Meta ( TemplateType ) import Headroom.Template ( Template(..) ) import Headroom.Types ( CurrentYear(..) ) import Headroom.Variables ( mkVariables ) import RIO hiding ( assert )-import RIO.FilePath ( (</>) ) import qualified RIO.Map as M import qualified RIO.NonEmpty as NE import qualified RIO.Text as T@@ -40,17 +43,48 @@ import Test.QuickCheck.Monadic +data TestEnv = TestEnv+ { envLogFunc :: LogFunc+ , envCurrentYear :: CurrentYear+ , envFileSystem :: FileSystem (RIO TestEnv)+ , envHeaderFnConfigs :: CtHeaderFnConfigs+ }++suffixLenses ''TestEnv+suffixLensesFor ["fsFindFilesByExts", "fsLoadFile"] ''FileSystem++instance HasLogFunc TestEnv where+ logFuncL = envLogFuncL++instance Has CtHeaderFnConfigs TestEnv where+ hasLens = envHeaderFnConfigsL++instance Has CurrentYear TestEnv where+ hasLens = envCurrentYearL++instance Has (FileSystem (RIO TestEnv)) TestEnv where+ hasLens = envFileSystemL++ spec :: Spec spec = do describe "loadBuiltInTemplates" $ do it "should load correct number of built-in templates" $ do templates <- runRIO env $ loadBuiltInTemplates BSD3- M.size templates `shouldBe` 10+ M.size templates `shouldBe` 11 describe "loadTemplateFiles" $ do it "should load templates from given paths" $ do- templates <- runRIO env $ loadTemplateFiles ["test-data" </> "templates"]+ let env' =+ env+ & (envFileSystemL . fsFindFilesByExtsL .~ fsFindFilesByExts')+ & (envFileSystemL . fsLoadFileL .~ fsLoadFile')+ fsFindFilesByExts' "test-dir" _ = pure ["haskell.mustache"]+ fsFindFilesByExts' _ _ = throwString "INVALID CONDITION"+ fsLoadFile' "haskell.mustache" = pure "template content"+ fsLoadFile' _ = throwString "INVALID CONDITION"+ templates <- runRIO env' $ loadTemplateFiles ["test-dir"] M.size templates `shouldBe` 1 M.member Haskell templates `shouldBe` True @@ -98,8 +132,17 @@ env :: TestEnv env = TestEnv { .. } where- envLogFunc = mkLogFunc (\_ _ _ _ -> pure ())- envCurrentYear = CurrentYear 2020+ envLogFunc = mkLogFunc (\_ _ _ _ -> pure ())+ envCurrentYear = CurrentYear 2020+ envFileSystem = FileSystem { fsCreateDirectory = undefined+ , fsDoesFileExist = undefined+ , fsFindFiles = undefined+ , fsFindFilesByExts = undefined+ , fsFindFilesByTypes = undefined+ , fsGetCurrentDirectory = undefined+ , fsListFiles = undefined+ , fsLoadFile = undefined+ } envHeaderFnConfigs = HeaderFnConfigs { hfcsUpdateCopyright = HeaderFnConfig { hfcEnabled = True@@ -109,19 +152,3 @@ } } }--data TestEnv = TestEnv- { envLogFunc :: !LogFunc- , envHeaderFnConfigs :: !CtHeaderFnConfigs- , envCurrentYear :: !CurrentYear- }-suffixLenses ''TestEnv--instance HasLogFunc TestEnv where- logFuncL = envLogFuncL--instance Has CtHeaderFnConfigs TestEnv where- hasLens = envHeaderFnConfigsL--instance Has CurrentYear TestEnv where- hasLens = envCurrentYearL
+ test/Headroom/Ext/JavaSpec.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}+module Headroom.Ext.JavaSpec+ ( spec+ )+where++import Headroom.Configuration.Types ( HeaderConfig(..)+ , HeaderSyntax(..)+ )+import Headroom.Ext.Java+import Headroom.FileSystem ( loadFile )+import Headroom.Variables ( mkVariables )+import RIO+import RIO.FilePath ( (</>) )+import Test.Hspec+++spec :: Spec+spec = do+ let codeSamples = "test-data" </> "code-samples"++ describe "extractPackageName" $ do+ it "extracts package name from Java source code" $ do+ sample <- loadFile $ codeSamples </> "java" </> "sample1.java"+ extractPackageName sample `shouldBe` Just "foo"+++ describe "extractVariables" $ do+ it "extracts variables from Java source code" $ do+ let config = HeaderConfig ["java"] 0 0 [] [] (BlockComment "/*" "*/")+ meta = Nothing+ headerPos = Just (0, 2)+ expected = mkVariables [("_java_package_name", "foo")]+ sample <- loadFile $ codeSamples </> "java" </> "sample1.java"+ extractVariables config meta headerPos sample `shouldBe` expected
+ test/Headroom/Ext/PureScriptSpec.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}+module Headroom.Ext.PureScriptSpec+ ( spec+ )+where++import Headroom.Configuration.Types ( HeaderConfig(..)+ , HeaderSyntax(..)+ )+import Headroom.Ext.PureScript+import Headroom.FileSystem ( loadFile )+import Headroom.Variables ( mkVariables )+import RIO+import RIO.FilePath ( (</>) )+import Test.Hspec+++spec :: Spec+spec = do+ let codeSamples = "test-data" </> "code-samples"++ describe "extractVariables" $ do+ it "extracts variables from PureScript source code" $ do+ let config = HeaderConfig ["purs"] 0 0 [] [] (LineComment "--")+ meta = Nothing+ headerPos = Just (1, 13)+ expected = mkVariables [("_purescript_module_name", "Test")]+ sample <- loadFile $ codeSamples </> "purescript" </> "full.purs"+ extractVariables config meta headerPos sample `shouldBe` expected
test/Headroom/ExtSpec.hs view
@@ -38,3 +38,21 @@ sample <- readFileUtf8 $ samplesDir </> "haskell" </> "full.hs" extractVariables Haskell config meta (Just (1, 13)) sample `shouldBe` expected++ it "extracts variables specific for Java file type" $ do+ let samplesDir = "test-data" </> "code-samples"+ config = HeaderConfig ["java"] 0 0 [] [] (BlockComment "/*" "*/")+ meta = Nothing+ expected = mkVariables [("_java_package_name", "foo")]+ sample <- readFileUtf8 $ samplesDir </> "java" </> "sample1.java"+ extractVariables Java config meta (Just (0, 2)) sample `shouldBe` expected++ it "extracts variables specific for PureScript file type" $ do+ let samplesDir = "test-data" </> "code-samples"+ config = HeaderConfig ["purs"] 0 0 [] [] (LineComment "--")+ meta = Nothing+ expected = mkVariables [("_purescript_module_name", "Test")]+ sample <- readFileUtf8 $ samplesDir </> "purescript" </> "full.purs"+ extractVariables PureScript config meta (Just (1, 1)) sample+ `shouldBe` expected+