Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fields parser #4702

Merged
merged 2 commits into from
Sep 20, 2017
Merged

Fields parser #4702

merged 2 commits into from
Sep 20, 2017

Conversation

phadej
Copy link
Collaborator

@phadej phadej commented Aug 16, 2017

this is PoC of approach to parse fields

The difference is visible in FieldDescr.hs and Cabal/Distribution/PackageDescription/Parsec.hs


Please include the following checklist in your PR:

  • Patches conform to the coding conventions.
  • Any changes that could be relevant to users have been recorded in the changelog.
  • The documentation has been updated, if necessary.

Please also shortly describe how you tested your change. Bonus points for added tests!

@phadej phadej requested review from 23Skidoo and hvr August 16, 2017 23:33
@mention-bot
Copy link

@phadej, thanks for your PR! By analyzing the history of the files in this pull request, we identified @ezyang, @23Skidoo and @Ericson2314 to be potential reviewers.


sourceRepoFieldDescrs :: [FieldDescr SourceRepo]
sourceRepoFieldDescrs =
[ simpleField "type"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like this boilerplate

<*> affineFieldAla "module" Token repoModule
<*> affineFieldAla "branch" Token repoBranch
<*> affineFieldAla "tag" Token repoTag
<*> affineFieldAla "subdir" FilePathNT repoSubdir
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the applicative value will live somewhere else, as we'll need it for pretty-printer

uniqueField = error "define me"

-- | Field which can be defined at most once.
affineField
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rename to optionalField

parser fields = case Map.lookup fn fields of
Nothing -> pure Nothing
Just [] -> pure Nothing
Just [MkNamelessField pos fls] -> Just . (unpack :: b -> a) <$> runFieldParser pos parsec fls
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: if many fields, take last.

-- Newtype
-------------------------------------------------------------------------------

class Newtype n o | n -> o where
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phadej
Copy link
Collaborator Author

phadej commented Aug 16, 2017

The core point is that "if you add a field, FieldFancy will break".

@@ -297,7 +300,18 @@ parseGenericPackageDescription' lexWarnings fs = do
_ -> do
parseFailure pos $ "Invalid source-repository kind " ++ show args
pure RepoHead
sr <- parseFields sourceRepoFieldDescrs warnUnrec (emptySourceRepo kind) fields
Copy link
Collaborator Author

@phadej phadej Aug 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also note that one won't need fishy emptySourceRepo anymore, and similars for other types!

pack = FilePathNT
unpack = getFilePathNT

instance Text FilePathNT
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text instances will be replaced with Display class (I once tried to add, but I have to try again!)

-- functions such as 'ala'.
module Distribution.Compat.Newtype where

-- TODO: export only Newtype (..), ala
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please!

ala' _ hof f = unpack . hof (pack . f)

-------------------------------------------------------------------------------
-- Move to own module
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please.

@phadej phadej force-pushed the fields-parser branch 3 times, most recently from f2dc34a to 73304e6 Compare August 17, 2017 13:19
<*> optionalFieldAla "module" Token repoModule
<*> optionalFieldAla "branch" Token repoBranch
<*> optionalFieldAla "tag" Token repoTag
<*> optionalFieldAla "subdir" FilePathNT repoSubdir
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this patch thunk is the reason for new functionality.

@phadej phadej force-pushed the fields-parser branch 16 times, most recently from f1a7752 to 60e0f79 Compare August 20, 2017 15:42
@phadej phadej force-pushed the fields-parser branch 14 times, most recently from 690a725 to 4d6057b Compare September 5, 2017 07:40
@phadej
Copy link
Collaborator Author

phadej commented Sep 5, 2017

This PR is ready. I'll write a changelog stub separately.

@phadej phadej mentioned this pull request Sep 8, 2017
3 tasks
Copy link
Member

@hvr hvr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big patch, and tbh, it had a bit of noise (import-list & pragma-list normalisations) that made it more difficult to focus on what matters.

Btw, now I understand why you'd want a parser abstraction along the lines of http://hackage.haskell.org/package/parsers...

However, I couldn't see anything obviously bad, so this looks good for me. Afaik, @23Skidoo wanted to give this PR a review as well.

@23Skidoo
Copy link
Member

23Skidoo commented Sep 9, 2017

it had a bit of noise (import-list & pragma-list normalisations)

I usually just ignore this stuff. If something's wrong with it, CI will tell you.

@phadej
Copy link
Collaborator Author

phadej commented Sep 14, 2017

@23Skidoo are you planning to review this, or should I merge?

@23Skidoo
Copy link
Member

@phadej Sorry for the delay, I'll try to finish the review today.

-- Fields can be specified multiple times in the .cabal files. The order of
-- such entries is important, but the mutual ordering of different fields is
-- not.Also conditional sections are considered after non-conditional data.
-- The example of this silent-commutation quirck is the fact that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/quirck/quirk/

Copy link
Member

@23Skidoo 23Skidoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing job! LGTM modulo minor comments. Sorry for procrastinating with the review.

@@ -274,18 +277,22 @@ library
parsec >= 3.1.9 && <3.2
exposed-modules:
Distribution.Compat.Parsec
Distribution.FieldGrammar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, can this stuff live under e.g. Distribution.Parsec.FieldGrammar instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's both related to Parsing and Pretty-printing, and actually will be a little related to command line parsing too.

x <- parse contents
let contents' = showGenericPackageDescription x
y <- parse (toUTF8BS contents')
let y' = if x ^. L.packageDescription . L.license == UnspecifiedLicense
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a comment here explaining why special-casing of UnknownLicense "UnspecifiedLicense" is needed here and whether we can make it go away in the future?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will hopefully go away in SPDX change. The short explanation is that parse . pretty roundtrip on License doesn't hold ATM. Yet Hackage never accepts a package with UnspecifiedLicense, so I didn't bother to refactor it yet.

y0 <- parse "2nd" (toUTF8BS bs')

-- unspecified license
let y1 = if x0 ^. L.packageDescription . L.license == UnspecifiedLicense
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some duplication here with the ParserTests module. Maybe worth consolidating various data scrubbing utilities used in the parser test suite in a single place somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll think about license stuff particularly when doing SPDX change, but yeah, there are commonalities. I'll factor them out in separate PR.


showToken :: String -> PP.Doc
showToken str
| "--" `isPrefixOf` str = PP.text (show str)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice with a comment here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment, but --foo looks like a comment.

(^^^) :: a -> (a -> b) -> b
x ^^^ f = f x

-- | Partitionin state
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Partititionin/Partitioning/.

@phadej
Copy link
Collaborator Author

phadej commented Sep 19, 2017

I'll fix typos and add comments tomorrow. If there is no objection I'll merge this after that.

This commit reworks how GenericPackageDescription is parsed from
`[Field Position]` and pretty-printed to `Doc`.

This also fixes few issues:
- Fix haskell#4697: `cabal format` doesn't output custom-setup stanza (nor
  foreign-lib stanzas)
- Fix haskell#4719: `parse . pretty . parse = parse`  for all Hackage cabal files.
    - `parser-hackage-tests roundtrip` is the test program.

The handling of `license-file` and `license-files` is changed.
Now they behave the same.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants