Coder Social home page Coder Social logo

dhall-to-cabal's Introduction

Dhall Logo

Dhall is a programmable configuration language optimized for maintainability.

You can think of Dhall as: JSON + functions + types + imports

Note that while Dhall is programmable, Dhall is not Turing-complete. Many of Dhall's features take advantage of this restriction to provide stronger safety guarantees and more powerful tooling.

You can try the language live in your browser by visiting the official website:

Getting started

The easiest way to get started experimenting with Dhall is to install the dhall-to-json and/or dhall-to-yaml executables, which enable you to generate JSON and YAML, respectively, on the command line. Platform- and runtime-specific installation instructions can be found in the Dhall documentation.

For other ways to integrate Dhall in your project, read:

Tutorials

For a short introduction, read:

To learn more about core language features, read:

For an even longer hands-on tutorial, read:

... and for an even longer tutorial, read:

Finally, we have a cheatsheet for a very condensed overview and quick lookup:

What is this repository?

The Dhall configuration language has multiple implementations so that Dhall configuration files can be understood natively by several programming languages. You can find the latest list of the language bindings and their respective repositories here:

This repository contains language-independent functionality, such as:

  • The grammar and formal semantics

    Dhall is a formally-specified language standard, and language bindings follow the specification in order to ensure portability of Dhall configuration files across language bindings.

  • The standard test suite

    This repository contains a test suite that language bindings can use to check compliance against the standard.

  • The Prelude

    One Dhall package named the Prelude is versioned with and distributed alongside the language standard. This package contains general-purpose utilities.

  • Shared infrastructure for the Dhall ecosystem

    Several services support Dhall developers and this repository contains a NixOps specification of that infrastructure that automatically deploys changes merged to that configuration.

Development status

The current version and versioning policy is detailed in the Versioning document, and you can see the latest changes in the Changelog.

The Dhall configuration language slowly evolves in response to user feedback and if you would like to participate in the language evolution process then you should read:

Design philosophy

Programming languages are all about design tradeoffs and the Dhall language uses the following guiding principles (in order of descending priority) that help navigate those tradeoffs:

  • Polish

    The language should delight users. Error messages should be fantastic, execution should be snappy, documentation should be excellent, and everything should "just work".

  • Simplicity

    When in doubt, cut it out. Every configuration language needs bindings to multiple programming languages, and the more complex the configuration language the more difficult to create new bindings. Let the host language that you bind to compensate for any missing features from Dhall.

  • Beginner-friendliness

    Dhall needs to be a language that anybody can learn in a day and debug with little to no assistance from others. Otherwise people can't recommend Dhall to their team with confidence.

  • Robustness

    A configuration language needs to be rock solid. The last thing a person wants to debug is their configuration file. The language should never hang or crash. Ever.

  • Consistency

    There should only be one way to do something. Users should be able to instantly discern whether or not something is possible within the Dhall language or not.

The Dhall configuration language is also designed to negate many of the common objections to programmable configuration files, such as:

"Config files shouldn't be Turing complete"

Dhall is not Turing-complete. Evaluation always terminates, no exceptions

"Configuration languages become unreadable due to abstraction and indirection"

Every Dhall configuration file can be reduced to a normal form which eliminates all abstraction and indirection

"Users will go crazy with syntax and user-defined constructs"

Dhall is a very minimal programming language. For example: you cannot even compare strings for equality. The language also forbids many other common operations in order to force users to keep things simple

Name

The language is named after a Dustman from the game Planescape: Torment who belongs to a faction obsessed with death (termination). The fountain pen in the logo is the modern analog of Dhall's quill.

The name rhymes with "tall"/"call"/"hall" (i.e. "dɔl" for a US speaker or "dɔːl" for a UK speaker using the International Phonetic Alphabet).

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

dhall-to-cabal's People

Contributors

dependabot[bot] avatar f-f avatar gabriella439 avatar jneira avatar mstksg avatar ocharles avatar quasicomputational avatar robbiemcmichael avatar sjakobi avatar toonn avatar vaibhavsagar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dhall-to-cabal's Issues

Compatibility and upgrade guidelines for Dhall code

The type of the input Dhall expression to dhall-to-cabal is going to have to change sooner or later. If a future version of Cabal introduces a new feature (which it's surely going to), then dhall-to-cabal is going to expect a different type, and never mind any other changes it might be necessary or useful to make.

We probably should have some kind of story here about what user code can do to avoid fragility and what to do when the breaking update comes.

One idea might be to say that the prelude's defaults should be used as much as possible, and to avoid writing explicit sum types in user code. If new fields or constructors are added, this provides a reasonable upgrade path: just change the version of the prelude you're importing and off you go. It deals well even if existing fields or constructors are changed: only the parts directly affected will need additional changes.

However, this sort of resilience isn't preserved by normalisation or import resolution. Maybe we should warn about that in the docs or something?

We can detect if an expression isn't importing prelude.dhall and types.dhall and warn, which isn't foolproof but should have very good false positive and false negative rates; the question is whether that's a good idea.

A second, complimentary possibility: we could provide a compatibility Dhall function, accepting the old Package type and returning a new one. That's more work for us, and it might only be a deferral of the pain for users if they've somehow painted themselves into a corner where upgrading is hard. Possibly worth experimenting with partial normalisation to see if that gives good results here.

Finally we might advise users who are in an upgrade corner to put their generated Cabal files through cabal-to-dhall and then refactor the Dhall as necessary. At least the presence of this option will keep users from being totally trapped by legacy Dhall code. Maybe we can make cabal-to-dhall better (e.g., floating out common dependency versions to the top level?) so that less manual refactoring is needed to get back to where you were; on the other hand, it's slightly difficult to predict what will be useful here without having seen how dhall-to-cabal gets used in the wild and what sorts of abstracting users do.

None of this is critical or needs solving soon, mostly because anyone using dhall-to-cabal today had better have a taste for adventure, but it's something to think about for the future if we want to become a Serious Tool.

Let --print-type reference by import

Currently, --print-type will generate self-contained output. This is good for some use-cases, but it is troublesome when there are large enumerations in play. It's annoying enough with Extension today, but it's going to get a lot worse with #42. I think the route forward here is to provide a toggle between referencing types by import and directly including them.

Add a header to generated .cabal files

The header should warn against hand-modifying the file, mention dhall-to-cabal was used to generate it, and, ideally, name the file that it was generated from (if the filename was passed to dhall-to-cabal).

Release 1.0

I'm pretty much done with everything to get this project off the ground and released. To recap, we currently have:

  • A complete Dhall.Type that extracts a GenericPackageDescription. This is the same type that Cabal's parser parses into. As far as I know, the extraction is complete - there is nothing in a .cabal file that can't be said in dhall-to-cabal .dhall file. This type is in types/Package.dhall.
  • A bunch of Dhall files that correspond to types and empty values in Cabal files. See dhall/types and dhall/defaults
  • The helper functions GitHub-project and v (built-in Text -> Version).
  • A dhall-to-cabal executable that takes a Dhall file and outputs a .cabal file to stdout.

This lets us write Dhall expressions that output Cabal files such as this one: dhall-to-cabal.dhall.

So, where do we go from here? What's missing?

dhall-to-cabal performance has regressed

For 1.0.0.1

$ time ./dist/build/dhall-to-cabal/dhall-to-cabal dhall-to-cabal.dhall

real	0m6.735s
user	0m6.628s
sys	0m0.106s

For 1.1.0.0

$ time ./dist/build/dhall-to-cabal/dhall-to-cabal dhall-to-cabal.dhall

real	0m53.553s
user	0m52.914s
sys	0m0.562s

Ouch! Hopefully @quasicomputational's work on Dhall itself will help fix this.

Require Cabal 2.1

This is needed for Cabal's pretty printer to actually work. Unfortunately, this isn't out yet.

Wrong CWD handling

Consider running dhall-to-cabal foo/bar.dhall. The input file name could have relative imports, which have to be resolved relative to foo/. However, we read the file and then process it totally divorced of that directory information: we'll try to resolve imports relative to the current working directory.

This isn't trivially fixable in dhall-to-cabal: we need some extra API from dhall itself to specify what directory an expression's imports should be resolved relative to.

Produce complete PackageDescriptions

Step one is to produce a complete PackageDescription value from a Dhall expression. This is the unconditional version of a .cabal file. Currently the https://github.com/ocharles/dhall-to-cabal/blob/master/Distribution/Package/Dhall.hs#L65 packageDescription Dhall interpreter is total, but fills many things in with defaults. All of these defaults need to be replaced with a recursive-descent into the given Dhall expression.

If you want to help, make small pull requests, or maybe mention here if you want to "claim" responsibility for a bunch of fields.

More test cases

Currently the golden tests only test this projects cabal file. We should have more test cases. The idea would be to take Cabal files from Hackage, and add them as the golden output. Contributors will need to write a Dhall expression that produces that Cabal file. If that can't be done, then we've found a bug in dhall-to-cabal, hurrah!

I would love failing test cases - you don't even have to provide a fix for the failing test.

Produce GenericPackageDescriptions

Step two is to produce GenericPackageDescriptions. My thought here is to introduce variables like os into the typing environment, but keep them as free variables and block normalization. We normalize as far as we can, and then I can reflect underlying if expressions from Dhall to CondTree expressions in the Cabal file.

Thus, we would be writing

build-dependencies = [ ... ] ++ if os == Linux then [ ... ] else [ ... ]

to get

build-depends:
  ...
  if os(linux):
    ...

(or whatever the valid cabal syntax is)

@Gabriel439, does this sound sensible?

Remove Union, unionAlt, etc?

Using Union, unionAlt, etc in CabalToDhall leads to some cute definitions, but I'm not sure they're pulling their weight.

Losing warnings about incomplete pattern matches is a pretty big price to pay for some convenience! Also, I think we want to write most (all?) sum types in terms of prelude.types.*, rather than the often-much-larger union literals on users.

So I think we should remove these, and write the InputTypes directly. This can be done incrementally and there's no pressing need to get it done, though.

Add dabal (name subject to bike shedding)

It's a little tedious having to go from .dhall to .cabal and then to use cabal. We could add dabal, which is a wrapper around cabal. It would generate the .cabal file and then run cabal commands on it. It might be possible to do this without generating a file at all, which would be nice!

Allow concise error output

There should be some way to disable --explain mode. I actually think concise error messages should be the default (consistent with other dhall* command-line utilities) but I'd be willing to accept the converse: a flag to disable the verbose error messages

Use code formatter

How about using some formatter? I am not sure about the formatting that you would like to using stylish-haskell or brittany would help me do PRs with the right syntax.

Any preferences ?

Provide a standard library of Dhall expressions

Writing a full GenericPackageDescription is pretty horrible. This problem is compounded due to Optional always requiring a type signature. dhall-to-cabal should provide a standard library of Dhall expressions. I can roughly envision things like, simpleLibrary, executable, test-suite, and appropriate merging operators.

Add Travis (or some other CI)

@Profpatsch noticed a couple of problems while (presumably) trying to build dhall-to-cabal - firstly hitting some missing files. A CI server would have caught this. I haven't really set one of these up before, but if anyone has experience, this would be a great help.

Use defaults in cabal-to-dhall

cabal-to-dhall generates pretty big output, see, e.g., this test from #54, where four conditionals lead to 16 mostly-empty Library records. If defaults were used, it would look more like this, which is a lot less scary.

cabal-to-dhall does not terminate for some inputs involving conditionals

hi, executing cabal-to-dhall with this input:

name:                wai-servlet
version:             0.1.5.0
cabal-version:       2.0
                                          
Flag wai-servlet-debug
    Description: print debug output. not suitable for production
    Default:     False

library
  if impl(ghc >= 0.0.9.7)
     cpp-options:      -DINTEROP
  if impl(ghc < 0.7.0.2)
     cpp-options:      -DPURE_JAVA_WITH
  if impl(ghc >= 0.0.9)
     c-sources:        java/Utils.java
  if flag(wai-servlet-debug)
     cpp-options:      -DWAI_SERVLET_DEBUG

the execution hangs and eats a lot of memory, eventually exiting with:

C:\ws\eta\dhall\dhall-to-etlas>type golden-tests\wai-servlet-ghc.cabal | cabal-t
o-dhall > wai-servlet-ghc.gen.dhall
cabal-to-dhall: getMBlocks: VirtualAlloc MEM_COMMIT failed: The paging file is 
too small for this operation to complete..

If i remove any of the four conditions (including if flag(wai-servlet-debug)..) the program is able to convert the file.

Possibly remove Guarded?

#44 un-exports it from types.dhall, meaning that, if you want to use it, it's got to be imported separately. But it's not a big type anyway; types.Config -> a is only a bit longer than types.Guarded a, and it's arguably clearer. Maybe it makes more sense to always write it as the former, and to drop Guarded as a thing? It made a lot of sense to have Guarded when it was a record, but now that conditionals are done implicitly I'm not so sure.

Factor cabal-to-dhall's conditionals

#57 will help a lot with cutting down cabal-to-dhall's verbosity, but I've realised that it probably won't be enough for larger projects.

Consider lens as an example of a moderately large project that's likely to be typical: the library section has nine conditionals, about fifty exposed modules, and about twenty dependencies; each conditional only affects one or two fields. If we naively duplicate the library section for each conditional, that's a lot of bloat: it'll be about 2^9 * 70 ~ 35k lines!

Better would be to factor out the common parts between branches and then push the conditionals into the fields themselves. That is, rather than:

  library = \ (config : Config) ->
    if minGHC config "8.0"
    then defaults.Library
     // { exposed-modules = ...
        , build-depends = ...
        }
    else defaults.Library
    // { exposed-modules = ...
       , build-depends = [ deps.generics-deriving ] # ...
       }

we'd generate code like

  library = \ (config : Config) ->
        defaults.Library
     // { exposed-modules = ...
        , build-depends =
            ( if minGHC config "8.0"
              then []
              else [ deps.generics-deriving ]
            ) # ...
        }

I think this might need a heuristic for when it's not helpful (little in common between the branches), but maybe that'll be so rare that it wouldn't be worth the bother.

Conditionals with inner conditionals have their branches reversed

Input:

   let prelude = ./dhall/prelude.dhall 
in let types = ./dhall/types.dhall 
in let v = prelude.v
in let compiler = constructors types.Compiler
in   prelude.defaults.Package
  // { version = v "0"
     , library =
       [ \ (config : ./dhall/types/Config.dhall) -> prelude.defaults.Library
           // { compiler-options = prelude.defaults.CompilerOptions
                 // { GHC = [ "-Weverything" ]
                        # (if config.impl (compiler.GHC {=}) (prelude.orLaterVersion (v "8.2"))
                             then [ "-Wno-redundant-constraints" ] : List Text
                             else [] : List Text)
                        # (if config.impl (compiler.GHC {=}) (prelude.orLaterVersion (v "8.4"))
                             then [ "-Wno-missing-export-lists" ] : List Text
                             else [] : List Text)
                    }
              }
       ] : Optional (./dhall/types/Guarded.dhall types.Library)
     }

Output:

$ dhall-to-cabal example.dhall 
name: 
version: 0
cabal-version: 2.0
build-type: Simple
license: UnspecifiedLicense

library
    
    if impl(ghc >=8.2)
        
        if impl(ghc >=8.4)
            ghc-options: -Weverything -Wno-missing-export-lists
        else
            ghc-options: -Weverything
    else
        
        if impl(ghc >=8.4)
            ghc-options: -Weverything -Wno-redundant-constraints -Wno-missing-export-lists
        else
            ghc-options: -Weverything -Wno-redundant-constraints

The branches of the outer conditional seem to be reversed.

Support for flags

A continuation from #2. I have an idea (or at least, did at one point!) for how I want to do this...

README has stale versioned links

Not submitting a PR (yet) because it's not quite obvious what the Right Thing here is.

If the links were made relative (and the examples were put into extra-doc-files), we would be doing the right thing: sdists, installed versions, browsing the repository on GitHub, etc would all be linking to appropriate versions. But relative links will break in Hackage's README display (I think? I haven't actually checked).

If we go with explicitly versioned links (i.e., just bump the version), then we've got to remember to bump all of them with each release, and HEAD will be pointing to the last released version, which might not be current.

If we go with unversioned links, then sdists, installed versions and Hackage will have links pointing to potentially bleeding-edge examples that won't work with the released versions.

cabal-to-dhall golden tests requires diff program (not present by default in win)

Hi! Afaik the awesome new test group cabal-to-dhall by @quasicomputational needs to execute the diff program and the poor souls that are in windows doesn't have it by default, ¿could be easily replaced with calls to Diff haskell package (already in scope)?

In windows all the tests fail with

  cabal-to-dhall
    simple:                   FAIL
      Exception: diff: createProcess: does not exist (No such file or directory)

    gh-36:                    FAIL
      Exception: diff: createProcess: does not exist (No such file or directory)

    conditional-dependencies: FAIL
      Exception: diff: createProcess: does not exist (No such file or directory)

There are workarounds:

(Tested in windows 7 with 7fe5edd version and cabal 2.2.0.0)

Ergonomics versus Cabal-faithfulness in defaults

Some of Cabal's defaults for fields are not great for ergonomics and boilerplate reduction. In #112 I suggested setting our default default-language to Haskell2010, which is what about 99.5% of code is going to want. @ocharles reasonably pointed out two things: this is a divergence from what Cabal does, and Dhall is powerful enough that users can define their own defaults.

Regarding the first point, hpack fills in these sorts of things by default and people don't seem to mind it, but dhall-to-cabal does hew rather more closely to Cabal.

Regarding the second point, that's also correct, but I'd like to see dhall-to-cabal have great out-of-the-box usability without having to get into abstraction and possibly forking upstream code for simple things like default-language, where there is a sensible choice of default.

We've got the capability now to define multiple sets of defaults in Haskell code and to manipulate them as first-class objects. Maybe this offers a solution: two sets of defaults, a 'give me what Cabal does' set and then an opinionated set targetting boilerplate reduction and ergonomics (or possibly several opinionated sets with different objectives). cabal-to-dhall can learn to switch between them (and then let the meta-default debate begin), and users can easily get at one or the other by changing prelude.defaults to prelude.defaults-extra in their code.

Have a canonical type or embrace a more flexible encoding?

e154561 begins an exploration of giving up a canonical type for cabal files to produce a more lightweight syntax. That commit only begins the work, but one could imagine writing:

    let empty-package = ./dhall/empty-package.dhall 

in  let licenses = constructors ./dhall/types/License 

in  let extensions = constructors ./dhall/types/Extension 

in  let gitHub-project = ./dhall/gitHubProject.dhall 

in    gitHub-project { owner = "ocharles", repo = "dhall-to-cabal" }
     { executables =
          { dhall-to-cabal =
                ./dhall/defaults/Executable.dhall 
               { build-dependencies =
                    { dhall-to-cabal = anyVersion
                    , optparse-applicative =
                        unionVersionRanges
                          (majorBoundVersion [ +0, +13, +2 ])
                          (majorBoundVersion [ +0, +14 ])
                    }
                , hs-source-dirs     = [ "exe" ]
                , main-is            = "Main.hs"
                , other-extensions   = [ extensions.NamedFieldPuns {=} ]
                }
          }
      , library     =
            ./dhall/defaults/Library.dhall 
           { build-dependencies =
                { containers = majorBoundVersion [ +0, +5 ]
                , ..
                }
            , compiler-options   =
                  ./dhall/defaults/CompilerOptions 
                 { GHC =
                      { build-options = [ "-Wall", "-fno-warn-name-shadowing" ]
                      }
                  }
            , exposed-modules    = [ "Distribution.Package.Dhall" ]
            , hs-source-dirs     = [ "lib" ]
            , other-extensions   =
                [ extensions.ApplicativeDo {=}
                , extensions.GADTs {=}
                , extensions.GeneralizedNewtypeDeriving {=}
                , extensions.LambdaCase {=}
                , extensions.OverloadedStrings {=}
                , extensions.RecordWildCards {=}
                , extensions.TypeApplications {=}
                ]
            , other-modules      = [ "Dhall.Extra" ]
            }
      , license     = licenses.MIT {=}
      , package     = { name = "dhall-to-cabal", version = [ +0, +1, +0 ] }
      }

Here both the top-level record has no canonical type, but nor do build-dependencies.

CC @Gabriel439

Accept inline Dhall expressions on the command line

One way to do this would be to accept the Dhall expression on standard input similar to how the other dhall* command-line utilities work, but I'd be fine with any other approach. The rationale behind this is that:

  • Anything that accepts inline Dhall expressions on the command line automatically accepts file imports by virtue of Dhall's import system
  • This makes it easier to generate a .cabal file in a single command line invocation (i.e. dhall-to-cabal <<< 'http://example.com/YesodProject { name = "foo" }')

dhall-to-cabal.cabal: NoParse "scope"

On current nixpkgs master (as well as master 4 weeks back), invoking nix-shell fails:

building path(s) ‘/nix/store/jwg9s7qz6aj8fhpz2m54jzaxkqg5glrz-cabal2nix-dhall-to-cabal’
installing
*** parsing cabal file: user error (cannot parse "/nix/store/pbcxflfkppxjk1sldsp2x0v6y5fj0393-dhall-to-cabal/dhall-to-cabal.cabal": NoParse "scope" 38)
cabal2nix: nix-prefetch-zip: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory)
builder for ‘/nix/store/b8iqh190j7xjy8q3n29xbxv55yim48ck-cabal2nix-dhall-to-cabal.drv’ failed with exit code 1
error: build of ‘/nix/store/b8iqh190j7xjy8q3n29xbxv55yim48ck-cabal2nix-dhall-to-cabal.drv’ failed
(use ‘--show-trace’ to show detailed location information)

empty-package.dhall does not produce a valid cabal file

While PackageDescription allows an empty name to type check, it does not produce a valid Cabal file.

Ideas:

  • Perhaps empty-package should be a function taking a name
  • Perhaps we should introduce a primitive NonEmptyString type and smart constructor.
  • dhall-to-cabal could also learn some basic validation rules too, and produce its own errors outside Dhall.

The latter is probably the way to go, though it'd be nice if empty-package could produce something that doesn't error.

Correct divergences from cabal field names

E.g., we have

  • build-dependencies but build-depends in Cabal
  • source-repos but source-repositories in Cabal

I'm sure there are more. There is no good reason to rename these fields.

Spec-version-specific Package types

From #98:

It turns out that it's easy to generate invalid .cabal files for cabal-version: 2.2, because non-SPDX licenses aren't at all supported, and pre-2.2 spec versions will fail with SPDX. So, if we want to follow the dictum of 'make illegal states unrepresentable', we should change the Package type to be a union of pre-2.2 and post-2.2 records, or do something similar.

There are some other cases where we'd want to do this (e.g., no autogen-modules before whichever version that was introduced in), as well.

Add to Stackage?

It'd be nice to have dhall-to-cabal in Stackage for some purposes. I don't think it'd be much extra effort since we want to keep up with dhall and Cabal anyway, which are our two likeliest candidates for breakage, though we would need to match dhall's release cadence if only to bump bounds.

Factor out common parts of types/{Library,ForeignLibrary,Executable,Benchmark,TestSuite}.dhall

Most of all of those files are what we might call 'BuildInfo', following Cabal, plus a few component-specific fields. When that code was written, Dhall didn't have a way to combine record types. But now the //\\ operator is a thing, and we can factor out all 28 or so shared fields (plus another 10 when #42 lands) into a new file types/BuildInfo.dhall, and then define them with reference to that plus their idiosyncratic fields.

This has an additional benefit because then you can define libraryBuildInfo : Library -> BuildInfo, executableBuildInfo, etc, and then write mapBuildInfo : (BuildInfo ->Config -> BuildInfo) -> Package -> Package to, e.g., conveniently add warnings to all components.

It'd be nice if --print-type would output the build components in terms of BuildInfo too.

Pretty-print cabal-to-dhall's output

cabal-to-dhall currently outputs a potentially-large, unformatted blob of Dhall. Considering especially that experimenting with cabal-to-dhall could be someone's first taste of Dhall, this is particularly bad UX. We should figure out how to wire up Dhall's pretty-printing to our output.

Add support for cabal-version field values in the form ">= 1.10"

Hi, it seems dhall-to-cabal dont support the >= 1.10 value in the field, only a simple version like 2.0.
However cabal files referencing cabal specs below 1.12 must use the form >= 1.10. Although packages should update those versions i guess there are many of them using it yet.
Not sure about how to implement it in dhall-to-cabal and cabal-to-dhall:

  • an option could change the dhall type of cabal-version to < Left : ./Version.dhall | Right : ./VersionRange.dhall >
    • like the cabal lib underlying type specVersionRaw :: Either Version VersionRange
    • but in fact cabal only allow simple versions or >= 1.10

Thanks!

Cabal 2.4.0.0

I think the relevant lines from the changelog are:

  • KnownExtension: added new extensions BlockArguments (#5101), NumericUnderscores (#5130, QuantifiedConstraints, and StarIsType.
  • buildDepends is removed from PackageDescription. It had long been uselessly hanging about as top-level build-depends already got put into per-component condition trees anyway. Now it's finally been put out of its misery (#4383).
  • Added Eta to CompilerFlavor and to known compilers.
  • Allow ** wildcards in data-files, extra-source-files and extra-doc-files. These allow a limited form of recursive matching, and require cabal-version: 2.4. (#5284, #3178, et al.)

Error using cached version of prelude and types (using master version of dhall)

Hi, i've setup a fork to use the near next versión of dhall, 1.17 with cached imports with hashes (fork diff)
It includes a test case using a local import hashed and after caching the prelude and types it fails:

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>dir C:\Users\user\AppData\Local\dhall /B

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>dhall-to-cabal < dhall-to-cabal-http.dhall
cabal-version: 2.2
<rest of correct cabal output>

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>dir C:\Users\user\AppData\Local\dhall /B
39919f424375b417e118f94da599d69bbff58b63d418fa7a1bf914005c780f06
f3ffaa13c8f2e82121145d4602ee38861b7bacbc3427649e1e6a844e448a7159

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>dhall-to-cabal < dhall-to-cabal-http.dhall
dhall-to-cabal: App (Var (V "_" 0)) (TextLit (Chunks [] "1.0.0"))
CallStack (from HasCallStack):
  error, called at lib\DhallToCabal.hs:245:11 in dhall-to-cabal-1.3.0.1-DeqFZykxniiI9HWlOcxoWI:DhallToCabal

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>del C:\Users\user\AppData\Local\dhall\39919f424375b417e118f94da599d69bbff58b63d418fa7a1bf914005c780f06

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>del C:\Users\user\AppData\Local\dhall\f3ffaa13c8f2e82121145d4602ee38861b7bacbc3427649e1e6a844e448a7159

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>dir C:\Users\user\AppData\Local\dhall /B

C:\dhall-to-etlas\golden-tests\dhall-to-cabal>dhall-to-cabal < dhall-to-cabal-http.dhall
cabal-version: 2.2
<rest of correct cabal output>

Not sure if it is a only dhall-to-cabal issue, but compiling the file with dhall itself works, with and without cache files.

When repeating conditions, only the first is honored

With this input:

   let prelude = ./dhall/prelude.dhall

in let types = ./dhall/types.dhall

in let v = prelude.v

in let ghcImpl =
       \ ( cfg : types.Config ) -> \ ( ver : types.VersionRange )
    -> cfg.impl ( prelude.types.Compilers.GHC {=} ) ver

in ./dhall/defaults/Package.dhall 
// { name =
       "Name"
   , version =
       ./dhall/types/Version/v.dhall  "1"
   , library =
        [ \ ( config : types.Config )
         -> prelude.defaults.Library
         // { exposed-modules =
                [ "Module1" ]
              # ( if ghcImpl config ( prelude.orLaterVersion ( v "7.1.3" ) )
                  then [ "Module2" ] else [ ] : List Text )
            , other-modules =
                ( if ghcImpl config ( prelude.orLaterVersion ( v "7.1.3" ) )
                  then [ "OtherModule" ] else [ ] : List Text )
            , cpp-options =
                ( if ghcImpl config ( prelude.orLaterVersion ( v "7.1.3" ) )
                  then [ "-DCOND1" ] else [ ] : List Text )
            }
        ] : Optional ( ./dhall/types/Guarded.dhall  types.Library )
        
   }

The output is:

name: Name
version: 1
cabal-version: 2.0
build-type: Simple
license: UnspecifiedLicense

library

    if impl(ghc >=7.1.3)
        exposed-modules:
            Module2
    exposed-modules:
        Module1
    cpp-options: -DCOND1
    other-modules:
        OtherModule

But it should be

name: Name
version: 1
cabal-version: 2.0
build-type: Simple
license: UnspecifiedLicense

library

    if impl(ghc >=7.1.3)
        exposed-modules:
            Module2
    exposed-modules:
        Module1
    if impl(ghc >=7.1.3)
        cpp-options: -DCOND1
    if impl(ghc >=7.1.3)
        other-modules:
           OtherModule

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.