packages feed

cabal-gild 0.2.1.1 → 0.3.0.0

raw patch · 96 files changed

+2550/−7290 lines, 96 filesdep +hspecdep +textdep +transformersdep −QuickCheckdep −mtldep −tastydep ~Cabal-syntaxdep ~basedep ~bytestring

Dependencies added: hspec, text, transformers

Dependencies removed: QuickCheck, mtl, tasty, tasty-hunit, tasty-quickcheck

Dependency ranges changed: Cabal-syntax, base, bytestring, containers, exceptions

Files

CHANGELOG.md view
@@ -1,4 +1,4 @@ # Change log -cabal-gild follows the [Package Versioning Policy](https://pvp.haskell.org).+Gild follows the [Package Versioning Policy](https://pvp.haskell.org). You can find release notes [on GitHub](https://github.com/tfausak/cabal-gild/releases).
LICENSE.txt view
@@ -1,674 +1,21 @@-              GNU GENERAL PUBLIC LICENSE-                Version 3, 29 June 2007-- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>- Everyone is permitted to copy and distribute verbatim copies- of this license document, but changing it is not allowed.--                     Preamble--  The GNU General Public License is a free, copyleft license for-software and other kinds of works.--  The licenses for most software and other practical works are designed-to take away your freedom to share and change the works.  By contrast,-the GNU General Public License is intended to guarantee your freedom to-share and change all versions of a program--to make sure it remains free-software for all its users.  We, the Free Software Foundation, use the-GNU General Public License for most of our software; it applies also to-any other work released this way by its authors.  You can apply it to-your programs, too.--  When we speak of free software, we are referring to freedom, not-price.  Our General Public Licenses are designed to make sure that you-have the freedom to distribute copies of free software (and charge for-them if you wish), that you receive source code or can get it if you-want it, that you can change the software or use pieces of it in new-free programs, and that you know you can do these things.--  To protect your rights, we need to prevent others from denying you-these rights or asking you to surrender the rights.  Therefore, you have-certain responsibilities if you distribute copies of the software, or if-you modify it: responsibilities to respect the freedom of others.--  For example, if you distribute copies of such a program, whether-gratis or for a fee, you must pass on to the recipients the same-freedoms that you received.  You must make sure that they, too, receive-or can get the source code.  And you must show them these terms so they-know their rights.--  Developers that use the GNU GPL protect your rights with two steps:-(1) assert copyright on the software, and (2) offer you this License-giving you legal permission to copy, distribute and/or modify it.--  For the developers' and authors' protection, the GPL clearly explains-that there is no warranty for this free software.  For both users' and-authors' sake, the GPL requires that modified versions be marked as-changed, so that their problems will not be attributed erroneously to-authors of previous versions.--  Some devices are designed to deny users access to install or run-modified versions of the software inside them, although the manufacturer-can do so.  This is fundamentally incompatible with the aim of-protecting users' freedom to change the software.  The systematic-pattern of such abuse occurs in the area of products for individuals to-use, which is precisely where it is most unacceptable.  Therefore, we-have designed this version of the GPL to prohibit the practice for those-products.  If such problems arise substantially in other domains, we-stand ready to extend this provision to those domains in future versions-of the GPL, as needed to protect the freedom of users.--  Finally, every program is threatened constantly by software patents.-States should not allow patents to restrict development and use of-software on general-purpose computers, but in those that do, we wish to-avoid the special danger that patents applied to a free program could-make it effectively proprietary.  To prevent this, the GPL assures that-patents cannot be used to render the program non-free.--  The precise terms and conditions for copying, distribution and-modification follow.--                TERMS AND CONDITIONS--  0. Definitions.--  "This License" refers to version 3 of the GNU General Public License.--  "Copyright" also means copyright-like laws that apply to other kinds of-works, such as semiconductor masks.--  "The Program" refers to any copyrightable work licensed under this-License.  Each licensee is addressed as "you".  "Licensees" and-"recipients" may be individuals or organizations.--  To "modify" a work means to copy from or adapt all or part of the work-in a fashion requiring copyright permission, other than the making of an-exact copy.  The resulting work is called a "modified version" of the-earlier work or a work "based on" the earlier work.--  A "covered work" means either the unmodified Program or a work based-on the Program.--  To "propagate" a work means to do anything with it that, without-permission, would make you directly or secondarily liable for-infringement under applicable copyright law, except executing it on a-computer or modifying a private copy.  Propagation includes copying,-distribution (with or without modification), making available to the-public, and in some countries other activities as well.--  To "convey" a work means any kind of propagation that enables other-parties to make or receive copies.  Mere interaction with a user through-a computer network, with no transfer of a copy, is not conveying.--  An interactive user interface displays "Appropriate Legal Notices"-to the extent that it includes a convenient and prominently visible-feature that (1) displays an appropriate copyright notice, and (2)-tells the user that there is no warranty for the work (except to the-extent that warranties are provided), that licensees may convey the-work under this License, and how to view a copy of this License.  If-the interface presents a list of user commands or options, such as a-menu, a prominent item in the list meets this criterion.--  1. Source Code.--  The "source code" for a work means the preferred form of the work-for making modifications to it.  "Object code" means any non-source-form of a work.--  A "Standard Interface" means an interface that either is an official-standard defined by a recognized standards body, or, in the case of-interfaces specified for a particular programming language, one that-is widely used among developers working in that language.--  The "System Libraries" of an executable work include anything, other-than the work as a whole, that (a) is included in the normal form of-packaging a Major Component, but which is not part of that Major-Component, and (b) serves only to enable use of the work with that-Major Component, or to implement a Standard Interface for which an-implementation is available to the public in source code form.  A-"Major Component", in this context, means a major essential component-(kernel, window system, and so on) of the specific operating system-(if any) on which the executable work runs, or a compiler used to-produce the work, or an object code interpreter used to run it.--  The "Corresponding Source" for a work in object code form means all-the source code needed to generate, install, and (for an executable-work) run the object code and to modify the work, including scripts to-control those activities.  However, it does not include the work's-System Libraries, or general-purpose tools or generally available free-programs which are used unmodified in performing those activities but-which are not part of the work.  For example, Corresponding Source-includes interface definition files associated with source files for-the work, and the source code for shared libraries and dynamically-linked subprograms that the work is specifically designed to require,-such as by intimate data communication or control flow between those-subprograms and other parts of the work.--  The Corresponding Source need not include anything that users-can regenerate automatically from other parts of the Corresponding-Source.--  The Corresponding Source for a work in source code form is that-same work.--  2. Basic Permissions.--  All rights granted under this License are granted for the term of-copyright on the Program, and are irrevocable provided the stated-conditions are met.  This License explicitly affirms your unlimited-permission to run the unmodified Program.  The output from running a-covered work is covered by this License only if the output, given its-content, constitutes a covered work.  This License acknowledges your-rights of fair use or other equivalent, as provided by copyright law.--  You may make, run and propagate covered works that you do not-convey, without conditions so long as your license otherwise remains-in force.  You may convey covered works to others for the sole purpose-of having them make modifications exclusively for you, or provide you-with facilities for running those works, provided that you comply with-the terms of this License in conveying all material for which you do-not control copyright.  Those thus making or running the covered works-for you must do so exclusively on your behalf, under your direction-and control, on terms that prohibit them from making any copies of-your copyrighted material outside their relationship with you.--  Conveying under any other circumstances is permitted solely under-the conditions stated below.  Sublicensing is not allowed; section 10-makes it unnecessary.--  3. Protecting Users' Legal Rights From Anti-Circumvention Law.--  No covered work shall be deemed part of an effective technological-measure under any applicable law fulfilling obligations under article-11 of the WIPO copyright treaty adopted on 20 December 1996, or-similar laws prohibiting or restricting circumvention of such-measures.--  When you convey a covered work, you waive any legal power to forbid-circumvention of technological measures to the extent such circumvention-is effected by exercising rights under this License with respect to-the covered work, and you disclaim any intention to limit operation or-modification of the work as a means of enforcing, against the work's-users, your or third parties' legal rights to forbid circumvention of-technological measures.--  4. Conveying Verbatim Copies.--  You may convey verbatim copies of the Program's source code as you-receive it, in any medium, provided that you conspicuously and-appropriately publish on each copy an appropriate copyright notice;-keep intact all notices stating that this License and any-non-permissive terms added in accord with section 7 apply to the code;-keep intact all notices of the absence of any warranty; and give all-recipients a copy of this License along with the Program.--  You may charge any price or no price for each copy that you convey,-and you may offer support or warranty protection for a fee.--  5. Conveying Modified Source Versions.--  You may convey a work based on the Program, or the modifications to-produce it from the Program, in the form of source code under the-terms of section 4, provided that you also meet all of these conditions:--    a) The work must carry prominent notices stating that you modified-    it, and giving a relevant date.--    b) The work must carry prominent notices stating that it is-    released under this License and any conditions added under section-    7.  This requirement modifies the requirement in section 4 to-    "keep intact all notices".--    c) You must license the entire work, as a whole, under this-    License to anyone who comes into possession of a copy.  This-    License will therefore apply, along with any applicable section 7-    additional terms, to the whole of the work, and all its parts,-    regardless of how they are packaged.  This License gives no-    permission to license the work in any other way, but it does not-    invalidate such permission if you have separately received it.--    d) If the work has interactive user interfaces, each must display-    Appropriate Legal Notices; however, if the Program has interactive-    interfaces that do not display Appropriate Legal Notices, your-    work need not make them do so.--  A compilation of a covered work with other separate and independent-works, which are not by their nature extensions of the covered work,-and which are not combined with it such as to form a larger program,-in or on a volume of a storage or distribution medium, is called an-"aggregate" if the compilation and its resulting copyright are not-used to limit the access or legal rights of the compilation's users-beyond what the individual works permit.  Inclusion of a covered work-in an aggregate does not cause this License to apply to the other-parts of the aggregate.--  6. Conveying Non-Source Forms.--  You may convey a covered work in object code form under the terms-of sections 4 and 5, provided that you also convey the-machine-readable Corresponding Source under the terms of this License,-in one of these ways:--    a) Convey the object code in, or embodied in, a physical product-    (including a physical distribution medium), accompanied by the-    Corresponding Source fixed on a durable physical medium-    customarily used for software interchange.--    b) Convey the object code in, or embodied in, a physical product-    (including a physical distribution medium), accompanied by a-    written offer, valid for at least three years and valid for as-    long as you offer spare parts or customer support for that product-    model, to give anyone who possesses the object code either (1) a-    copy of the Corresponding Source for all the software in the-    product that is covered by this License, on a durable physical-    medium customarily used for software interchange, for a price no-    more than your reasonable cost of physically performing this-    conveying of source, or (2) access to copy the-    Corresponding Source from a network server at no charge.--    c) Convey individual copies of the object code with a copy of the-    written offer to provide the Corresponding Source.  This-    alternative is allowed only occasionally and noncommercially, and-    only if you received the object code with such an offer, in accord-    with subsection 6b.--    d) Convey the object code by offering access from a designated-    place (gratis or for a charge), and offer equivalent access to the-    Corresponding Source in the same way through the same place at no-    further charge.  You need not require recipients to copy the-    Corresponding Source along with the object code.  If the place to-    copy the object code is a network server, the Corresponding Source-    may be on a different server (operated by you or a third party)-    that supports equivalent copying facilities, provided you maintain-    clear directions next to the object code saying where to find the-    Corresponding Source.  Regardless of what server hosts the-    Corresponding Source, you remain obligated to ensure that it is-    available for as long as needed to satisfy these requirements.--    e) Convey the object code using peer-to-peer transmission, provided-    you inform other peers where the object code and Corresponding-    Source of the work are being offered to the general public at no-    charge under subsection 6d.--  A separable portion of the object code, whose source code is excluded-from the Corresponding Source as a System Library, need not be-included in conveying the object code work.--  A "User Product" is either (1) a "consumer product", which means any-tangible personal property which is normally used for personal, family,-or household purposes, or (2) anything designed or sold for incorporation-into a dwelling.  In determining whether a product is a consumer product,-doubtful cases shall be resolved in favor of coverage.  For a particular-product received by a particular user, "normally used" refers to a-typical or common use of that class of product, regardless of the status-of the particular user or of the way in which the particular user-actually uses, or expects or is expected to use, the product.  A product-is a consumer product regardless of whether the product has substantial-commercial, industrial or non-consumer uses, unless such uses represent-the only significant mode of use of the product.--  "Installation Information" for a User Product means any methods,-procedures, authorization keys, or other information required to install-and execute modified versions of a covered work in that User Product from-a modified version of its Corresponding Source.  The information must-suffice to ensure that the continued functioning of the modified object-code is in no case prevented or interfered with solely because-modification has been made.--  If you convey an object code work under this section in, or with, or-specifically for use in, a User Product, and the conveying occurs as-part of a transaction in which the right of possession and use of the-User Product is transferred to the recipient in perpetuity or for a-fixed term (regardless of how the transaction is characterized), the-Corresponding Source conveyed under this section must be accompanied-by the Installation Information.  But this requirement does not apply-if neither you nor any third party retains the ability to install-modified object code on the User Product (for example, the work has-been installed in ROM).--  The requirement to provide Installation Information does not include a-requirement to continue to provide support service, warranty, or updates-for a work that has been modified or installed by the recipient, or for-the User Product in which it has been modified or installed.  Access to a-network may be denied when the modification itself materially and-adversely affects the operation of the network or violates the rules and-protocols for communication across the network.--  Corresponding Source conveyed, and Installation Information provided,-in accord with this section must be in a format that is publicly-documented (and with an implementation available to the public in-source code form), and must require no special password or key for-unpacking, reading or copying.--  7. Additional Terms.--  "Additional permissions" are terms that supplement the terms of this-License by making exceptions from one or more of its conditions.-Additional permissions that are applicable to the entire Program shall-be treated as though they were included in this License, to the extent-that they are valid under applicable law.  If additional permissions-apply only to part of the Program, that part may be used separately-under those permissions, but the entire Program remains governed by-this License without regard to the additional permissions.--  When you convey a copy of a covered work, you may at your option-remove any additional permissions from that copy, or from any part of-it.  (Additional permissions may be written to require their own-removal in certain cases when you modify the work.)  You may place-additional permissions on material, added by you to a covered work,-for which you have or can give appropriate copyright permission.--  Notwithstanding any other provision of this License, for material you-add to a covered work, you may (if authorized by the copyright holders of-that material) supplement the terms of this License with terms:--    a) Disclaiming warranty or limiting liability differently from the-    terms of sections 15 and 16 of this License; or--    b) Requiring preservation of specified reasonable legal notices or-    author attributions in that material or in the Appropriate Legal-    Notices displayed by works containing it; or--    c) Prohibiting misrepresentation of the origin of that material, or-    requiring that modified versions of such material be marked in-    reasonable ways as different from the original version; or--    d) Limiting the use for publicity purposes of names of licensors or-    authors of the material; or--    e) Declining to grant rights under trademark law for use of some-    trade names, trademarks, or service marks; or--    f) Requiring indemnification of licensors and authors of that-    material by anyone who conveys the material (or modified versions of-    it) with contractual assumptions of liability to the recipient, for-    any liability that these contractual assumptions directly impose on-    those licensors and authors.--  All other non-permissive additional terms are considered "further-restrictions" within the meaning of section 10.  If the Program as you-received it, or any part of it, contains a notice stating that it is-governed by this License along with a term that is a further-restriction, you may remove that term.  If a license document contains-a further restriction but permits relicensing or conveying under this-License, you may add to a covered work material governed by the terms-of that license document, provided that the further restriction does-not survive such relicensing or conveying.--  If you add terms to a covered work in accord with this section, you-must place, in the relevant source files, a statement of the-additional terms that apply to those files, or a notice indicating-where to find the applicable terms.--  Additional terms, permissive or non-permissive, may be stated in the-form of a separately written license, or stated as exceptions;-the above requirements apply either way.--  8. Termination.--  You may not propagate or modify a covered work except as expressly-provided under this License.  Any attempt otherwise to propagate or-modify it is void, and will automatically terminate your rights under-this License (including any patent licenses granted under the third-paragraph of section 11).--  However, if you cease all violation of this License, then your-license from a particular copyright holder is reinstated (a)-provisionally, unless and until the copyright holder explicitly and-finally terminates your license, and (b) permanently, if the copyright-holder fails to notify you of the violation by some reasonable means-prior to 60 days after the cessation.--  Moreover, your license from a particular copyright holder is-reinstated permanently if the copyright holder notifies you of the-violation by some reasonable means, this is the first time you have-received notice of violation of this License (for any work) from that-copyright holder, and you cure the violation prior to 30 days after-your receipt of the notice.--  Termination of your rights under this section does not terminate the-licenses of parties who have received copies or rights from you under-this License.  If your rights have been terminated and not permanently-reinstated, you do not qualify to receive new licenses for the same-material under section 10.--  9. Acceptance Not Required for Having Copies.--  You are not required to accept this License in order to receive or-run a copy of the Program.  Ancillary propagation of a covered work-occurring solely as a consequence of using peer-to-peer transmission-to receive a copy likewise does not require acceptance.  However,-nothing other than this License grants you permission to propagate or-modify any covered work.  These actions infringe copyright if you do-not accept this License.  Therefore, by modifying or propagating a-covered work, you indicate your acceptance of this License to do so.--  10. Automatic Licensing of Downstream Recipients.--  Each time you convey a covered work, the recipient automatically-receives a license from the original licensors, to run, modify and-propagate that work, subject to this License.  You are not responsible-for enforcing compliance by third parties with this License.--  An "entity transaction" is a transaction transferring control of an-organization, or substantially all assets of one, or subdividing an-organization, or merging organizations.  If propagation of a covered-work results from an entity transaction, each party to that-transaction who receives a copy of the work also receives whatever-licenses to the work the party's predecessor in interest had or could-give under the previous paragraph, plus a right to possession of the-Corresponding Source of the work from the predecessor in interest, if-the predecessor has it or can get it with reasonable efforts.--  You may not impose any further restrictions on the exercise of the-rights granted or affirmed under this License.  For example, you may-not impose a license fee, royalty, or other charge for exercise of-rights granted under this License, and you may not initiate litigation-(including a cross-claim or counterclaim in a lawsuit) alleging that-any patent claim is infringed by making, using, selling, offering for-sale, or importing the Program or any portion of it.--  11. Patents.--  A "contributor" is a copyright holder who authorizes use under this-License of the Program or a work on which the Program is based.  The-work thus licensed is called the contributor's "contributor version".--  A contributor's "essential patent claims" are all patent claims-owned or controlled by the contributor, whether already acquired or-hereafter acquired, that would be infringed by some manner, permitted-by this License, of making, using, or selling its contributor version,-but do not include claims that would be infringed only as a-consequence of further modification of the contributor version.  For-purposes of this definition, "control" includes the right to grant-patent sublicenses in a manner consistent with the requirements of-this License.--  Each contributor grants you a non-exclusive, worldwide, royalty-free-patent license under the contributor's essential patent claims, to-make, use, sell, offer for sale, import and otherwise run, modify and-propagate the contents of its contributor version.--  In the following three paragraphs, a "patent license" is any express-agreement or commitment, however denominated, not to enforce a patent-(such as an express permission to practice a patent or covenant not to-sue for patent infringement).  To "grant" such a patent license to a-party means to make such an agreement or commitment not to enforce a-patent against the party.--  If you convey a covered work, knowingly relying on a patent license,-and the Corresponding Source of the work is not available for anyone-to copy, free of charge and under the terms of this License, through a-publicly available network server or other readily accessible means,-then you must either (1) cause the Corresponding Source to be so-available, or (2) arrange to deprive yourself of the benefit of the-patent license for this particular work, or (3) arrange, in a manner-consistent with the requirements of this License, to extend the patent-license to downstream recipients.  "Knowingly relying" means you have-actual knowledge that, but for the patent license, your conveying the-covered work in a country, or your recipient's use of the covered work-in a country, would infringe one or more identifiable patents in that-country that you have reason to believe are valid.--  If, pursuant to or in connection with a single transaction or-arrangement, you convey, or propagate by procuring conveyance of, a-covered work, and grant a patent license to some of the parties-receiving the covered work authorizing them to use, propagate, modify-or convey a specific copy of the covered work, then the patent license-you grant is automatically extended to all recipients of the covered-work and works based on it.--  A patent license is "discriminatory" if it does not include within-the scope of its coverage, prohibits the exercise of, or is-conditioned on the non-exercise of one or more of the rights that are-specifically granted under this License.  You may not convey a covered-work if you are a party to an arrangement with a third party that is-in the business of distributing software, under which you make payment-to the third party based on the extent of your activity of conveying-the work, and under which the third party grants, to any of the-parties who would receive the covered work from you, a discriminatory-patent license (a) in connection with copies of the covered work-conveyed by you (or copies made from those copies), or (b) primarily-for and in connection with specific products or compilations that-contain the covered work, unless you entered into that arrangement,-or that patent license was granted, prior to 28 March 2007.--  Nothing in this License shall be construed as excluding or limiting-any implied license or other defenses to infringement that may-otherwise be available to you under applicable patent law.--  12. No Surrender of Others' Freedom.--  If conditions are imposed on you (whether by court order, agreement or-otherwise) that contradict the conditions of this License, they do not-excuse you from the conditions of this License.  If you cannot convey a-covered work so as to satisfy simultaneously your obligations under this-License and any other pertinent obligations, then as a consequence you may-not convey it at all.  For example, if you agree to terms that obligate you-to collect a royalty for further conveying from those to whom you convey-the Program, the only way you could satisfy both those terms and this-License would be to refrain entirely from conveying the Program.--  13. Use with the GNU Affero General Public License.--  Notwithstanding any other provision of this License, you have-permission to link or combine any covered work with a work licensed-under version 3 of the GNU Affero General Public License into a single-combined work, and to convey the resulting work.  The terms of this-License will continue to apply to the part which is the covered work,-but the special requirements of the GNU Affero General Public License,-section 13, concerning interaction through a network will apply to the-combination as such.--  14. Revised Versions of this License.--  The Free Software Foundation may publish revised and/or new versions of-the GNU General Public License from time to time.  Such new versions will-be similar in spirit to the present version, but may differ in detail to-address new problems or concerns.--  Each version is given a distinguishing version number.  If the-Program specifies that a certain numbered version of the GNU General-Public License "or any later version" applies to it, you have the-option of following the terms and conditions either of that numbered-version or of any later version published by the Free Software-Foundation.  If the Program does not specify a version number of the-GNU General Public License, you may choose any version ever published-by the Free Software Foundation.--  If the Program specifies that a proxy can decide which future-versions of the GNU General Public License can be used, that proxy's-public statement of acceptance of a version permanently authorizes you-to choose that version for the Program.--  Later license versions may give you additional or different-permissions.  However, no additional obligations are imposed on any-author or copyright holder as a result of your choosing to follow a-later version.--  15. Disclaimer of Warranty.--  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.--  16. Limitation of Liability.--  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF-SUCH DAMAGES.--  17. Interpretation of Sections 15 and 16.--  If the disclaimer of warranty and limitation of liability provided-above cannot be given local legal effect according to their terms,-reviewing courts shall apply local law that most closely approximates-an absolute waiver of all civil liability in connection with the-Program, unless a warranty or assumption of liability accompanies a-copy of the Program in return for a fee.--              END OF TERMS AND CONDITIONS--     How to Apply These Terms to Your New Programs--  If you develop a new program, and you want it to be of the greatest-possible use to the public, the best way to achieve this is to make it-free software which everyone can redistribute and change under these terms.--  To do so, attach the following notices to the program.  It is safest-to attach them to the start of each source file to most effectively-state the exclusion of warranty; and each file should have at least-the "copyright" line and a pointer to where the full notice is found.--    <one line to give the program's name and a brief idea of what it does.>-    Copyright (C) <year>  <name of 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/>.--Also add information on how to contact you by electronic and paper mail.--  If the program does terminal interaction, make it output a short-notice like this when it starts in an interactive mode:+MIT License -    <program>  Copyright (C) <year>  <name of author>-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.-    This is free software, and you are welcome to redistribute it-    under certain conditions; type `show c' for details.+Copyright (c) 2024 Taylor Fausak -The hypothetical commands `show w' and `show c' should show the appropriate-parts of the General Public License.  Of course, your program's commands-might be different; for a GUI interface, you would use an "about box".+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: -  You should also get your employer (if you work as a programmer) or school,-if any, to sign a "copyright disclaimer" for the program, if necessary.-For more information on this, and how to apply and follow the GNU GPL, see-<http://www.gnu.org/licenses/>.+The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software. -  The GNU General Public License does not permit incorporating your program-into proprietary programs.  If your program is a subroutine library, you-may consider it more useful to permit linking proprietary applications with-the library.  If this is what you want to do, use the GNU Lesser General-Public License instead of this License.  But first, please read-<http://www.gnu.org/philosophy/why-not-lgpl.html>.+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.
README.md view
@@ -1,63 +1,172 @@-# cabal-gild+# Gild -## Synopsis+[![Workflow](https://github.com/tfausak/cabal-gild/actions/workflows/workflow.yaml/badge.svg)](https://github.com/tfausak/cabal-gild/actions/workflows/workflow.yaml)+[![Hackage](https://img.shields.io/hackage/v/cabal-gild)](https://hackage.haskell.org/package/cabal-gild)+[![Stackage](https://www.stackage.org/package/cabal-gild/badge/nightly?label=stackage)](https://www.stackage.org/package/cabal-gild) -```sh-$ cabal install cabal-gild-$ ...-$ cabal-gild --inplace example.cabal+Gild is an opinionated command line utility that formats Haskell package+descriptions, which are also known as `*.cabal` files.++## Summary++Given a package description like this:++``` cabal+CABAL-VERSION : 3.0+name          : example+version       : 0.0.0.0++library+  build-depends: mtl>=2.3, base+  ghc-options: -Wall+  if impl(ghc>=9.8)+    ghc-options: -Wmissing-role-annotations ``` -## Output+Gild will produce output like this: -Turns this...+``` cabal+cabal-version: 3.0+name: example+version: 0.0.0.0 -```cabal-cabal-version: 2.4-name: cabal-gild-version: 0+library+  build-depends:+    base,+    mtl >=2.3, --- An example formatter-executable cabal-gild-    default-language: Haskell2010-    hs-source-dirs: src-    main-is: CabalGild.hs-    -- build depends will be in-    -- a nice tabular format-    build-depends: base >=4.11 && <4.13, pretty >=1.1.3.6 && <1.2, bytestring, Cabal ^>=2.5, containers ^>=0.5.11.0 || ^>=0.6.0.1-    -- extensions will be sorted-    other-extensions:-      DeriveFunctor FlexibleContexts ExistentialQuantification OverloadedStrings-      RankNTypes+  ghc-options: -Wall++  if impl(ghc >= 9.8)+    ghc-options: -Wmissing-role-annotations ``` -...into this:+See the [installation][] section for how to get Gild and the [usage][] section+for how to use it. -```cabal-cabal-version: 2.4-name:          cabal-gild-version:       0+[installation]: #installation+[usage]: #usage --- An example formatter-executable cabal-gild-  default-language: Haskell2010-  hs-source-dirs:   src-  main-is:          CabalGild.hs+## Goals -  -- build depends will be in-  -- a nice tabular format-  build-depends:-    , base        >=4.11      && <4.13-    , bytestring-    , Cabal       ^>=2.5-    , containers  ^>=0.5.11.0 || ^>=0.6.0.1-    , pretty      >=1.1.3.6   && <1.2+- There should be no configuration options. As long as the output format is+  reasonable, the specifics should not matter too much. This means the amount+  of indentation cannot be changed, for example. -  -- extensions will be sorted-  other-extensions:-    DeriveFunctor-    ExistentialQuantification-    FlexibleContexts-    OverloadedStrings-    RankNTypes+- The output should be diff friendly. This means things generally go on their+  own line, trailing commas are used when possible, and elements are sorted+  where it makes sense.++- The output should be semantically the same as the input. This means no+  normalization or canonicalization. For example, separate `build-depends`+  fields are not merged together.++- It should be possible to format other files that use the same format as+  package descriptions. This means `cabal.project` files can be formatted as+  well.++- The focus is on formatting only. There should be no effort made to validate+  input or provide any checks or lints.++- The command line utility should be fast enough to run on every save. It+  should not need network access.++## Installation++Go to the [latest release][] page and download the binary for your platform.++[latest release]: https://github.com/tfausak/cabal-gild/releases/latest++### From Source++In general you should prefer downloading the appropriate binary for you+platform. However it is possible to build Gild from source. It supports Linux,+macOS, and Windows along with the three most recent versions of GHC. Any other+configurations are unsupported.++With Cabal:++``` sh+$ cabal install cabal-gild ```++With Stack:++``` sh+$ stack install cabal-gild+```++## Usage++Gild is a command line utility named `cabal-gild`. By default it reads from+standard input (STDIN) and writes to standard output (STDOUT). Its behavior can+be modified with command line options, which are described below.++### Options++Run `cabal-gild --help` to see the options that Gild supports. They are:++- `--help`: Prints the help message to STDOUT then exits successfully.++- `--version`: Prints the version number to STDOUT then exits successfully.++- `--input=FILE`: Uses `FILE` as the input. If this is `-` (which is the+  default), then the input will be read from STDIN.++- `--mode=MODE`: Sets the mode to `MODE`, which must be either `format` (the+  default) or `check`. When the mode is `format`, Gild will output the+  formatted package description. When the mode is `check`, Gild will exit+  successfully if the input is already formatted, otherwise it will exit+  unsuccessfully.++- `--output=FILE`: Uses `FILE` as the output. If this is `-` (which is the+  default), then the output will be written to STDOUT. To modify a file in+  place, use the same file as both input and output. For example:++  ``` sh+  $ cabal-gild --input p.cabal --output p.cabal+  ```++  This option is ignored when the mode is `check`.++- `--stdin=FILE`: When reading input from STDIN, use `FILE` as the effective+  input file. This is useful when a file's contents are already available, like+  in an editor. For example:++  ``` sh+  $ cabal-gild --stdin p.cabal < p.cabal+  ```++  This option is ignored when the input is not `-`.++### Pragmas++Gild supports special comments in package descriptions that act as pragmas.+Each pragma starts with `-- cabal-gild:`. Pragmas must be the last comment+before a field.++- `-- cabal-gild: discover DIRECTORY`: This pragma will discover any Haskell+  files (`*.hs`) in the given directory and use those to populate the list of+  modules. For example, given this input:++  ``` cabal+  library+    -- cabal-gild: discover source/library+    exposed-modules: ...+  ```++  Assuming there is a single Haskell file at `source/library/M.hs`, Gild will+  produce this output:++  ``` cabal+  library+    -- cabal-gild: discover source/library+    exposed-modules: M+  ```++  This pragma only works with the `exposed-modules` and `other-modules` fields.+  It will be ignored on all other fields.++  Any existing modules in the list will be ignored. The entire field will be+  replaced. This means adding, removing, and renaming modules should be handled+  automatically.
cabal-gild.cabal view
@@ -1,120 +1,131 @@-cabal-version:      2.2-name:               cabal-gild-version:            0.2.1.1-synopsis:           Format .cabal files-category:           Development-description:-  Format @.cabal@ files preserving the original field ordering, and comments.-  .-  Tuned for Oleg's preference, but has some knobs still.--license:            GPL-3.0-or-later AND BSD-3-Clause-license-file:       LICENSE.txt-author:             Oleg Grenrus <oleg.grenrus@iki.fi>-maintainer:         Taylor Fausak+cabal-version: 2.2+author: Taylor Fausak+category: Development+description: Gild formats package descriptions. extra-doc-files:   CHANGELOG.md   README.md -extra-source-files:-  fixtures/*.cabal-  fixtures/*.format+license: MIT+license-file: LICENSE.txt+maintainer: Taylor Fausak+name: cabal-gild+synopsis: Formats package descriptions.+version: 0.3.0.0  source-repository head-  type:     git+  type: git   location: https://github.com/tfausak/cabal-gild  flag pedantic   default: False-  manual:  True+  manual: True  common library-  build-depends:    base ^>=4.17.2.1 || ^>=4.18.2.0 || ^>=4.19.0.0+  build-depends: base ^>=4.17.0.0 || ^>=4.18.0.0 || ^>=4.19.0.0   default-language: Haskell2010   ghc-options:-    -Weverything -Wno-all-missed-specialisations -Wno-implicit-prelude-    -Wno-missed-specialisations -Wno-missing-deriving-strategies-    -Wno-missing-export-lists -Wno-missing-import-lists-    -Wno-missing-kind-signatures -Wno-missing-safe-haskell-mode-    -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe+    -Weverything+    -Wno-all-missed-specialisations+    -Wno-implicit-prelude+    -Wno-missed-specialisations+    -Wno-missing-deriving-strategies+    -Wno-missing-export-lists+    -Wno-missing-import-lists+    -Wno-missing-kind-signatures+    -Wno-missing-safe-haskell-mode+    -Wno-prepositive-qualified-module+    -Wno-safe+    -Wno-unsafe -  if impl(ghc >=9.8)+  if impl(ghc >= 9.8)     ghc-options: -Wno-missing-role-annotations    if flag(pedantic)     ghc-options: -Werror  common executable-  import:        library+  import: library   build-depends: cabal-gild-  ghc-options:   -rtsopts -threaded+  ghc-options:+    -rtsopts+    -threaded  library-  import:          library-  hs-source-dirs:  source/library-  other-modules:   Paths_cabal_gild+  import: library   autogen-modules: Paths_cabal_gild--  -- GHC boot libraries   build-depends:-    , bytestring ^>=0.11.5.3 || ^>=0.12.0.2-    , Cabal-syntax ^>=3.8.1.0 || ^>=3.10.1.0-    , containers ^>=0.6.7-    , directory ^>=1.3.7.1-    , exceptions ^>=0.10.5-    , filepath ^>=1.4.2.2-    , mtl ^>=2.2.2 || ^>=2.3.1-    , parsec ^>=3.1.16.1-    , pretty ^>=1.1.3.6+    Cabal-syntax ^>=3.8.1.0 || ^>=3.10.1.0,+    bytestring ^>=0.11.3.1 || ^>=0.12.0.2,+    containers ^>=0.6.6,+    directory ^>=1.3.7.1,+    exceptions ^>=0.10.5,+    filepath ^>=1.4.2.2,+    parsec ^>=3.1.16.1,+    pretty ^>=1.1.3.6,+    text ^>=2.0.1 || ^>=2.1,+    transformers ^>=0.5.6.2 || ^>=0.6.1.0, -  -- cabal-gild: expand source/library+  -- cabal-gild: discover source/library   exposed-modules:-    CabalGild-    CabalGild.Comments-    CabalGild.Error-    CabalGild.Fields-    CabalGild.Fields.BuildDepends-    CabalGild.Fields.Extensions-    CabalGild.Fields.Modules-    CabalGild.Fields.SourceFiles-    CabalGild.Fields.TestedWith-    CabalGild.FreeText-    CabalGild.Glob+    CabalGild.Action.AttachComments+    CabalGild.Action.Discover+    CabalGild.Action.ExtractComments+    CabalGild.Action.Format+    CabalGild.Action.GetCabalVersion+    CabalGild.Action.Reindent+    CabalGild.Action.RemovePositions+    CabalGild.Action.Render+    CabalGild.Class.MonadLog+    CabalGild.Class.MonadRead+    CabalGild.Class.MonadWalk+    CabalGild.Class.MonadWrite+    CabalGild.Compat.Cabal+    CabalGild.Exception.CheckFailure+    CabalGild.Exception.InvalidMode+    CabalGild.Exception.InvalidOption+    CabalGild.Exception.ParseError+    CabalGild.Exception.UnexpectedArgument+    CabalGild.Exception.UnknownOption+    CabalGild.Extra.Either+    CabalGild.Extra.Field+    CabalGild.Extra.FieldLine+    CabalGild.Extra.List+    CabalGild.Extra.ModuleName+    CabalGild.Extra.Name+    CabalGild.Extra.SectionArg+    CabalGild.Extra.String     CabalGild.Main-    CabalGild.Monad-    CabalGild.Options-    CabalGild.Parser-    CabalGild.Pragma-    CabalGild.Refactoring-    CabalGild.Refactoring.ExpandExposedModules-    CabalGild.Refactoring.Fragments-    CabalGild.Refactoring.GlobFiles-    CabalGild.Refactoring.Type-    VersionInterval+    CabalGild.Type.Block+    CabalGild.Type.Chunk+    CabalGild.Type.Comment+    CabalGild.Type.Config+    CabalGild.Type.Flag+    CabalGild.Type.Line+    CabalGild.Type.List+    CabalGild.Type.Mode+    CabalGild.Type.Pragma+    CabalGild.Type.Set+    CabalGild.Type.SomeParsecParser +  hs-source-dirs: source/library+  other-modules: Paths_cabal_gild+ executable cabal-gild-  import:         executable+  import: executable   hs-source-dirs: source/executable-  main-is:        Main.hs+  main-is: Main.hs  test-suite cabal-gild-test-suite-  import:         executable-  type:           exitcode-stdio-1.0-  hs-source-dirs: source/test-suite-  main-is:        Main.hs-  other-modules:-    CabalGild.Test.Golden-    CabalGild.Test.Interval--  -- dependencies in library+  import: executable   build-depends:-    , bytestring-    , Cabal-syntax-    , containers-    , filepath-    , QuickCheck ^>=2.14.3-    , tasty ^>=1.5-    , tasty-hunit ^>=0.10.1-    , tasty-quickcheck ^>=0.10.3+    bytestring,+    containers,+    exceptions,+    filepath,+    hspec ^>=2.11.7,+    transformers, --- end file comment+  hs-source-dirs: source/test-suite+  main-is: Main.hs+  type: exitcode-stdio-1.0
− fixtures/Cabal-notab.cabal
@@ -1,653 +0,0 @@-name:          Cabal-version:       2.5.0.0--- cabal-gild: no-tabular-copyright:     2003-2018, Cabal Development Team (see AUTHORS file)-license:       BSD3-license-file:  LICENSE-author:        Cabal Development Team <cabal-devel@haskell.org>-maintainer:    cabal-devel@haskell.org-homepage:      http://www.haskell.org/cabal/-bug-reports:   https://github.com/haskell/cabal/issues-synopsis:      A framework for packaging Haskell software-description:-  The Haskell Common Architecture for Building Applications and-  Libraries: a framework defining a common interface for authors to more-  easily build their Haskell applications in a portable way.-  .-  The Haskell Cabal is part of a larger infrastructure for distributing,-  organizing, and cataloging Haskell libraries and tools.-category:       Distribution-cabal-version:  >=1.10-build-type:     Simple--- If we use a new Cabal feature, this needs to be changed to Custom so--- we can bootstrap.--extra-source-files:-  README.md tests/README.md ChangeLog.md-  doc/bugs-and-stability.rst doc/concepts-and-development.rst-  doc/conf.py doc/config-and-install.rst doc/developing-packages.rst-  doc/images/Cabal-dark.png doc/index.rst doc/installing-packages.rst-  doc/intro.rst doc/misc.rst doc/nix-local-build-overview.rst-  doc/nix-local-build.rst doc/file-format-changelog.rst doc/README.md-  doc/references.inc--  -- Generated with 'make gen-extra-source-files'-  -- Do NOT edit this section manually; instead, run the script.-  -- BEGIN gen-extra-source-files-  tests/ParserTests/errors/common1.cabal-  tests/ParserTests/errors/common1.errors-  tests/ParserTests/errors/common2.cabal-  tests/ParserTests/errors/common2.errors-  tests/ParserTests/errors/common3.cabal-  tests/ParserTests/errors/common3.errors-  tests/ParserTests/errors/forward-compat.cabal-  tests/ParserTests/errors/forward-compat.errors-  tests/ParserTests/errors/forward-compat2.cabal-  tests/ParserTests/errors/forward-compat2.errors-  tests/ParserTests/errors/forward-compat3.cabal-  tests/ParserTests/errors/forward-compat3.errors-  tests/ParserTests/errors/issue-5055-2.cabal-  tests/ParserTests/errors/issue-5055-2.errors-  tests/ParserTests/errors/issue-5055.cabal-  tests/ParserTests/errors/issue-5055.errors-  tests/ParserTests/errors/leading-comma-2.cabal-  tests/ParserTests/errors/leading-comma-2.errors-  tests/ParserTests/errors/leading-comma-2b.cabal-  tests/ParserTests/errors/leading-comma-2b.errors-  tests/ParserTests/errors/leading-comma-2c.cabal-  tests/ParserTests/errors/leading-comma-2c.errors-  tests/ParserTests/errors/leading-comma.cabal-  tests/ParserTests/errors/leading-comma.errors-  tests/ParserTests/errors/multiple-libs.cabal-  tests/ParserTests/errors/multiple-libs.errors-  tests/ParserTests/errors/noVersion.cabal-  tests/ParserTests/errors/noVersion.errors-  tests/ParserTests/errors/noVersion2.cabal-  tests/ParserTests/errors/noVersion2.errors-  tests/ParserTests/errors/range-ge-wild.cabal-  tests/ParserTests/errors/range-ge-wild.errors-  tests/ParserTests/errors/removed-fields.cabal-  tests/ParserTests/errors/removed-fields.errors-  tests/ParserTests/errors/spdx-1.cabal-  tests/ParserTests/errors/spdx-1.errors-  tests/ParserTests/errors/spdx-2.cabal-  tests/ParserTests/errors/spdx-2.errors-  tests/ParserTests/errors/spdx-3.cabal-  tests/ParserTests/errors/spdx-3.errors-  tests/ParserTests/ipi/Includes2.cabal-  tests/ParserTests/ipi/Includes2.expr-  tests/ParserTests/ipi/Includes2.format-  tests/ParserTests/ipi/internal-preprocessor-test.cabal-  tests/ParserTests/ipi/internal-preprocessor-test.expr-  tests/ParserTests/ipi/internal-preprocessor-test.format-  tests/ParserTests/ipi/issue-2276-ghc-9885.cabal-  tests/ParserTests/ipi/issue-2276-ghc-9885.expr-  tests/ParserTests/ipi/issue-2276-ghc-9885.format-  tests/ParserTests/ipi/transformers.cabal-  tests/ParserTests/ipi/transformers.expr-  tests/ParserTests/ipi/transformers.format-  tests/ParserTests/regressions/MiniAgda.cabal-  tests/ParserTests/regressions/MiniAgda.check-  tests/ParserTests/regressions/Octree-0.5.cabal-  tests/ParserTests/regressions/Octree-0.5.expr-  tests/ParserTests/regressions/Octree-0.5.format-  tests/ParserTests/regressions/bad-glob-syntax.cabal-  tests/ParserTests/regressions/bad-glob-syntax.check-  tests/ParserTests/regressions/cc-options-with-optimization.cabal-  tests/ParserTests/regressions/cc-options-with-optimization.check-  tests/ParserTests/regressions/common-conditional.cabal-  tests/ParserTests/regressions/common-conditional.expr-  tests/ParserTests/regressions/common-conditional.format-  tests/ParserTests/regressions/common.cabal-  tests/ParserTests/regressions/common.expr-  tests/ParserTests/regressions/common.format-  tests/ParserTests/regressions/common2.cabal-  tests/ParserTests/regressions/common2.expr-  tests/ParserTests/regressions/common2.format-  tests/ParserTests/regressions/cxx-options-with-optimization.cabal-  tests/ParserTests/regressions/cxx-options-with-optimization.check-  tests/ParserTests/regressions/elif.cabal-  tests/ParserTests/regressions/elif.expr-  tests/ParserTests/regressions/elif.format-  tests/ParserTests/regressions/elif2.cabal-  tests/ParserTests/regressions/elif2.expr-  tests/ParserTests/regressions/elif2.format-  tests/ParserTests/regressions/encoding-0.8.cabal-  tests/ParserTests/regressions/encoding-0.8.expr-  tests/ParserTests/regressions/encoding-0.8.format-  tests/ParserTests/regressions/extensions-paths-5054.cabal-  tests/ParserTests/regressions/extensions-paths-5054.check-  tests/ParserTests/regressions/generics-sop.cabal-  tests/ParserTests/regressions/generics-sop.expr-  tests/ParserTests/regressions/generics-sop.format-  tests/ParserTests/regressions/ghc-option-j.cabal-  tests/ParserTests/regressions/ghc-option-j.check-  tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal-  tests/ParserTests/regressions/haddock-api-2.18.1-check.check-  tests/ParserTests/regressions/hidden-main-lib.cabal-  tests/ParserTests/regressions/hidden-main-lib.expr-  tests/ParserTests/regressions/hidden-main-lib.format-  tests/ParserTests/regressions/issue-5055.cabal-  tests/ParserTests/regressions/issue-5055.expr-  tests/ParserTests/regressions/issue-5055.format-  tests/ParserTests/regressions/issue-774.cabal-  tests/ParserTests/regressions/issue-774.check-  tests/ParserTests/regressions/issue-774.expr-  tests/ParserTests/regressions/issue-774.format-  tests/ParserTests/regressions/jaeger-flamegraph.cabal-  tests/ParserTests/regressions/jaeger-flamegraph.expr-  tests/ParserTests/regressions/jaeger-flamegraph.format-  tests/ParserTests/regressions/leading-comma-2.cabal-  tests/ParserTests/regressions/leading-comma-2.expr-  tests/ParserTests/regressions/leading-comma-2.format-  tests/ParserTests/regressions/leading-comma.cabal-  tests/ParserTests/regressions/leading-comma.expr-  tests/ParserTests/regressions/leading-comma.format-  tests/ParserTests/regressions/multiple-libs-2.cabal-  tests/ParserTests/regressions/multiple-libs-2.check-  tests/ParserTests/regressions/multiple-libs-2.expr-  tests/ParserTests/regressions/multiple-libs-2.format-  tests/ParserTests/regressions/noVersion.cabal-  tests/ParserTests/regressions/noVersion.expr-  tests/ParserTests/regressions/noVersion.format-  tests/ParserTests/regressions/nothing-unicode.cabal-  tests/ParserTests/regressions/nothing-unicode.check-  tests/ParserTests/regressions/nothing-unicode.expr-  tests/ParserTests/regressions/nothing-unicode.format-  tests/ParserTests/regressions/pre-1.6-glob.cabal-  tests/ParserTests/regressions/pre-1.6-glob.check-  tests/ParserTests/regressions/pre-2.4-globstar.cabal-  tests/ParserTests/regressions/pre-2.4-globstar.check-  tests/ParserTests/regressions/shake.cabal-  tests/ParserTests/regressions/shake.expr-  tests/ParserTests/regressions/shake.format-  tests/ParserTests/regressions/spdx-1.cabal-  tests/ParserTests/regressions/spdx-1.expr-  tests/ParserTests/regressions/spdx-1.format-  tests/ParserTests/regressions/spdx-2.cabal-  tests/ParserTests/regressions/spdx-2.expr-  tests/ParserTests/regressions/spdx-2.format-  tests/ParserTests/regressions/spdx-3.cabal-  tests/ParserTests/regressions/spdx-3.expr-  tests/ParserTests/regressions/spdx-3.format-  tests/ParserTests/regressions/th-lift-instances.cabal-  tests/ParserTests/regressions/th-lift-instances.expr-  tests/ParserTests/regressions/th-lift-instances.format-  tests/ParserTests/regressions/wl-pprint-indef.cabal-  tests/ParserTests/regressions/wl-pprint-indef.expr-  tests/ParserTests/regressions/wl-pprint-indef.format-  tests/ParserTests/warnings/bom.cabal-  tests/ParserTests/warnings/bool.cabal-  tests/ParserTests/warnings/deprecatedfield.cabal-  tests/ParserTests/warnings/doubledash.cabal-  tests/ParserTests/warnings/extratestmodule.cabal-  tests/ParserTests/warnings/gluedop.cabal-  tests/ParserTests/warnings/multiplesingular.cabal-  tests/ParserTests/warnings/nbsp.cabal-  tests/ParserTests/warnings/newsyntax.cabal-  tests/ParserTests/warnings/oldsyntax.cabal-  tests/ParserTests/warnings/subsection.cabal-  tests/ParserTests/warnings/tab.cabal-  tests/ParserTests/warnings/trailingfield.cabal-  tests/ParserTests/warnings/unknownfield.cabal-  tests/ParserTests/warnings/unknownsection.cabal-  tests/ParserTests/warnings/utf8.cabal-  tests/ParserTests/warnings/versiontag.cabal-  tests/hackage/check.sh-  tests/hackage/download.sh-  tests/hackage/unpack.sh-  tests/misc/ghc-supported-languages.hs-  -- END gen-extra-source-files--source-repository head-  type:     git-  location: https://github.com/haskell/cabal/-  subdir:   Cabal--flag bundled-binary-generic-  default: False--library-  build-depends:-    array      >= 0.4.0.1  && < 0.6,-    base       >= 4.6      && < 5,-    bytestring >= 0.10.0.0 && < 0.11,-    containers >= 0.5.0.0  && < 0.7,-    deepseq    >= 1.3.0.1  && < 1.5,-    directory  >= 1.2      && < 1.4,-    filepath   >= 1.3.0.1  && < 1.5,-    pretty     >= 1.1.1    && < 1.2,-    process    >= 1.1.0.2  && < 1.7,-    time       >= 1.4.0.1  && < 1.10--  if flag(bundled-binary-generic)-    build-depends: binary >= 0.5.1.1 && < 0.7-  else-    build-depends: binary >= 0.7 && < 0.9--  if os(windows)-    build-depends: Win32 >= 2.3.0.0 && < 2.9-  else-    build-depends: unix  >= 2.6.0.0 && < 2.8--  ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs-  if impl(ghc >= 8.0)-    ghc-options: -Wcompat -Wnoncanonical-monad-instances-                 -Wnoncanonical-monadfail-instances--  exposed-modules:-    Distribution.Backpack-    Distribution.Backpack.Configure-    Distribution.Backpack.ComponentsGraph-    Distribution.Backpack.ConfiguredComponent-    Distribution.Backpack.DescribeUnitId-    Distribution.Backpack.FullUnitId-    Distribution.Backpack.LinkedComponent-    Distribution.Backpack.ModSubst-    Distribution.Backpack.ModuleShape-    Distribution.Backpack.PreModuleShape-    Distribution.CabalSpecVersion-    Distribution.Utils.IOData-    Distribution.Utils.LogProgress-    Distribution.Utils.MapAccum-    Distribution.Compat.CreatePipe-    Distribution.Compat.Directory-    Distribution.Compat.Environment-    Distribution.Compat.Exception-    Distribution.Compat.Graph-    Distribution.Compat.Internal.TempFile-    Distribution.Compat.Newtype-    Distribution.Compat.Prelude.Internal-    Distribution.Compat.Semigroup-    Distribution.Compat.Stack-    Distribution.Compat.Time-    Distribution.Compat.DList-    Distribution.Compiler-    Distribution.InstalledPackageInfo-    Distribution.Types.AbiDependency-    Distribution.Types.ExposedModule-    Distribution.Types.InstalledPackageInfo-    Distribution.Types.InstalledPackageInfo.FieldGrammar-    Distribution.License-    Distribution.Make-    Distribution.ModuleName-    Distribution.Package-    Distribution.PackageDescription-    Distribution.PackageDescription.Check-    Distribution.PackageDescription.Configuration-    Distribution.PackageDescription.PrettyPrint-    Distribution.PackageDescription.Utils-    Distribution.ReadE-    Distribution.Simple-    Distribution.Simple.Bench-    Distribution.Simple.Build-    Distribution.Simple.Build.Macros-    Distribution.Simple.Build.PathsModule-    Distribution.Simple.BuildPaths-    Distribution.Simple.BuildTarget-    Distribution.Simple.BuildToolDepends-    Distribution.Simple.CCompiler-    Distribution.Simple.Command-    Distribution.Simple.Compiler-    Distribution.Simple.Configure-    Distribution.Simple.Flag-    Distribution.Simple.GHC-    Distribution.Simple.GHCJS-    Distribution.Simple.Haddock-    Distribution.Simple.Doctest-    Distribution.Simple.Glob-    Distribution.Simple.HaskellSuite-    Distribution.Simple.Hpc-    Distribution.Simple.Install-    Distribution.Simple.InstallDirs-    Distribution.Simple.LocalBuildInfo-    Distribution.Simple.PackageIndex-    Distribution.Simple.PreProcess-    Distribution.Simple.PreProcess.Unlit-    Distribution.Simple.Program-    Distribution.Simple.Program.Ar-    Distribution.Simple.Program.Builtin-    Distribution.Simple.Program.Db-    Distribution.Simple.Program.Find-    Distribution.Simple.Program.GHC-    Distribution.Simple.Program.HcPkg-    Distribution.Simple.Program.Hpc-    Distribution.Simple.Program.Internal-    Distribution.Simple.Program.Ld-    Distribution.Simple.Program.ResponseFile-    Distribution.Simple.Program.Run-    Distribution.Simple.Program.Script-    Distribution.Simple.Program.Strip-    Distribution.Simple.Program.Types-    Distribution.Simple.Register-    Distribution.Simple.Setup-    Distribution.Simple.SrcDist-    Distribution.Simple.Test-    Distribution.Simple.Test.ExeV10-    Distribution.Simple.Test.LibV09-    Distribution.Simple.Test.Log-    Distribution.Simple.UHC-    Distribution.Simple.UserHooks-    Distribution.Simple.Utils-    Distribution.SPDX-    Distribution.SPDX.License-    Distribution.SPDX.LicenseId-    Distribution.SPDX.LicenseExceptionId-    Distribution.SPDX.LicenseExpression-    Distribution.SPDX.LicenseListVersion-    Distribution.SPDX.LicenseReference-    Distribution.System-    Distribution.TestSuite-    Distribution.Text-    Distribution.Pretty-    Distribution.Types.AbiHash-    Distribution.Types.AnnotatedId-    Distribution.Types.Benchmark-    Distribution.Types.BenchmarkInterface-    Distribution.Types.BenchmarkType-    Distribution.Types.BuildInfo-    Distribution.Types.BuildType-    Distribution.Types.ComponentInclude-    Distribution.Types.Dependency-    Distribution.Types.ExeDependency-    Distribution.Types.LegacyExeDependency-    Distribution.Types.PkgconfigDependency-    Distribution.Types.DependencyMap-    Distribution.Types.ComponentId-    Distribution.Types.MungedPackageId-    Distribution.Types.PackageId-    Distribution.Types.UnitId-    Distribution.Types.Executable-    Distribution.Types.ExecutableScope-    Distribution.Types.Library-    Distribution.Types.LibraryVisibility-    Distribution.Types.ForeignLib-    Distribution.Types.ForeignLibType-    Distribution.Types.ForeignLibOption-    Distribution.Types.Module-    Distribution.Types.ModuleReexport-    Distribution.Types.ModuleRenaming-    Distribution.Types.ComponentName-    Distribution.Types.LibraryName-    Distribution.Types.MungedPackageName-    Distribution.Types.PackageName-    Distribution.Types.PkgconfigName-    Distribution.Types.UnqualComponentName-    Distribution.Types.IncludeRenaming-    Distribution.Types.Mixin-    Distribution.Types.SetupBuildInfo-    Distribution.Types.TestSuite-    Distribution.Types.TestSuiteInterface-    Distribution.Types.TestType-    Distribution.Types.GenericPackageDescription-    Distribution.Types.Condition-    Distribution.Types.CondTree-    Distribution.Types.HookedBuildInfo-    Distribution.Types.PackageDescription-    Distribution.Types.SourceRepo-    Distribution.Types.Component-    Distribution.Types.ComponentLocalBuildInfo-    Distribution.Types.LocalBuildInfo-    Distribution.Types.ComponentRequestedSpec-    Distribution.Types.TargetInfo-    Distribution.Types.Version-    Distribution.Types.VersionRange-    Distribution.Types.VersionInterval-    Distribution.Types.GivenComponent-    Distribution.Types.PackageVersionConstraint-    Distribution.Utils.Generic-    Distribution.Utils.NubList-    Distribution.Utils.ShortText-    Distribution.Utils.Progress-    Distribution.Verbosity-    Distribution.Version-    Language.Haskell.Extension-    Distribution.Compat.Binary--  -- Parsec parser-related modules-  build-depends:-    -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity-    -- See also https://github.com/ekmett/transformers-compat/issues/35-    transformers (>= 0.3      && < 0.4) || (>=0.4.1.0 && <0.6),-    mtl           >= 2.1      && < 2.3,-    text          >= 1.2.3.0  && < 1.3,-    parsec        >= 3.1.13.0 && < 3.2-  exposed-modules:-    Distribution.Compat.Parsing-    Distribution.Compat.CharParsing-    Distribution.FieldGrammar-    Distribution.FieldGrammar.Class-    Distribution.FieldGrammar.FieldDescrs-    Distribution.FieldGrammar.Parsec-    Distribution.FieldGrammar.Pretty-    Distribution.PackageDescription.FieldGrammar-    Distribution.PackageDescription.Parsec-    Distribution.PackageDescription.Quirks-    Distribution.Parsec-    Distribution.Parsec.Error-    Distribution.Parsec.Newtypes-    Distribution.Parsec.Position-    Distribution.Parsec.Warning-    Distribution.Parsec.FieldLineStream-    Distribution.Fields-    Distribution.Fields.ConfVar-    Distribution.Fields.Field-    Distribution.Fields.Lexer-    Distribution.Fields.LexerMonad-    Distribution.Fields.ParseResult-    Distribution.Fields.Parser-    Distribution.Fields.Pretty--  -- Lens functionality-  exposed-modules:-    Distribution.Compat.Lens-    Distribution.Types.Lens-    Distribution.Types.Benchmark.Lens-    Distribution.Types.BuildInfo.Lens-    Distribution.Types.Executable.Lens-    Distribution.Types.ForeignLib.Lens-    Distribution.Types.GenericPackageDescription.Lens-    Distribution.Types.InstalledPackageInfo.Lens-    Distribution.Types.Library.Lens-    Distribution.Types.PackageDescription.Lens-    Distribution.Types.PackageId.Lens-    Distribution.Types.SetupBuildInfo.Lens-    Distribution.Types.SourceRepo.Lens-    Distribution.Types.TestSuite.Lens--  other-modules:-    Distribution.Backpack.PreExistingComponent-    Distribution.Backpack.ReadyComponent-    Distribution.Backpack.MixLink-    Distribution.Backpack.ModuleScope-    Distribution.Backpack.UnifyM-    Distribution.Backpack.Id-    Distribution.Utils.UnionFind-    Distribution.Utils.Base62-    Distribution.Compat.CopyFile-    Distribution.Compat.GetShortPathName-    Distribution.Compat.MonadFail-    Distribution.Compat.Prelude-    Distribution.Compat.SnocList-    Distribution.GetOpt-    Distribution.Lex-    Distribution.Utils.String-    Distribution.Simple.GHC.EnvironmentParser-    Distribution.Simple.GHC.Internal-    Distribution.Simple.GHC.ImplInfo-    Paths_Cabal--  if flag(bundled-binary-generic)-    other-modules:-      Distribution.Compat.Binary.Class-      Distribution.Compat.Binary.Generic--  default-language: Haskell2010-  other-extensions:-    BangPatterns-    CPP-    DefaultSignatures-    DeriveDataTypeable-    DeriveFoldable-    DeriveFunctor-    DeriveGeneric-    DeriveTraversable-    ExistentialQuantification-    FlexibleContexts-    FlexibleInstances-    GeneralizedNewtypeDeriving-    ImplicitParams-    KindSignatures-    NondecreasingIndentation-    OverloadedStrings-    RankNTypes-    RecordWildCards-    ScopedTypeVariables-    StandaloneDeriving-    Trustworthy-    TypeFamilies-    TypeOperators-    TypeSynonymInstances-    UndecidableInstances--  if impl(ghc >= 7.11)-    other-extensions: PatternSynonyms---- Small, fast running tests.-test-suite unit-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests-  other-modules:-    Test.Laws-    Test.QuickCheck.Utils-    UnitTests.Distribution.Compat.CreatePipe-    UnitTests.Distribution.Compat.Time-    UnitTests.Distribution.Compat.Graph-    UnitTests.Distribution.Simple.Glob-    UnitTests.Distribution.Simple.Program.Internal-    UnitTests.Distribution.Simple.Utils-    UnitTests.Distribution.SPDX-    UnitTests.Distribution.System-    UnitTests.Distribution.Types.GenericPackageDescription-    UnitTests.Distribution.Utils.Generic-    UnitTests.Distribution.Utils.NubList-    UnitTests.Distribution.Utils.ShortText-    UnitTests.Distribution.Version-  main-is: UnitTests.hs-  build-depends:-    array,-    base,-    bytestring,-    containers,-    directory,-    filepath,-    integer-logarithms >= 1.0.2 && <1.1,-    tasty >= 1.1.0.3 && < 1.2,-    tasty-hunit,-    tasty-quickcheck,-    tagged,-    temporary,-    text,-    pretty,-    QuickCheck >= 2.11.3 && < 2.12,-    Cabal-  ghc-options: -Wall-  default-language: Haskell2010--test-suite parser-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests-  main-is: ParserTests.hs-  build-depends:-    base,-    base-compat >=0.10.4 && <0.11,-    bytestring,-    directory,-    filepath,-    tasty >= 1.1.0.3 && < 1.2,-    tasty-hunit,-    tasty-quickcheck,-    tasty-golden >=2.3.1.1 && <2.4,-    Diff >=0.3.4 && <0.4,-    Cabal-  ghc-options: -Wall-  default-language: Haskell2010--  if impl(ghc >= 7.8)-    build-depends:-      tree-diff      >= 0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--test-suite check-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests-  main-is: CheckTests.hs-  build-depends:-    base,-    bytestring,-    directory,-    filepath,-    tasty >= 1.1.0.3 && < 1.2,-    tasty-golden >=2.3.1.1 && <2.4,-    Diff >=0.3.4 && <0.4,-    Cabal-  ghc-options: -Wall-  default-language: Haskell2010--test-suite custom-setup-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests/custom-setup-  main-is: CustomSetupTests.hs-  other-modules:-    CabalDoctestSetup-    IdrisSetup-  build-depends:-    Cabal,-    base,-    directory,-    filepath,-    process-  default-language: Haskell2010--test-suite hackage-tests-  type: exitcode-stdio-1.0-  main-is: HackageTests.hs--  -- TODO: need to get 01-index.tar on appveyor-  if os(windows)-    buildable: False--  hs-source-dirs: tests--  build-depends:-    base,-    Cabal,-    bytestring,-    deepseq,-    containers,-    directory,-    filepath--  build-depends:-    base-compat          >=0.10.4   && <0.11,-    base-orphans         >=0.6      && <0.9,-    optparse-applicative >=0.13.2.0 && <0.15,-    stm                  >=2.4.5.0  && <2.6,-    tar                  >=0.5.0.3  && <0.6--  if impl(ghc >= 7.8)-    build-depends:-      tree-diff      >= 0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--  ghc-options: -Wall -rtsopts -threaded-  default-extensions: CPP-  default-language: Haskell2010
− fixtures/Cabal-notab.format
@@ -1,675 +0,0 @@-name:               Cabal-version:            2.5.0.0---- cabal-gild: no-tabular-copyright:          2003-2018, Cabal Development Team (see AUTHORS file)-license:            BSD3-license-file:       LICENSE-author:             Cabal Development Team <cabal-devel@haskell.org>-maintainer:         cabal-devel@haskell.org-homepage:           http://www.haskell.org/cabal/-bug-reports:        https://github.com/haskell/cabal/issues-synopsis:           A framework for packaging Haskell software-description:-  The Haskell Common Architecture for Building Applications and-  Libraries: a framework defining a common interface for authors to more-  easily build their Haskell applications in a portable way.-  .-  The Haskell Cabal is part of a larger infrastructure for distributing,-  organizing, and cataloging Haskell libraries and tools.--category:           Distribution-cabal-version:      >=1.10-build-type:         Simple---- If we use a new Cabal feature, this needs to be changed to Custom so--- we can bootstrap.--extra-source-files:-  ChangeLog.md-  doc/bugs-and-stability.rst-  doc/concepts-and-development.rst-  doc/conf.py-  doc/config-and-install.rst-  doc/developing-packages.rst-  doc/file-format-changelog.rst-  doc/images/Cabal-dark.png-  doc/index.rst-  doc/installing-packages.rst-  doc/intro.rst-  doc/misc.rst-  doc/nix-local-build-overview.rst-  doc/nix-local-build.rst-  doc/README.md-  doc/references.inc-  README.md-  tests/hackage/check.sh-  tests/hackage/download.sh-  tests/hackage/unpack.sh-  tests/misc/ghc-supported-languages.hs-  tests/ParserTests/errors/common1.cabal-  tests/ParserTests/errors/common1.errors-  tests/ParserTests/errors/common2.cabal-  tests/ParserTests/errors/common2.errors-  tests/ParserTests/errors/common3.cabal-  tests/ParserTests/errors/common3.errors-  tests/ParserTests/errors/forward-compat.cabal-  tests/ParserTests/errors/forward-compat.errors-  tests/ParserTests/errors/forward-compat2.cabal-  tests/ParserTests/errors/forward-compat2.errors-  tests/ParserTests/errors/forward-compat3.cabal-  tests/ParserTests/errors/forward-compat3.errors-  tests/ParserTests/errors/issue-5055-2.cabal-  tests/ParserTests/errors/issue-5055-2.errors-  tests/ParserTests/errors/issue-5055.cabal-  tests/ParserTests/errors/issue-5055.errors-  tests/ParserTests/errors/leading-comma-2.cabal-  tests/ParserTests/errors/leading-comma-2.errors-  tests/ParserTests/errors/leading-comma-2b.cabal-  tests/ParserTests/errors/leading-comma-2b.errors-  tests/ParserTests/errors/leading-comma-2c.cabal-  tests/ParserTests/errors/leading-comma-2c.errors-  tests/ParserTests/errors/leading-comma.cabal-  tests/ParserTests/errors/leading-comma.errors-  tests/ParserTests/errors/multiple-libs.cabal-  tests/ParserTests/errors/multiple-libs.errors-  tests/ParserTests/errors/noVersion.cabal-  tests/ParserTests/errors/noVersion.errors-  tests/ParserTests/errors/noVersion2.cabal-  tests/ParserTests/errors/noVersion2.errors-  tests/ParserTests/errors/range-ge-wild.cabal-  tests/ParserTests/errors/range-ge-wild.errors-  tests/ParserTests/errors/removed-fields.cabal-  tests/ParserTests/errors/removed-fields.errors-  tests/ParserTests/errors/spdx-1.cabal-  tests/ParserTests/errors/spdx-1.errors-  tests/ParserTests/errors/spdx-2.cabal-  tests/ParserTests/errors/spdx-2.errors-  tests/ParserTests/errors/spdx-3.cabal-  tests/ParserTests/errors/spdx-3.errors-  tests/ParserTests/ipi/Includes2.cabal-  tests/ParserTests/ipi/Includes2.expr-  tests/ParserTests/ipi/Includes2.format-  tests/ParserTests/ipi/internal-preprocessor-test.cabal-  tests/ParserTests/ipi/internal-preprocessor-test.expr-  tests/ParserTests/ipi/internal-preprocessor-test.format-  tests/ParserTests/ipi/issue-2276-ghc-9885.cabal-  tests/ParserTests/ipi/issue-2276-ghc-9885.expr-  tests/ParserTests/ipi/issue-2276-ghc-9885.format-  tests/ParserTests/ipi/transformers.cabal-  tests/ParserTests/ipi/transformers.expr-  tests/ParserTests/ipi/transformers.format-  tests/ParserTests/regressions/bad-glob-syntax.cabal-  tests/ParserTests/regressions/bad-glob-syntax.check-  tests/ParserTests/regressions/cc-options-with-optimization.cabal-  tests/ParserTests/regressions/cc-options-with-optimization.check-  tests/ParserTests/regressions/common-conditional.cabal-  tests/ParserTests/regressions/common-conditional.expr-  tests/ParserTests/regressions/common-conditional.format-  tests/ParserTests/regressions/common.cabal-  tests/ParserTests/regressions/common.expr-  tests/ParserTests/regressions/common.format-  tests/ParserTests/regressions/common2.cabal-  tests/ParserTests/regressions/common2.expr-  tests/ParserTests/regressions/common2.format-  tests/ParserTests/regressions/cxx-options-with-optimization.cabal-  tests/ParserTests/regressions/cxx-options-with-optimization.check-  tests/ParserTests/regressions/elif.cabal-  tests/ParserTests/regressions/elif.expr-  tests/ParserTests/regressions/elif.format-  tests/ParserTests/regressions/elif2.cabal-  tests/ParserTests/regressions/elif2.expr-  tests/ParserTests/regressions/elif2.format-  tests/ParserTests/regressions/encoding-0.8.cabal-  tests/ParserTests/regressions/encoding-0.8.expr-  tests/ParserTests/regressions/encoding-0.8.format-  tests/ParserTests/regressions/extensions-paths-5054.cabal-  tests/ParserTests/regressions/extensions-paths-5054.check-  tests/ParserTests/regressions/generics-sop.cabal-  tests/ParserTests/regressions/generics-sop.expr-  tests/ParserTests/regressions/generics-sop.format-  tests/ParserTests/regressions/ghc-option-j.cabal-  tests/ParserTests/regressions/ghc-option-j.check-  tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal-  tests/ParserTests/regressions/haddock-api-2.18.1-check.check-  tests/ParserTests/regressions/hidden-main-lib.cabal-  tests/ParserTests/regressions/hidden-main-lib.expr-  tests/ParserTests/regressions/hidden-main-lib.format-  tests/ParserTests/regressions/issue-5055.cabal-  tests/ParserTests/regressions/issue-5055.expr-  tests/ParserTests/regressions/issue-5055.format-  tests/ParserTests/regressions/issue-774.cabal-  tests/ParserTests/regressions/issue-774.check-  tests/ParserTests/regressions/issue-774.expr-  tests/ParserTests/regressions/issue-774.format-  tests/ParserTests/regressions/jaeger-flamegraph.cabal-  tests/ParserTests/regressions/jaeger-flamegraph.expr-  tests/ParserTests/regressions/jaeger-flamegraph.format-  tests/ParserTests/regressions/leading-comma-2.cabal-  tests/ParserTests/regressions/leading-comma-2.expr-  tests/ParserTests/regressions/leading-comma-2.format-  tests/ParserTests/regressions/leading-comma.cabal-  tests/ParserTests/regressions/leading-comma.expr-  tests/ParserTests/regressions/leading-comma.format-  tests/ParserTests/regressions/MiniAgda.cabal-  tests/ParserTests/regressions/MiniAgda.check-  tests/ParserTests/regressions/multiple-libs-2.cabal-  tests/ParserTests/regressions/multiple-libs-2.check-  tests/ParserTests/regressions/multiple-libs-2.expr-  tests/ParserTests/regressions/multiple-libs-2.format-  tests/ParserTests/regressions/nothing-unicode.cabal-  tests/ParserTests/regressions/nothing-unicode.check-  tests/ParserTests/regressions/nothing-unicode.expr-  tests/ParserTests/regressions/nothing-unicode.format-  tests/ParserTests/regressions/noVersion.cabal-  tests/ParserTests/regressions/noVersion.expr-  tests/ParserTests/regressions/noVersion.format-  tests/ParserTests/regressions/Octree-0.5.cabal-  tests/ParserTests/regressions/Octree-0.5.expr-  tests/ParserTests/regressions/Octree-0.5.format-  tests/ParserTests/regressions/pre-1.6-glob.cabal-  tests/ParserTests/regressions/pre-1.6-glob.check-  tests/ParserTests/regressions/pre-2.4-globstar.cabal-  tests/ParserTests/regressions/pre-2.4-globstar.check-  tests/ParserTests/regressions/shake.cabal-  tests/ParserTests/regressions/shake.expr-  tests/ParserTests/regressions/shake.format-  tests/ParserTests/regressions/spdx-1.cabal-  tests/ParserTests/regressions/spdx-1.expr-  tests/ParserTests/regressions/spdx-1.format-  tests/ParserTests/regressions/spdx-2.cabal-  tests/ParserTests/regressions/spdx-2.expr-  tests/ParserTests/regressions/spdx-2.format-  tests/ParserTests/regressions/spdx-3.cabal-  tests/ParserTests/regressions/spdx-3.expr-  tests/ParserTests/regressions/spdx-3.format-  tests/ParserTests/regressions/th-lift-instances.cabal-  tests/ParserTests/regressions/th-lift-instances.expr-  tests/ParserTests/regressions/th-lift-instances.format-  tests/ParserTests/regressions/wl-pprint-indef.cabal-  tests/ParserTests/regressions/wl-pprint-indef.expr-  tests/ParserTests/regressions/wl-pprint-indef.format-  tests/ParserTests/warnings/bom.cabal-  tests/ParserTests/warnings/bool.cabal-  tests/ParserTests/warnings/deprecatedfield.cabal-  tests/ParserTests/warnings/doubledash.cabal-  tests/ParserTests/warnings/extratestmodule.cabal-  tests/ParserTests/warnings/gluedop.cabal-  tests/ParserTests/warnings/multiplesingular.cabal-  tests/ParserTests/warnings/nbsp.cabal-  tests/ParserTests/warnings/newsyntax.cabal-  tests/ParserTests/warnings/oldsyntax.cabal-  tests/ParserTests/warnings/subsection.cabal-  tests/ParserTests/warnings/tab.cabal-  tests/ParserTests/warnings/trailingfield.cabal-  tests/ParserTests/warnings/unknownfield.cabal-  tests/ParserTests/warnings/unknownsection.cabal-  tests/ParserTests/warnings/utf8.cabal-  tests/ParserTests/warnings/versiontag.cabal-  tests/README.md---- Generated with 'make gen-extra-source-files'--- Do NOT edit this section manually; instead, run the script.--- BEGIN gen-extra-source-files--- END gen-extra-source-files--source-repository head-  type:     git-  location: https://github.com/haskell/cabal/-  subdir:   Cabal--flag bundled-binary-generic-  default: False--library-  build-depends:-      array >=0.4.0.1 && <0.6-    , base >=4.6 && <5-    , bytestring >=0.10.0.0 && <0.11-    , containers >=0.5.0.0 && <0.7-    , deepseq >=1.3.0.1 && <1.5-    , directory >=1.2 && <1.4-    , filepath >=1.3.0.1 && <1.5-    , pretty >=1.1.1 && <1.2-    , process >=1.1.0.2 && <1.7-    , time >=1.4.0.1 && <1.10--  if flag(bundled-binary-generic)-    build-depends: binary >=0.5.1.1 && <0.7--  else-    build-depends: binary >=0.7 && <0.9--  if os(windows)-    build-depends: Win32 >=2.3.0.0 && <2.9--  else-    build-depends: unix >=2.6.0.0 && <2.8--  ghc-options:      -Wall -fno-ignore-asserts -fwarn-tabs--  if impl(ghc >=8.0)-    ghc-options:-      -Wcompat -Wnoncanonical-monad-instances-      -Wnoncanonical-monadfail-instances--  exposed-modules:-    Distribution.Backpack-    Distribution.Backpack.ComponentsGraph-    Distribution.Backpack.Configure-    Distribution.Backpack.ConfiguredComponent-    Distribution.Backpack.DescribeUnitId-    Distribution.Backpack.FullUnitId-    Distribution.Backpack.LinkedComponent-    Distribution.Backpack.ModSubst-    Distribution.Backpack.ModuleShape-    Distribution.Backpack.PreModuleShape-    Distribution.CabalSpecVersion-    Distribution.Compat.Binary-    Distribution.Compat.CreatePipe-    Distribution.Compat.Directory-    Distribution.Compat.DList-    Distribution.Compat.Environment-    Distribution.Compat.Exception-    Distribution.Compat.Graph-    Distribution.Compat.Internal.TempFile-    Distribution.Compat.Newtype-    Distribution.Compat.Prelude.Internal-    Distribution.Compat.Semigroup-    Distribution.Compat.Stack-    Distribution.Compat.Time-    Distribution.Compiler-    Distribution.InstalledPackageInfo-    Distribution.License-    Distribution.Make-    Distribution.ModuleName-    Distribution.Package-    Distribution.PackageDescription-    Distribution.PackageDescription.Check-    Distribution.PackageDescription.Configuration-    Distribution.PackageDescription.PrettyPrint-    Distribution.PackageDescription.Utils-    Distribution.Pretty-    Distribution.ReadE-    Distribution.Simple-    Distribution.Simple.Bench-    Distribution.Simple.Build-    Distribution.Simple.Build.Macros-    Distribution.Simple.Build.PathsModule-    Distribution.Simple.BuildPaths-    Distribution.Simple.BuildTarget-    Distribution.Simple.BuildToolDepends-    Distribution.Simple.CCompiler-    Distribution.Simple.Command-    Distribution.Simple.Compiler-    Distribution.Simple.Configure-    Distribution.Simple.Doctest-    Distribution.Simple.Flag-    Distribution.Simple.GHC-    Distribution.Simple.GHCJS-    Distribution.Simple.Glob-    Distribution.Simple.Haddock-    Distribution.Simple.HaskellSuite-    Distribution.Simple.Hpc-    Distribution.Simple.Install-    Distribution.Simple.InstallDirs-    Distribution.Simple.LocalBuildInfo-    Distribution.Simple.PackageIndex-    Distribution.Simple.PreProcess-    Distribution.Simple.PreProcess.Unlit-    Distribution.Simple.Program-    Distribution.Simple.Program.Ar-    Distribution.Simple.Program.Builtin-    Distribution.Simple.Program.Db-    Distribution.Simple.Program.Find-    Distribution.Simple.Program.GHC-    Distribution.Simple.Program.HcPkg-    Distribution.Simple.Program.Hpc-    Distribution.Simple.Program.Internal-    Distribution.Simple.Program.Ld-    Distribution.Simple.Program.ResponseFile-    Distribution.Simple.Program.Run-    Distribution.Simple.Program.Script-    Distribution.Simple.Program.Strip-    Distribution.Simple.Program.Types-    Distribution.Simple.Register-    Distribution.Simple.Setup-    Distribution.Simple.SrcDist-    Distribution.Simple.Test-    Distribution.Simple.Test.ExeV10-    Distribution.Simple.Test.LibV09-    Distribution.Simple.Test.Log-    Distribution.Simple.UHC-    Distribution.Simple.UserHooks-    Distribution.Simple.Utils-    Distribution.SPDX-    Distribution.SPDX.License-    Distribution.SPDX.LicenseExceptionId-    Distribution.SPDX.LicenseExpression-    Distribution.SPDX.LicenseId-    Distribution.SPDX.LicenseListVersion-    Distribution.SPDX.LicenseReference-    Distribution.System-    Distribution.TestSuite-    Distribution.Text-    Distribution.Types.AbiDependency-    Distribution.Types.AbiHash-    Distribution.Types.AnnotatedId-    Distribution.Types.Benchmark-    Distribution.Types.BenchmarkInterface-    Distribution.Types.BenchmarkType-    Distribution.Types.BuildInfo-    Distribution.Types.BuildType-    Distribution.Types.Component-    Distribution.Types.ComponentId-    Distribution.Types.ComponentInclude-    Distribution.Types.ComponentLocalBuildInfo-    Distribution.Types.ComponentName-    Distribution.Types.ComponentRequestedSpec-    Distribution.Types.Condition-    Distribution.Types.CondTree-    Distribution.Types.Dependency-    Distribution.Types.DependencyMap-    Distribution.Types.Executable-    Distribution.Types.ExecutableScope-    Distribution.Types.ExeDependency-    Distribution.Types.ExposedModule-    Distribution.Types.ForeignLib-    Distribution.Types.ForeignLibOption-    Distribution.Types.ForeignLibType-    Distribution.Types.GenericPackageDescription-    Distribution.Types.GivenComponent-    Distribution.Types.HookedBuildInfo-    Distribution.Types.IncludeRenaming-    Distribution.Types.InstalledPackageInfo-    Distribution.Types.InstalledPackageInfo.FieldGrammar-    Distribution.Types.LegacyExeDependency-    Distribution.Types.Library-    Distribution.Types.LibraryName-    Distribution.Types.LibraryVisibility-    Distribution.Types.LocalBuildInfo-    Distribution.Types.Mixin-    Distribution.Types.Module-    Distribution.Types.ModuleReexport-    Distribution.Types.ModuleRenaming-    Distribution.Types.MungedPackageId-    Distribution.Types.MungedPackageName-    Distribution.Types.PackageDescription-    Distribution.Types.PackageId-    Distribution.Types.PackageName-    Distribution.Types.PackageVersionConstraint-    Distribution.Types.PkgconfigDependency-    Distribution.Types.PkgconfigName-    Distribution.Types.SetupBuildInfo-    Distribution.Types.SourceRepo-    Distribution.Types.TargetInfo-    Distribution.Types.TestSuite-    Distribution.Types.TestSuiteInterface-    Distribution.Types.TestType-    Distribution.Types.UnitId-    Distribution.Types.UnqualComponentName-    Distribution.Types.Version-    Distribution.Types.VersionInterval-    Distribution.Types.VersionRange-    Distribution.Utils.Generic-    Distribution.Utils.IOData-    Distribution.Utils.LogProgress-    Distribution.Utils.MapAccum-    Distribution.Utils.NubList-    Distribution.Utils.Progress-    Distribution.Utils.ShortText-    Distribution.Verbosity-    Distribution.Version-    Language.Haskell.Extension--  -- Parsec parser-related modules-  build-depends:-      mtl >=2.1 && <2.3-    , parsec >=3.1.13.0 && <3.2-    , text >=1.2.3.0 && <1.3-    , transformers >=0.3 && <0.4 || >=0.4.1.0 && <0.6--  -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity-  -- See also https://github.com/ekmett/transformers-compat/issues/35-  exposed-modules:-    Distribution.Compat.CharParsing-    Distribution.Compat.Parsing-    Distribution.FieldGrammar-    Distribution.FieldGrammar.Class-    Distribution.FieldGrammar.FieldDescrs-    Distribution.FieldGrammar.Parsec-    Distribution.FieldGrammar.Pretty-    Distribution.Fields-    Distribution.Fields.ConfVar-    Distribution.Fields.Field-    Distribution.Fields.Lexer-    Distribution.Fields.LexerMonad-    Distribution.Fields.Parser-    Distribution.Fields.ParseResult-    Distribution.Fields.Pretty-    Distribution.PackageDescription.FieldGrammar-    Distribution.PackageDescription.Parsec-    Distribution.PackageDescription.Quirks-    Distribution.Parsec-    Distribution.Parsec.Error-    Distribution.Parsec.FieldLineStream-    Distribution.Parsec.Newtypes-    Distribution.Parsec.Position-    Distribution.Parsec.Warning--  -- Lens functionality-  exposed-modules:-    Distribution.Compat.Lens-    Distribution.Types.Benchmark.Lens-    Distribution.Types.BuildInfo.Lens-    Distribution.Types.Executable.Lens-    Distribution.Types.ForeignLib.Lens-    Distribution.Types.GenericPackageDescription.Lens-    Distribution.Types.InstalledPackageInfo.Lens-    Distribution.Types.Lens-    Distribution.Types.Library.Lens-    Distribution.Types.PackageDescription.Lens-    Distribution.Types.PackageId.Lens-    Distribution.Types.SetupBuildInfo.Lens-    Distribution.Types.SourceRepo.Lens-    Distribution.Types.TestSuite.Lens--  other-modules:-    Distribution.Backpack.Id-    Distribution.Backpack.MixLink-    Distribution.Backpack.ModuleScope-    Distribution.Backpack.PreExistingComponent-    Distribution.Backpack.ReadyComponent-    Distribution.Backpack.UnifyM-    Distribution.Compat.CopyFile-    Distribution.Compat.GetShortPathName-    Distribution.Compat.MonadFail-    Distribution.Compat.Prelude-    Distribution.Compat.SnocList-    Distribution.GetOpt-    Distribution.Lex-    Distribution.Simple.GHC.EnvironmentParser-    Distribution.Simple.GHC.ImplInfo-    Distribution.Simple.GHC.Internal-    Distribution.Utils.Base62-    Distribution.Utils.String-    Distribution.Utils.UnionFind-    Paths_Cabal--  if flag(bundled-binary-generic)-    other-modules:-      Distribution.Compat.Binary.Class-      Distribution.Compat.Binary.Generic--  default-language: Haskell2010-  other-extensions:-    BangPatterns-    CPP-    DefaultSignatures-    DeriveDataTypeable-    DeriveFoldable-    DeriveFunctor-    DeriveGeneric-    DeriveTraversable-    ExistentialQuantification-    FlexibleContexts-    FlexibleInstances-    GeneralizedNewtypeDeriving-    ImplicitParams-    KindSignatures-    NondecreasingIndentation-    OverloadedStrings-    RankNTypes-    RecordWildCards-    ScopedTypeVariables-    StandaloneDeriving-    Trustworthy-    TypeFamilies-    TypeOperators-    TypeSynonymInstances-    UndecidableInstances--  if impl(ghc >=7.11)-    other-extensions: PatternSynonyms---- Small, fast running tests.-test-suite unit-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests-  other-modules:-    Test.Laws-    Test.QuickCheck.Utils-    UnitTests.Distribution.Compat.CreatePipe-    UnitTests.Distribution.Compat.Graph-    UnitTests.Distribution.Compat.Time-    UnitTests.Distribution.Simple.Glob-    UnitTests.Distribution.Simple.Program.Internal-    UnitTests.Distribution.Simple.Utils-    UnitTests.Distribution.SPDX-    UnitTests.Distribution.System-    UnitTests.Distribution.Types.GenericPackageDescription-    UnitTests.Distribution.Utils.Generic-    UnitTests.Distribution.Utils.NubList-    UnitTests.Distribution.Utils.ShortText-    UnitTests.Distribution.Version--  main-is:          UnitTests.hs-  build-depends:-      array-    , base-    , bytestring-    , Cabal-    , containers-    , directory-    , filepath-    , integer-logarithms >=1.0.2 && <1.1-    , pretty-    , QuickCheck >=2.11.3 && <2.12-    , tagged-    , tasty >=1.1.0.3 && <1.2-    , tasty-hunit-    , tasty-quickcheck-    , temporary-    , text--  ghc-options:      -Wall-  default-language: Haskell2010--test-suite parser-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests-  main-is:          ParserTests.hs-  build-depends:-      base-    , base-compat >=0.10.4 && <0.11-    , bytestring-    , Cabal-    , Diff >=0.3.4 && <0.4-    , directory-    , filepath-    , tasty >=1.1.0.3 && <1.2-    , tasty-golden >=2.3.1.1 && <2.4-    , tasty-hunit-    , tasty-quickcheck--  ghc-options:      -Wall-  default-language: Haskell2010--  if impl(ghc >=7.8)-    build-depends: tree-diff >=0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--test-suite check-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests-  main-is:          CheckTests.hs-  build-depends:-      base-    , bytestring-    , Cabal-    , Diff >=0.3.4 && <0.4-    , directory-    , filepath-    , tasty >=1.1.0.3 && <1.2-    , tasty-golden >=2.3.1.1 && <2.4--  ghc-options:      -Wall-  default-language: Haskell2010--test-suite custom-setup-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests/custom-setup-  main-is:          CustomSetupTests.hs-  other-modules:-    CabalDoctestSetup-    IdrisSetup--  build-depends:-      base-    , Cabal-    , directory-    , filepath-    , process--  default-language: Haskell2010--test-suite hackage-tests-  type:               exitcode-stdio-1.0-  main-is:            HackageTests.hs--  -- TODO: need to get 01-index.tar on appveyor-  if os(windows)-    buildable: False--  hs-source-dirs:     tests-  build-depends:-      base-    , bytestring-    , Cabal-    , containers-    , deepseq-    , directory-    , filepath--  build-depends:-      base-compat >=0.10.4 && <0.11-    , base-orphans >=0.6 && <0.9-    , optparse-applicative >=0.13.2.0 && <0.15-    , stm >=2.4.5.0 && <2.6-    , tar >=0.5.0.3 && <0.6--  if impl(ghc >=7.8)-    build-depends: tree-diff >=0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--  ghc-options:        -Wall -rtsopts -threaded-  default-extensions: CPP-  default-language:   Haskell2010
− fixtures/Cabal.cabal
@@ -1,652 +0,0 @@-name:          Cabal-version:       2.5.0.0-copyright:     2003-2018, Cabal Development Team (see AUTHORS file)-license:       BSD3-license-file:  LICENSE-author:        Cabal Development Team <cabal-devel@haskell.org>-maintainer:    cabal-devel@haskell.org-homepage:      http://www.haskell.org/cabal/-bug-reports:   https://github.com/haskell/cabal/issues-synopsis:      A framework for packaging Haskell software-description:-  The Haskell Common Architecture for Building Applications and-  Libraries: a framework defining a common interface for authors to more-  easily build their Haskell applications in a portable way.-  .-  The Haskell Cabal is part of a larger infrastructure for distributing,-  organizing, and cataloging Haskell libraries and tools.-category:       Distribution-cabal-version:  >=1.10-build-type:     Simple--- If we use a new Cabal feature, this needs to be changed to Custom so--- we can bootstrap.--extra-source-files:-  README.md tests/README.md ChangeLog.md-  doc/bugs-and-stability.rst doc/concepts-and-development.rst-  doc/conf.py doc/config-and-install.rst doc/developing-packages.rst-  doc/images/Cabal-dark.png doc/index.rst doc/installing-packages.rst-  doc/intro.rst doc/misc.rst doc/nix-local-build-overview.rst-  doc/nix-local-build.rst doc/file-format-changelog.rst doc/README.md-  doc/references.inc--  -- Generated with 'make gen-extra-source-files'-  -- Do NOT edit this section manually; instead, run the script.-  -- BEGIN gen-extra-source-files-  tests/ParserTests/errors/common1.cabal-  tests/ParserTests/errors/common1.errors-  tests/ParserTests/errors/common2.cabal-  tests/ParserTests/errors/common2.errors-  tests/ParserTests/errors/common3.cabal-  tests/ParserTests/errors/common3.errors-  tests/ParserTests/errors/forward-compat.cabal-  tests/ParserTests/errors/forward-compat.errors-  tests/ParserTests/errors/forward-compat2.cabal-  tests/ParserTests/errors/forward-compat2.errors-  tests/ParserTests/errors/forward-compat3.cabal-  tests/ParserTests/errors/forward-compat3.errors-  tests/ParserTests/errors/issue-5055-2.cabal-  tests/ParserTests/errors/issue-5055-2.errors-  tests/ParserTests/errors/issue-5055.cabal-  tests/ParserTests/errors/issue-5055.errors-  tests/ParserTests/errors/leading-comma-2.cabal-  tests/ParserTests/errors/leading-comma-2.errors-  tests/ParserTests/errors/leading-comma-2b.cabal-  tests/ParserTests/errors/leading-comma-2b.errors-  tests/ParserTests/errors/leading-comma-2c.cabal-  tests/ParserTests/errors/leading-comma-2c.errors-  tests/ParserTests/errors/leading-comma.cabal-  tests/ParserTests/errors/leading-comma.errors-  tests/ParserTests/errors/multiple-libs.cabal-  tests/ParserTests/errors/multiple-libs.errors-  tests/ParserTests/errors/noVersion.cabal-  tests/ParserTests/errors/noVersion.errors-  tests/ParserTests/errors/noVersion2.cabal-  tests/ParserTests/errors/noVersion2.errors-  tests/ParserTests/errors/range-ge-wild.cabal-  tests/ParserTests/errors/range-ge-wild.errors-  tests/ParserTests/errors/removed-fields.cabal-  tests/ParserTests/errors/removed-fields.errors-  tests/ParserTests/errors/spdx-1.cabal-  tests/ParserTests/errors/spdx-1.errors-  tests/ParserTests/errors/spdx-2.cabal-  tests/ParserTests/errors/spdx-2.errors-  tests/ParserTests/errors/spdx-3.cabal-  tests/ParserTests/errors/spdx-3.errors-  tests/ParserTests/ipi/Includes2.cabal-  tests/ParserTests/ipi/Includes2.expr-  tests/ParserTests/ipi/Includes2.format-  tests/ParserTests/ipi/internal-preprocessor-test.cabal-  tests/ParserTests/ipi/internal-preprocessor-test.expr-  tests/ParserTests/ipi/internal-preprocessor-test.format-  tests/ParserTests/ipi/issue-2276-ghc-9885.cabal-  tests/ParserTests/ipi/issue-2276-ghc-9885.expr-  tests/ParserTests/ipi/issue-2276-ghc-9885.format-  tests/ParserTests/ipi/transformers.cabal-  tests/ParserTests/ipi/transformers.expr-  tests/ParserTests/ipi/transformers.format-  tests/ParserTests/regressions/MiniAgda.cabal-  tests/ParserTests/regressions/MiniAgda.check-  tests/ParserTests/regressions/Octree-0.5.cabal-  tests/ParserTests/regressions/Octree-0.5.expr-  tests/ParserTests/regressions/Octree-0.5.format-  tests/ParserTests/regressions/bad-glob-syntax.cabal-  tests/ParserTests/regressions/bad-glob-syntax.check-  tests/ParserTests/regressions/cc-options-with-optimization.cabal-  tests/ParserTests/regressions/cc-options-with-optimization.check-  tests/ParserTests/regressions/common-conditional.cabal-  tests/ParserTests/regressions/common-conditional.expr-  tests/ParserTests/regressions/common-conditional.format-  tests/ParserTests/regressions/common.cabal-  tests/ParserTests/regressions/common.expr-  tests/ParserTests/regressions/common.format-  tests/ParserTests/regressions/common2.cabal-  tests/ParserTests/regressions/common2.expr-  tests/ParserTests/regressions/common2.format-  tests/ParserTests/regressions/cxx-options-with-optimization.cabal-  tests/ParserTests/regressions/cxx-options-with-optimization.check-  tests/ParserTests/regressions/elif.cabal-  tests/ParserTests/regressions/elif.expr-  tests/ParserTests/regressions/elif.format-  tests/ParserTests/regressions/elif2.cabal-  tests/ParserTests/regressions/elif2.expr-  tests/ParserTests/regressions/elif2.format-  tests/ParserTests/regressions/encoding-0.8.cabal-  tests/ParserTests/regressions/encoding-0.8.expr-  tests/ParserTests/regressions/encoding-0.8.format-  tests/ParserTests/regressions/extensions-paths-5054.cabal-  tests/ParserTests/regressions/extensions-paths-5054.check-  tests/ParserTests/regressions/generics-sop.cabal-  tests/ParserTests/regressions/generics-sop.expr-  tests/ParserTests/regressions/generics-sop.format-  tests/ParserTests/regressions/ghc-option-j.cabal-  tests/ParserTests/regressions/ghc-option-j.check-  tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal-  tests/ParserTests/regressions/haddock-api-2.18.1-check.check-  tests/ParserTests/regressions/hidden-main-lib.cabal-  tests/ParserTests/regressions/hidden-main-lib.expr-  tests/ParserTests/regressions/hidden-main-lib.format-  tests/ParserTests/regressions/issue-5055.cabal-  tests/ParserTests/regressions/issue-5055.expr-  tests/ParserTests/regressions/issue-5055.format-  tests/ParserTests/regressions/issue-774.cabal-  tests/ParserTests/regressions/issue-774.check-  tests/ParserTests/regressions/issue-774.expr-  tests/ParserTests/regressions/issue-774.format-  tests/ParserTests/regressions/jaeger-flamegraph.cabal-  tests/ParserTests/regressions/jaeger-flamegraph.expr-  tests/ParserTests/regressions/jaeger-flamegraph.format-  tests/ParserTests/regressions/leading-comma-2.cabal-  tests/ParserTests/regressions/leading-comma-2.expr-  tests/ParserTests/regressions/leading-comma-2.format-  tests/ParserTests/regressions/leading-comma.cabal-  tests/ParserTests/regressions/leading-comma.expr-  tests/ParserTests/regressions/leading-comma.format-  tests/ParserTests/regressions/multiple-libs-2.cabal-  tests/ParserTests/regressions/multiple-libs-2.check-  tests/ParserTests/regressions/multiple-libs-2.expr-  tests/ParserTests/regressions/multiple-libs-2.format-  tests/ParserTests/regressions/noVersion.cabal-  tests/ParserTests/regressions/noVersion.expr-  tests/ParserTests/regressions/noVersion.format-  tests/ParserTests/regressions/nothing-unicode.cabal-  tests/ParserTests/regressions/nothing-unicode.check-  tests/ParserTests/regressions/nothing-unicode.expr-  tests/ParserTests/regressions/nothing-unicode.format-  tests/ParserTests/regressions/pre-1.6-glob.cabal-  tests/ParserTests/regressions/pre-1.6-glob.check-  tests/ParserTests/regressions/pre-2.4-globstar.cabal-  tests/ParserTests/regressions/pre-2.4-globstar.check-  tests/ParserTests/regressions/shake.cabal-  tests/ParserTests/regressions/shake.expr-  tests/ParserTests/regressions/shake.format-  tests/ParserTests/regressions/spdx-1.cabal-  tests/ParserTests/regressions/spdx-1.expr-  tests/ParserTests/regressions/spdx-1.format-  tests/ParserTests/regressions/spdx-2.cabal-  tests/ParserTests/regressions/spdx-2.expr-  tests/ParserTests/regressions/spdx-2.format-  tests/ParserTests/regressions/spdx-3.cabal-  tests/ParserTests/regressions/spdx-3.expr-  tests/ParserTests/regressions/spdx-3.format-  tests/ParserTests/regressions/th-lift-instances.cabal-  tests/ParserTests/regressions/th-lift-instances.expr-  tests/ParserTests/regressions/th-lift-instances.format-  tests/ParserTests/regressions/wl-pprint-indef.cabal-  tests/ParserTests/regressions/wl-pprint-indef.expr-  tests/ParserTests/regressions/wl-pprint-indef.format-  tests/ParserTests/warnings/bom.cabal-  tests/ParserTests/warnings/bool.cabal-  tests/ParserTests/warnings/deprecatedfield.cabal-  tests/ParserTests/warnings/doubledash.cabal-  tests/ParserTests/warnings/extratestmodule.cabal-  tests/ParserTests/warnings/gluedop.cabal-  tests/ParserTests/warnings/multiplesingular.cabal-  tests/ParserTests/warnings/nbsp.cabal-  tests/ParserTests/warnings/newsyntax.cabal-  tests/ParserTests/warnings/oldsyntax.cabal-  tests/ParserTests/warnings/subsection.cabal-  tests/ParserTests/warnings/tab.cabal-  tests/ParserTests/warnings/trailingfield.cabal-  tests/ParserTests/warnings/unknownfield.cabal-  tests/ParserTests/warnings/unknownsection.cabal-  tests/ParserTests/warnings/utf8.cabal-  tests/ParserTests/warnings/versiontag.cabal-  tests/hackage/check.sh-  tests/hackage/download.sh-  tests/hackage/unpack.sh-  tests/misc/ghc-supported-languages.hs-  -- END gen-extra-source-files--source-repository head-  type:     git-  location: https://github.com/haskell/cabal/-  subdir:   Cabal--flag bundled-binary-generic-  default: False--library-  build-depends:-    array      >= 0.4.0.1  && < 0.6,-    base       >= 4.6      && < 5,-    bytestring >= 0.10.0.0 && < 0.11,-    containers >= 0.5.0.0  && < 0.7,-    deepseq    >= 1.3.0.1  && < 1.5,-    directory  >= 1.2      && < 1.4,-    filepath   >= 1.3.0.1  && < 1.5,-    pretty     >= 1.1.1    && < 1.2,-    process    >= 1.1.0.2  && < 1.7,-    time       >= 1.4.0.1  && < 1.10--  if flag(bundled-binary-generic)-    build-depends: binary >= 0.5.1.1 && < 0.7-  else-    build-depends: binary >= 0.7 && < 0.9--  if os(windows)-    build-depends: Win32 >= 2.3.0.0 && < 2.9-  else-    build-depends: unix  >= 2.6.0.0 && < 2.8--  ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs-  if impl(ghc >= 8.0)-    ghc-options: -Wcompat -Wnoncanonical-monad-instances-                 -Wnoncanonical-monadfail-instances--  exposed-modules:-    Distribution.Backpack-    Distribution.Backpack.Configure-    Distribution.Backpack.ComponentsGraph-    Distribution.Backpack.ConfiguredComponent-    Distribution.Backpack.DescribeUnitId-    Distribution.Backpack.FullUnitId-    Distribution.Backpack.LinkedComponent-    Distribution.Backpack.ModSubst-    Distribution.Backpack.ModuleShape-    Distribution.Backpack.PreModuleShape-    Distribution.CabalSpecVersion-    Distribution.Utils.IOData-    Distribution.Utils.LogProgress-    Distribution.Utils.MapAccum-    Distribution.Compat.CreatePipe-    Distribution.Compat.Directory-    Distribution.Compat.Environment-    Distribution.Compat.Exception-    Distribution.Compat.Graph-    Distribution.Compat.Internal.TempFile-    Distribution.Compat.Newtype-    Distribution.Compat.Prelude.Internal-    Distribution.Compat.Semigroup-    Distribution.Compat.Stack-    Distribution.Compat.Time-    Distribution.Compat.DList-    Distribution.Compiler-    Distribution.InstalledPackageInfo-    Distribution.Types.AbiDependency-    Distribution.Types.ExposedModule-    Distribution.Types.InstalledPackageInfo-    Distribution.Types.InstalledPackageInfo.FieldGrammar-    Distribution.License-    Distribution.Make-    Distribution.ModuleName-    Distribution.Package-    Distribution.PackageDescription-    Distribution.PackageDescription.Check-    Distribution.PackageDescription.Configuration-    Distribution.PackageDescription.PrettyPrint-    Distribution.PackageDescription.Utils-    Distribution.ReadE-    Distribution.Simple-    Distribution.Simple.Bench-    Distribution.Simple.Build-    Distribution.Simple.Build.Macros-    Distribution.Simple.Build.PathsModule-    Distribution.Simple.BuildPaths-    Distribution.Simple.BuildTarget-    Distribution.Simple.BuildToolDepends-    Distribution.Simple.CCompiler-    Distribution.Simple.Command-    Distribution.Simple.Compiler-    Distribution.Simple.Configure-    Distribution.Simple.Flag-    Distribution.Simple.GHC-    Distribution.Simple.GHCJS-    Distribution.Simple.Haddock-    Distribution.Simple.Doctest-    Distribution.Simple.Glob-    Distribution.Simple.HaskellSuite-    Distribution.Simple.Hpc-    Distribution.Simple.Install-    Distribution.Simple.InstallDirs-    Distribution.Simple.LocalBuildInfo-    Distribution.Simple.PackageIndex-    Distribution.Simple.PreProcess-    Distribution.Simple.PreProcess.Unlit-    Distribution.Simple.Program-    Distribution.Simple.Program.Ar-    Distribution.Simple.Program.Builtin-    Distribution.Simple.Program.Db-    Distribution.Simple.Program.Find-    Distribution.Simple.Program.GHC-    Distribution.Simple.Program.HcPkg-    Distribution.Simple.Program.Hpc-    Distribution.Simple.Program.Internal-    Distribution.Simple.Program.Ld-    Distribution.Simple.Program.ResponseFile-    Distribution.Simple.Program.Run-    Distribution.Simple.Program.Script-    Distribution.Simple.Program.Strip-    Distribution.Simple.Program.Types-    Distribution.Simple.Register-    Distribution.Simple.Setup-    Distribution.Simple.SrcDist-    Distribution.Simple.Test-    Distribution.Simple.Test.ExeV10-    Distribution.Simple.Test.LibV09-    Distribution.Simple.Test.Log-    Distribution.Simple.UHC-    Distribution.Simple.UserHooks-    Distribution.Simple.Utils-    Distribution.SPDX-    Distribution.SPDX.License-    Distribution.SPDX.LicenseId-    Distribution.SPDX.LicenseExceptionId-    Distribution.SPDX.LicenseExpression-    Distribution.SPDX.LicenseListVersion-    Distribution.SPDX.LicenseReference-    Distribution.System-    Distribution.TestSuite-    Distribution.Text-    Distribution.Pretty-    Distribution.Types.AbiHash-    Distribution.Types.AnnotatedId-    Distribution.Types.Benchmark-    Distribution.Types.BenchmarkInterface-    Distribution.Types.BenchmarkType-    Distribution.Types.BuildInfo-    Distribution.Types.BuildType-    Distribution.Types.ComponentInclude-    Distribution.Types.Dependency-    Distribution.Types.ExeDependency-    Distribution.Types.LegacyExeDependency-    Distribution.Types.PkgconfigDependency-    Distribution.Types.DependencyMap-    Distribution.Types.ComponentId-    Distribution.Types.MungedPackageId-    Distribution.Types.PackageId-    Distribution.Types.UnitId-    Distribution.Types.Executable-    Distribution.Types.ExecutableScope-    Distribution.Types.Library-    Distribution.Types.LibraryVisibility-    Distribution.Types.ForeignLib-    Distribution.Types.ForeignLibType-    Distribution.Types.ForeignLibOption-    Distribution.Types.Module-    Distribution.Types.ModuleReexport-    Distribution.Types.ModuleRenaming-    Distribution.Types.ComponentName-    Distribution.Types.LibraryName-    Distribution.Types.MungedPackageName-    Distribution.Types.PackageName-    Distribution.Types.PkgconfigName-    Distribution.Types.UnqualComponentName-    Distribution.Types.IncludeRenaming-    Distribution.Types.Mixin-    Distribution.Types.SetupBuildInfo-    Distribution.Types.TestSuite-    Distribution.Types.TestSuiteInterface-    Distribution.Types.TestType-    Distribution.Types.GenericPackageDescription-    Distribution.Types.Condition-    Distribution.Types.CondTree-    Distribution.Types.HookedBuildInfo-    Distribution.Types.PackageDescription-    Distribution.Types.SourceRepo-    Distribution.Types.Component-    Distribution.Types.ComponentLocalBuildInfo-    Distribution.Types.LocalBuildInfo-    Distribution.Types.ComponentRequestedSpec-    Distribution.Types.TargetInfo-    Distribution.Types.Version-    Distribution.Types.VersionRange-    Distribution.Types.VersionInterval-    Distribution.Types.GivenComponent-    Distribution.Types.PackageVersionConstraint-    Distribution.Utils.Generic-    Distribution.Utils.NubList-    Distribution.Utils.ShortText-    Distribution.Utils.Progress-    Distribution.Verbosity-    Distribution.Version-    Language.Haskell.Extension-    Distribution.Compat.Binary--  -- Parsec parser-related modules-  build-depends:-    -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity-    -- See also https://github.com/ekmett/transformers-compat/issues/35-    transformers (>= 0.3      && < 0.4) || (>=0.4.1.0 && <0.6),-    mtl           >= 2.1      && < 2.3,-    text          >= 1.2.3.0  && < 1.3,-    parsec        >= 3.1.13.0 && < 3.2-  exposed-modules:-    Distribution.Compat.Parsing-    Distribution.Compat.CharParsing-    Distribution.FieldGrammar-    Distribution.FieldGrammar.Class-    Distribution.FieldGrammar.FieldDescrs-    Distribution.FieldGrammar.Parsec-    Distribution.FieldGrammar.Pretty-    Distribution.PackageDescription.FieldGrammar-    Distribution.PackageDescription.Parsec-    Distribution.PackageDescription.Quirks-    Distribution.Parsec-    Distribution.Parsec.Error-    Distribution.Parsec.Newtypes-    Distribution.Parsec.Position-    Distribution.Parsec.Warning-    Distribution.Parsec.FieldLineStream-    Distribution.Fields-    Distribution.Fields.ConfVar-    Distribution.Fields.Field-    Distribution.Fields.Lexer-    Distribution.Fields.LexerMonad-    Distribution.Fields.ParseResult-    Distribution.Fields.Parser-    Distribution.Fields.Pretty--  -- Lens functionality-  exposed-modules:-    Distribution.Compat.Lens-    Distribution.Types.Lens-    Distribution.Types.Benchmark.Lens-    Distribution.Types.BuildInfo.Lens-    Distribution.Types.Executable.Lens-    Distribution.Types.ForeignLib.Lens-    Distribution.Types.GenericPackageDescription.Lens-    Distribution.Types.InstalledPackageInfo.Lens-    Distribution.Types.Library.Lens-    Distribution.Types.PackageDescription.Lens-    Distribution.Types.PackageId.Lens-    Distribution.Types.SetupBuildInfo.Lens-    Distribution.Types.SourceRepo.Lens-    Distribution.Types.TestSuite.Lens--  other-modules:-    Distribution.Backpack.PreExistingComponent-    Distribution.Backpack.ReadyComponent-    Distribution.Backpack.MixLink-    Distribution.Backpack.ModuleScope-    Distribution.Backpack.UnifyM-    Distribution.Backpack.Id-    Distribution.Utils.UnionFind-    Distribution.Utils.Base62-    Distribution.Compat.CopyFile-    Distribution.Compat.GetShortPathName-    Distribution.Compat.MonadFail-    Distribution.Compat.Prelude-    Distribution.Compat.SnocList-    Distribution.GetOpt-    Distribution.Lex-    Distribution.Utils.String-    Distribution.Simple.GHC.EnvironmentParser-    Distribution.Simple.GHC.Internal-    Distribution.Simple.GHC.ImplInfo-    Paths_Cabal--  if flag(bundled-binary-generic)-    other-modules:-      Distribution.Compat.Binary.Class-      Distribution.Compat.Binary.Generic--  default-language: Haskell2010-  other-extensions:-    BangPatterns-    CPP-    DefaultSignatures-    DeriveDataTypeable-    DeriveFoldable-    DeriveFunctor-    DeriveGeneric-    DeriveTraversable-    ExistentialQuantification-    FlexibleContexts-    FlexibleInstances-    GeneralizedNewtypeDeriving-    ImplicitParams-    KindSignatures-    NondecreasingIndentation-    OverloadedStrings-    RankNTypes-    RecordWildCards-    ScopedTypeVariables-    StandaloneDeriving-    Trustworthy-    TypeFamilies-    TypeOperators-    TypeSynonymInstances-    UndecidableInstances--  if impl(ghc >= 7.11)-    other-extensions: PatternSynonyms---- Small, fast running tests.-test-suite unit-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests-  other-modules:-    Test.Laws-    Test.QuickCheck.Utils-    UnitTests.Distribution.Compat.CreatePipe-    UnitTests.Distribution.Compat.Time-    UnitTests.Distribution.Compat.Graph-    UnitTests.Distribution.Simple.Glob-    UnitTests.Distribution.Simple.Program.Internal-    UnitTests.Distribution.Simple.Utils-    UnitTests.Distribution.SPDX-    UnitTests.Distribution.System-    UnitTests.Distribution.Types.GenericPackageDescription-    UnitTests.Distribution.Utils.Generic-    UnitTests.Distribution.Utils.NubList-    UnitTests.Distribution.Utils.ShortText-    UnitTests.Distribution.Version-  main-is: UnitTests.hs-  build-depends:-    array,-    base,-    bytestring,-    containers,-    directory,-    filepath,-    integer-logarithms >= 1.0.2 && <1.1,-    tasty >= 1.1.0.3 && < 1.2,-    tasty-hunit,-    tasty-quickcheck,-    tagged,-    temporary,-    text,-    pretty,-    QuickCheck >= 2.11.3 && < 2.12,-    Cabal-  ghc-options: -Wall-  default-language: Haskell2010--test-suite parser-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests-  main-is: ParserTests.hs-  build-depends:-    base,-    base-compat >=0.10.4 && <0.11,-    bytestring,-    directory,-    filepath,-    tasty >= 1.1.0.3 && < 1.2,-    tasty-hunit,-    tasty-quickcheck,-    tasty-golden >=2.3.1.1 && <2.4,-    Diff >=0.3.4 && <0.4,-    Cabal-  ghc-options: -Wall-  default-language: Haskell2010--  if impl(ghc >= 7.8)-    build-depends:-      tree-diff      >= 0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--test-suite check-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests-  main-is: CheckTests.hs-  build-depends:-    base,-    bytestring,-    directory,-    filepath,-    tasty >= 1.1.0.3 && < 1.2,-    tasty-golden >=2.3.1.1 && <2.4,-    Diff >=0.3.4 && <0.4,-    Cabal-  ghc-options: -Wall-  default-language: Haskell2010--test-suite custom-setup-tests-  type: exitcode-stdio-1.0-  hs-source-dirs: tests/custom-setup-  main-is: CustomSetupTests.hs-  other-modules:-    CabalDoctestSetup-    IdrisSetup-  build-depends:-    Cabal,-    base,-    directory,-    filepath,-    process-  default-language: Haskell2010--test-suite hackage-tests-  type: exitcode-stdio-1.0-  main-is: HackageTests.hs--  -- TODO: need to get 01-index.tar on appveyor-  if os(windows)-    buildable: False--  hs-source-dirs: tests--  build-depends:-    base,-    Cabal,-    bytestring,-    deepseq,-    containers,-    directory,-    filepath--  build-depends:-    base-compat          >=0.10.4   && <0.11,-    base-orphans         >=0.6      && <0.9,-    optparse-applicative >=0.13.2.0 && <0.15,-    stm                  >=2.4.5.0  && <2.6,-    tar                  >=0.5.0.3  && <0.6--  if impl(ghc >= 7.8)-    build-depends:-      tree-diff      >= 0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--  ghc-options: -Wall -rtsopts -threaded-  default-extensions: CPP-  default-language: Haskell2010
− fixtures/Cabal.format
@@ -1,673 +0,0 @@-name:               Cabal-version:            2.5.0.0-copyright:          2003-2018, Cabal Development Team (see AUTHORS file)-license:            BSD3-license-file:       LICENSE-author:             Cabal Development Team <cabal-devel@haskell.org>-maintainer:         cabal-devel@haskell.org-homepage:           http://www.haskell.org/cabal/-bug-reports:        https://github.com/haskell/cabal/issues-synopsis:           A framework for packaging Haskell software-description:-  The Haskell Common Architecture for Building Applications and-  Libraries: a framework defining a common interface for authors to more-  easily build their Haskell applications in a portable way.-  .-  The Haskell Cabal is part of a larger infrastructure for distributing,-  organizing, and cataloging Haskell libraries and tools.--category:           Distribution-cabal-version:      >=1.10-build-type:         Simple---- If we use a new Cabal feature, this needs to be changed to Custom so--- we can bootstrap.--extra-source-files:-  ChangeLog.md-  doc/bugs-and-stability.rst-  doc/concepts-and-development.rst-  doc/conf.py-  doc/config-and-install.rst-  doc/developing-packages.rst-  doc/file-format-changelog.rst-  doc/images/Cabal-dark.png-  doc/index.rst-  doc/installing-packages.rst-  doc/intro.rst-  doc/misc.rst-  doc/nix-local-build-overview.rst-  doc/nix-local-build.rst-  doc/README.md-  doc/references.inc-  README.md-  tests/hackage/check.sh-  tests/hackage/download.sh-  tests/hackage/unpack.sh-  tests/misc/ghc-supported-languages.hs-  tests/ParserTests/errors/common1.cabal-  tests/ParserTests/errors/common1.errors-  tests/ParserTests/errors/common2.cabal-  tests/ParserTests/errors/common2.errors-  tests/ParserTests/errors/common3.cabal-  tests/ParserTests/errors/common3.errors-  tests/ParserTests/errors/forward-compat.cabal-  tests/ParserTests/errors/forward-compat.errors-  tests/ParserTests/errors/forward-compat2.cabal-  tests/ParserTests/errors/forward-compat2.errors-  tests/ParserTests/errors/forward-compat3.cabal-  tests/ParserTests/errors/forward-compat3.errors-  tests/ParserTests/errors/issue-5055-2.cabal-  tests/ParserTests/errors/issue-5055-2.errors-  tests/ParserTests/errors/issue-5055.cabal-  tests/ParserTests/errors/issue-5055.errors-  tests/ParserTests/errors/leading-comma-2.cabal-  tests/ParserTests/errors/leading-comma-2.errors-  tests/ParserTests/errors/leading-comma-2b.cabal-  tests/ParserTests/errors/leading-comma-2b.errors-  tests/ParserTests/errors/leading-comma-2c.cabal-  tests/ParserTests/errors/leading-comma-2c.errors-  tests/ParserTests/errors/leading-comma.cabal-  tests/ParserTests/errors/leading-comma.errors-  tests/ParserTests/errors/multiple-libs.cabal-  tests/ParserTests/errors/multiple-libs.errors-  tests/ParserTests/errors/noVersion.cabal-  tests/ParserTests/errors/noVersion.errors-  tests/ParserTests/errors/noVersion2.cabal-  tests/ParserTests/errors/noVersion2.errors-  tests/ParserTests/errors/range-ge-wild.cabal-  tests/ParserTests/errors/range-ge-wild.errors-  tests/ParserTests/errors/removed-fields.cabal-  tests/ParserTests/errors/removed-fields.errors-  tests/ParserTests/errors/spdx-1.cabal-  tests/ParserTests/errors/spdx-1.errors-  tests/ParserTests/errors/spdx-2.cabal-  tests/ParserTests/errors/spdx-2.errors-  tests/ParserTests/errors/spdx-3.cabal-  tests/ParserTests/errors/spdx-3.errors-  tests/ParserTests/ipi/Includes2.cabal-  tests/ParserTests/ipi/Includes2.expr-  tests/ParserTests/ipi/Includes2.format-  tests/ParserTests/ipi/internal-preprocessor-test.cabal-  tests/ParserTests/ipi/internal-preprocessor-test.expr-  tests/ParserTests/ipi/internal-preprocessor-test.format-  tests/ParserTests/ipi/issue-2276-ghc-9885.cabal-  tests/ParserTests/ipi/issue-2276-ghc-9885.expr-  tests/ParserTests/ipi/issue-2276-ghc-9885.format-  tests/ParserTests/ipi/transformers.cabal-  tests/ParserTests/ipi/transformers.expr-  tests/ParserTests/ipi/transformers.format-  tests/ParserTests/regressions/bad-glob-syntax.cabal-  tests/ParserTests/regressions/bad-glob-syntax.check-  tests/ParserTests/regressions/cc-options-with-optimization.cabal-  tests/ParserTests/regressions/cc-options-with-optimization.check-  tests/ParserTests/regressions/common-conditional.cabal-  tests/ParserTests/regressions/common-conditional.expr-  tests/ParserTests/regressions/common-conditional.format-  tests/ParserTests/regressions/common.cabal-  tests/ParserTests/regressions/common.expr-  tests/ParserTests/regressions/common.format-  tests/ParserTests/regressions/common2.cabal-  tests/ParserTests/regressions/common2.expr-  tests/ParserTests/regressions/common2.format-  tests/ParserTests/regressions/cxx-options-with-optimization.cabal-  tests/ParserTests/regressions/cxx-options-with-optimization.check-  tests/ParserTests/regressions/elif.cabal-  tests/ParserTests/regressions/elif.expr-  tests/ParserTests/regressions/elif.format-  tests/ParserTests/regressions/elif2.cabal-  tests/ParserTests/regressions/elif2.expr-  tests/ParserTests/regressions/elif2.format-  tests/ParserTests/regressions/encoding-0.8.cabal-  tests/ParserTests/regressions/encoding-0.8.expr-  tests/ParserTests/regressions/encoding-0.8.format-  tests/ParserTests/regressions/extensions-paths-5054.cabal-  tests/ParserTests/regressions/extensions-paths-5054.check-  tests/ParserTests/regressions/generics-sop.cabal-  tests/ParserTests/regressions/generics-sop.expr-  tests/ParserTests/regressions/generics-sop.format-  tests/ParserTests/regressions/ghc-option-j.cabal-  tests/ParserTests/regressions/ghc-option-j.check-  tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal-  tests/ParserTests/regressions/haddock-api-2.18.1-check.check-  tests/ParserTests/regressions/hidden-main-lib.cabal-  tests/ParserTests/regressions/hidden-main-lib.expr-  tests/ParserTests/regressions/hidden-main-lib.format-  tests/ParserTests/regressions/issue-5055.cabal-  tests/ParserTests/regressions/issue-5055.expr-  tests/ParserTests/regressions/issue-5055.format-  tests/ParserTests/regressions/issue-774.cabal-  tests/ParserTests/regressions/issue-774.check-  tests/ParserTests/regressions/issue-774.expr-  tests/ParserTests/regressions/issue-774.format-  tests/ParserTests/regressions/jaeger-flamegraph.cabal-  tests/ParserTests/regressions/jaeger-flamegraph.expr-  tests/ParserTests/regressions/jaeger-flamegraph.format-  tests/ParserTests/regressions/leading-comma-2.cabal-  tests/ParserTests/regressions/leading-comma-2.expr-  tests/ParserTests/regressions/leading-comma-2.format-  tests/ParserTests/regressions/leading-comma.cabal-  tests/ParserTests/regressions/leading-comma.expr-  tests/ParserTests/regressions/leading-comma.format-  tests/ParserTests/regressions/MiniAgda.cabal-  tests/ParserTests/regressions/MiniAgda.check-  tests/ParserTests/regressions/multiple-libs-2.cabal-  tests/ParserTests/regressions/multiple-libs-2.check-  tests/ParserTests/regressions/multiple-libs-2.expr-  tests/ParserTests/regressions/multiple-libs-2.format-  tests/ParserTests/regressions/nothing-unicode.cabal-  tests/ParserTests/regressions/nothing-unicode.check-  tests/ParserTests/regressions/nothing-unicode.expr-  tests/ParserTests/regressions/nothing-unicode.format-  tests/ParserTests/regressions/noVersion.cabal-  tests/ParserTests/regressions/noVersion.expr-  tests/ParserTests/regressions/noVersion.format-  tests/ParserTests/regressions/Octree-0.5.cabal-  tests/ParserTests/regressions/Octree-0.5.expr-  tests/ParserTests/regressions/Octree-0.5.format-  tests/ParserTests/regressions/pre-1.6-glob.cabal-  tests/ParserTests/regressions/pre-1.6-glob.check-  tests/ParserTests/regressions/pre-2.4-globstar.cabal-  tests/ParserTests/regressions/pre-2.4-globstar.check-  tests/ParserTests/regressions/shake.cabal-  tests/ParserTests/regressions/shake.expr-  tests/ParserTests/regressions/shake.format-  tests/ParserTests/regressions/spdx-1.cabal-  tests/ParserTests/regressions/spdx-1.expr-  tests/ParserTests/regressions/spdx-1.format-  tests/ParserTests/regressions/spdx-2.cabal-  tests/ParserTests/regressions/spdx-2.expr-  tests/ParserTests/regressions/spdx-2.format-  tests/ParserTests/regressions/spdx-3.cabal-  tests/ParserTests/regressions/spdx-3.expr-  tests/ParserTests/regressions/spdx-3.format-  tests/ParserTests/regressions/th-lift-instances.cabal-  tests/ParserTests/regressions/th-lift-instances.expr-  tests/ParserTests/regressions/th-lift-instances.format-  tests/ParserTests/regressions/wl-pprint-indef.cabal-  tests/ParserTests/regressions/wl-pprint-indef.expr-  tests/ParserTests/regressions/wl-pprint-indef.format-  tests/ParserTests/warnings/bom.cabal-  tests/ParserTests/warnings/bool.cabal-  tests/ParserTests/warnings/deprecatedfield.cabal-  tests/ParserTests/warnings/doubledash.cabal-  tests/ParserTests/warnings/extratestmodule.cabal-  tests/ParserTests/warnings/gluedop.cabal-  tests/ParserTests/warnings/multiplesingular.cabal-  tests/ParserTests/warnings/nbsp.cabal-  tests/ParserTests/warnings/newsyntax.cabal-  tests/ParserTests/warnings/oldsyntax.cabal-  tests/ParserTests/warnings/subsection.cabal-  tests/ParserTests/warnings/tab.cabal-  tests/ParserTests/warnings/trailingfield.cabal-  tests/ParserTests/warnings/unknownfield.cabal-  tests/ParserTests/warnings/unknownsection.cabal-  tests/ParserTests/warnings/utf8.cabal-  tests/ParserTests/warnings/versiontag.cabal-  tests/README.md---- Generated with 'make gen-extra-source-files'--- Do NOT edit this section manually; instead, run the script.--- BEGIN gen-extra-source-files--- END gen-extra-source-files--source-repository head-  type:     git-  location: https://github.com/haskell/cabal/-  subdir:   Cabal--flag bundled-binary-generic-  default: False--library-  build-depends:-      array       >=0.4.0.1  && <0.6-    , base        >=4.6      && <5-    , bytestring  >=0.10.0.0 && <0.11-    , containers  >=0.5.0.0  && <0.7-    , deepseq     >=1.3.0.1  && <1.5-    , directory   >=1.2      && <1.4-    , filepath    >=1.3.0.1  && <1.5-    , pretty      >=1.1.1    && <1.2-    , process     >=1.1.0.2  && <1.7-    , time        >=1.4.0.1  && <1.10--  if flag(bundled-binary-generic)-    build-depends: binary >=0.5.1.1 && <0.7--  else-    build-depends: binary >=0.7 && <0.9--  if os(windows)-    build-depends: Win32 >=2.3.0.0 && <2.9--  else-    build-depends: unix >=2.6.0.0 && <2.8--  ghc-options:      -Wall -fno-ignore-asserts -fwarn-tabs--  if impl(ghc >=8.0)-    ghc-options:-      -Wcompat -Wnoncanonical-monad-instances-      -Wnoncanonical-monadfail-instances--  exposed-modules:-    Distribution.Backpack-    Distribution.Backpack.ComponentsGraph-    Distribution.Backpack.Configure-    Distribution.Backpack.ConfiguredComponent-    Distribution.Backpack.DescribeUnitId-    Distribution.Backpack.FullUnitId-    Distribution.Backpack.LinkedComponent-    Distribution.Backpack.ModSubst-    Distribution.Backpack.ModuleShape-    Distribution.Backpack.PreModuleShape-    Distribution.CabalSpecVersion-    Distribution.Compat.Binary-    Distribution.Compat.CreatePipe-    Distribution.Compat.Directory-    Distribution.Compat.DList-    Distribution.Compat.Environment-    Distribution.Compat.Exception-    Distribution.Compat.Graph-    Distribution.Compat.Internal.TempFile-    Distribution.Compat.Newtype-    Distribution.Compat.Prelude.Internal-    Distribution.Compat.Semigroup-    Distribution.Compat.Stack-    Distribution.Compat.Time-    Distribution.Compiler-    Distribution.InstalledPackageInfo-    Distribution.License-    Distribution.Make-    Distribution.ModuleName-    Distribution.Package-    Distribution.PackageDescription-    Distribution.PackageDescription.Check-    Distribution.PackageDescription.Configuration-    Distribution.PackageDescription.PrettyPrint-    Distribution.PackageDescription.Utils-    Distribution.Pretty-    Distribution.ReadE-    Distribution.Simple-    Distribution.Simple.Bench-    Distribution.Simple.Build-    Distribution.Simple.Build.Macros-    Distribution.Simple.Build.PathsModule-    Distribution.Simple.BuildPaths-    Distribution.Simple.BuildTarget-    Distribution.Simple.BuildToolDepends-    Distribution.Simple.CCompiler-    Distribution.Simple.Command-    Distribution.Simple.Compiler-    Distribution.Simple.Configure-    Distribution.Simple.Doctest-    Distribution.Simple.Flag-    Distribution.Simple.GHC-    Distribution.Simple.GHCJS-    Distribution.Simple.Glob-    Distribution.Simple.Haddock-    Distribution.Simple.HaskellSuite-    Distribution.Simple.Hpc-    Distribution.Simple.Install-    Distribution.Simple.InstallDirs-    Distribution.Simple.LocalBuildInfo-    Distribution.Simple.PackageIndex-    Distribution.Simple.PreProcess-    Distribution.Simple.PreProcess.Unlit-    Distribution.Simple.Program-    Distribution.Simple.Program.Ar-    Distribution.Simple.Program.Builtin-    Distribution.Simple.Program.Db-    Distribution.Simple.Program.Find-    Distribution.Simple.Program.GHC-    Distribution.Simple.Program.HcPkg-    Distribution.Simple.Program.Hpc-    Distribution.Simple.Program.Internal-    Distribution.Simple.Program.Ld-    Distribution.Simple.Program.ResponseFile-    Distribution.Simple.Program.Run-    Distribution.Simple.Program.Script-    Distribution.Simple.Program.Strip-    Distribution.Simple.Program.Types-    Distribution.Simple.Register-    Distribution.Simple.Setup-    Distribution.Simple.SrcDist-    Distribution.Simple.Test-    Distribution.Simple.Test.ExeV10-    Distribution.Simple.Test.LibV09-    Distribution.Simple.Test.Log-    Distribution.Simple.UHC-    Distribution.Simple.UserHooks-    Distribution.Simple.Utils-    Distribution.SPDX-    Distribution.SPDX.License-    Distribution.SPDX.LicenseExceptionId-    Distribution.SPDX.LicenseExpression-    Distribution.SPDX.LicenseId-    Distribution.SPDX.LicenseListVersion-    Distribution.SPDX.LicenseReference-    Distribution.System-    Distribution.TestSuite-    Distribution.Text-    Distribution.Types.AbiDependency-    Distribution.Types.AbiHash-    Distribution.Types.AnnotatedId-    Distribution.Types.Benchmark-    Distribution.Types.BenchmarkInterface-    Distribution.Types.BenchmarkType-    Distribution.Types.BuildInfo-    Distribution.Types.BuildType-    Distribution.Types.Component-    Distribution.Types.ComponentId-    Distribution.Types.ComponentInclude-    Distribution.Types.ComponentLocalBuildInfo-    Distribution.Types.ComponentName-    Distribution.Types.ComponentRequestedSpec-    Distribution.Types.Condition-    Distribution.Types.CondTree-    Distribution.Types.Dependency-    Distribution.Types.DependencyMap-    Distribution.Types.Executable-    Distribution.Types.ExecutableScope-    Distribution.Types.ExeDependency-    Distribution.Types.ExposedModule-    Distribution.Types.ForeignLib-    Distribution.Types.ForeignLibOption-    Distribution.Types.ForeignLibType-    Distribution.Types.GenericPackageDescription-    Distribution.Types.GivenComponent-    Distribution.Types.HookedBuildInfo-    Distribution.Types.IncludeRenaming-    Distribution.Types.InstalledPackageInfo-    Distribution.Types.InstalledPackageInfo.FieldGrammar-    Distribution.Types.LegacyExeDependency-    Distribution.Types.Library-    Distribution.Types.LibraryName-    Distribution.Types.LibraryVisibility-    Distribution.Types.LocalBuildInfo-    Distribution.Types.Mixin-    Distribution.Types.Module-    Distribution.Types.ModuleReexport-    Distribution.Types.ModuleRenaming-    Distribution.Types.MungedPackageId-    Distribution.Types.MungedPackageName-    Distribution.Types.PackageDescription-    Distribution.Types.PackageId-    Distribution.Types.PackageName-    Distribution.Types.PackageVersionConstraint-    Distribution.Types.PkgconfigDependency-    Distribution.Types.PkgconfigName-    Distribution.Types.SetupBuildInfo-    Distribution.Types.SourceRepo-    Distribution.Types.TargetInfo-    Distribution.Types.TestSuite-    Distribution.Types.TestSuiteInterface-    Distribution.Types.TestType-    Distribution.Types.UnitId-    Distribution.Types.UnqualComponentName-    Distribution.Types.Version-    Distribution.Types.VersionInterval-    Distribution.Types.VersionRange-    Distribution.Utils.Generic-    Distribution.Utils.IOData-    Distribution.Utils.LogProgress-    Distribution.Utils.MapAccum-    Distribution.Utils.NubList-    Distribution.Utils.Progress-    Distribution.Utils.ShortText-    Distribution.Verbosity-    Distribution.Version-    Language.Haskell.Extension--  -- Parsec parser-related modules-  build-depends:-      mtl           >=2.1      && <2.3-    , parsec        >=3.1.13.0 && <3.2-    , text          >=1.2.3.0  && <1.3-    , transformers  >=0.3      && <0.4 || >=0.4.1.0 && <0.6--  -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity-  -- See also https://github.com/ekmett/transformers-compat/issues/35-  exposed-modules:-    Distribution.Compat.CharParsing-    Distribution.Compat.Parsing-    Distribution.FieldGrammar-    Distribution.FieldGrammar.Class-    Distribution.FieldGrammar.FieldDescrs-    Distribution.FieldGrammar.Parsec-    Distribution.FieldGrammar.Pretty-    Distribution.Fields-    Distribution.Fields.ConfVar-    Distribution.Fields.Field-    Distribution.Fields.Lexer-    Distribution.Fields.LexerMonad-    Distribution.Fields.Parser-    Distribution.Fields.ParseResult-    Distribution.Fields.Pretty-    Distribution.PackageDescription.FieldGrammar-    Distribution.PackageDescription.Parsec-    Distribution.PackageDescription.Quirks-    Distribution.Parsec-    Distribution.Parsec.Error-    Distribution.Parsec.FieldLineStream-    Distribution.Parsec.Newtypes-    Distribution.Parsec.Position-    Distribution.Parsec.Warning--  -- Lens functionality-  exposed-modules:-    Distribution.Compat.Lens-    Distribution.Types.Benchmark.Lens-    Distribution.Types.BuildInfo.Lens-    Distribution.Types.Executable.Lens-    Distribution.Types.ForeignLib.Lens-    Distribution.Types.GenericPackageDescription.Lens-    Distribution.Types.InstalledPackageInfo.Lens-    Distribution.Types.Lens-    Distribution.Types.Library.Lens-    Distribution.Types.PackageDescription.Lens-    Distribution.Types.PackageId.Lens-    Distribution.Types.SetupBuildInfo.Lens-    Distribution.Types.SourceRepo.Lens-    Distribution.Types.TestSuite.Lens--  other-modules:-    Distribution.Backpack.Id-    Distribution.Backpack.MixLink-    Distribution.Backpack.ModuleScope-    Distribution.Backpack.PreExistingComponent-    Distribution.Backpack.ReadyComponent-    Distribution.Backpack.UnifyM-    Distribution.Compat.CopyFile-    Distribution.Compat.GetShortPathName-    Distribution.Compat.MonadFail-    Distribution.Compat.Prelude-    Distribution.Compat.SnocList-    Distribution.GetOpt-    Distribution.Lex-    Distribution.Simple.GHC.EnvironmentParser-    Distribution.Simple.GHC.ImplInfo-    Distribution.Simple.GHC.Internal-    Distribution.Utils.Base62-    Distribution.Utils.String-    Distribution.Utils.UnionFind-    Paths_Cabal--  if flag(bundled-binary-generic)-    other-modules:-      Distribution.Compat.Binary.Class-      Distribution.Compat.Binary.Generic--  default-language: Haskell2010-  other-extensions:-    BangPatterns-    CPP-    DefaultSignatures-    DeriveDataTypeable-    DeriveFoldable-    DeriveFunctor-    DeriveGeneric-    DeriveTraversable-    ExistentialQuantification-    FlexibleContexts-    FlexibleInstances-    GeneralizedNewtypeDeriving-    ImplicitParams-    KindSignatures-    NondecreasingIndentation-    OverloadedStrings-    RankNTypes-    RecordWildCards-    ScopedTypeVariables-    StandaloneDeriving-    Trustworthy-    TypeFamilies-    TypeOperators-    TypeSynonymInstances-    UndecidableInstances--  if impl(ghc >=7.11)-    other-extensions: PatternSynonyms---- Small, fast running tests.-test-suite unit-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests-  other-modules:-    Test.Laws-    Test.QuickCheck.Utils-    UnitTests.Distribution.Compat.CreatePipe-    UnitTests.Distribution.Compat.Graph-    UnitTests.Distribution.Compat.Time-    UnitTests.Distribution.Simple.Glob-    UnitTests.Distribution.Simple.Program.Internal-    UnitTests.Distribution.Simple.Utils-    UnitTests.Distribution.SPDX-    UnitTests.Distribution.System-    UnitTests.Distribution.Types.GenericPackageDescription-    UnitTests.Distribution.Utils.Generic-    UnitTests.Distribution.Utils.NubList-    UnitTests.Distribution.Utils.ShortText-    UnitTests.Distribution.Version--  main-is:          UnitTests.hs-  build-depends:-      array-    , base-    , bytestring-    , Cabal-    , containers-    , directory-    , filepath-    , integer-logarithms  >=1.0.2   && <1.1-    , pretty-    , QuickCheck          >=2.11.3  && <2.12-    , tagged-    , tasty               >=1.1.0.3 && <1.2-    , tasty-hunit-    , tasty-quickcheck-    , temporary-    , text--  ghc-options:      -Wall-  default-language: Haskell2010--test-suite parser-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests-  main-is:          ParserTests.hs-  build-depends:-      base-    , base-compat       >=0.10.4  && <0.11-    , bytestring-    , Cabal-    , Diff              >=0.3.4   && <0.4-    , directory-    , filepath-    , tasty             >=1.1.0.3 && <1.2-    , tasty-golden      >=2.3.1.1 && <2.4-    , tasty-hunit-    , tasty-quickcheck--  ghc-options:      -Wall-  default-language: Haskell2010--  if impl(ghc >=7.8)-    build-depends: tree-diff >=0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--test-suite check-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests-  main-is:          CheckTests.hs-  build-depends:-      base-    , bytestring-    , Cabal-    , Diff          >=0.3.4   && <0.4-    , directory-    , filepath-    , tasty         >=1.1.0.3 && <1.2-    , tasty-golden  >=2.3.1.1 && <2.4--  ghc-options:      -Wall-  default-language: Haskell2010--test-suite custom-setup-tests-  type:             exitcode-stdio-1.0-  hs-source-dirs:   tests/custom-setup-  main-is:          CustomSetupTests.hs-  other-modules:-    CabalDoctestSetup-    IdrisSetup--  build-depends:-      base-    , Cabal-    , directory-    , filepath-    , process--  default-language: Haskell2010--test-suite hackage-tests-  type:               exitcode-stdio-1.0-  main-is:            HackageTests.hs--  -- TODO: need to get 01-index.tar on appveyor-  if os(windows)-    buildable: False--  hs-source-dirs:     tests-  build-depends:-      base-    , bytestring-    , Cabal-    , containers-    , deepseq-    , directory-    , filepath--  build-depends:-      base-compat           >=0.10.4   && <0.11-    , base-orphans          >=0.6      && <0.9-    , optparse-applicative  >=0.13.2.0 && <0.15-    , stm                   >=2.4.5.0  && <2.6-    , tar                   >=0.5.0.3  && <0.6--  if impl(ghc >=7.8)-    build-depends: tree-diff >=0.0.1 && <0.1-    other-modules:-      Instances.TreeDiff-      Instances.TreeDiff.Language-      Instances.TreeDiff.SPDX-      Instances.TreeDiff.Version--  ghc-options:        -Wall -rtsopts -threaded-  default-extensions: CPP-  default-language:   Haskell2010
− fixtures/cabal-fmt.cabal
@@ -1,16 +0,0 @@-cabal-version: 2.4-name: cabal-fmt-version: 0---- An example formatter-executable cabal-fmt-    default-language: Haskell2010-    hs-source-dirs: src -    main-is: CabalFmt.hs-    -- build depends will be in-    -- a nice tabular format-    build-depends: base >=4.11 && <4.13, pretty >=1.1.3.6 && <1.2, bytestring, Cabal ^>=2.5, containers ^>=0.5.11.0 || ^>=0.6.0.1-    -- extensions will be sorted-    other-extensions:-      DeriveFunctor FlexibleContexts ExistentialQuantification OverloadedStrings-      RankNTypes
− fixtures/cabal-fmt.format
@@ -1,26 +0,0 @@-cabal-version: 2.4-name:          cabal-fmt-version:       0---- An example formatter-executable cabal-fmt-  default-language: Haskell2010-  hs-source-dirs:   src-  main-is:          CabalFmt.hs--  -- build depends will be in-  -- a nice tabular format-  build-depends:-    , base        >=4.11      && <4.13-    , bytestring-    , Cabal       ^>=2.5-    , containers  ^>=0.5.11.0 || ^>=0.6.0.1-    , pretty      >=1.1.3.6   && <1.2--  -- extensions will be sorted-  other-extensions:-    DeriveFunctor-    ExistentialQuantification-    FlexibleContexts-    OverloadedStrings-    RankNTypes
− fixtures/fragment-empty.cabal
@@ -1,10 +0,0 @@-cabal-version:       2.4-name:                fragment-version:             1--library-  exposed-modules:     Example-  -- cabal-gild: fragment empty.fragment-  build-depends:       base >=4.3 && <4.13-  hs-source-dirs:      src-  default-language:    Haskell2010
− fixtures/fragment-empty.format
@@ -1,12 +0,0 @@--- Fragment empty.fragment is empty.-cabal-version: 2.4-name:          fragment-version:       1--library-  exposed-modules:  Example--  -- cabal-gild: fragment empty.fragment-  build-depends:    base >=4.3 && <4.13-  hs-source-dirs:   src-  default-language: Haskell2010
− fixtures/fragment-missing.cabal
@@ -1,10 +0,0 @@-cabal-version:       2.4-name:                fragment-version:             1--library-  exposed-modules:     Example-  -- cabal-gild: fragment missing.fragment-  build-depends:       base >=4.3 && <4.13-  hs-source-dirs:      src-  default-language:    Haskell2010
− fixtures/fragment-missing.format
@@ -1,12 +0,0 @@--- Fragment missing.fragment failed to read: "doesn't exist"-cabal-version: 2.4-name:          fragment-version:       1--library-  exposed-modules:  Example--  -- cabal-gild: fragment missing.fragment-  build-depends:    base >=4.3 && <4.13-  hs-source-dirs:   src-  default-language: Haskell2010
− fixtures/fragment-multiple.cabal
@@ -1,10 +0,0 @@-cabal-version:       2.4-name:                fragment-version:             1--library-  exposed-modules:     Example-  -- cabal-gild: fragment multiple.fragment-  build-depends:       base >=4.3 && <4.13-  hs-source-dirs:      src-  default-language:    Haskell2010
− fixtures/fragment-multiple.format
@@ -1,12 +0,0 @@--- Fragment multiple.fragment contains multiple fields or sections, using only the first.-cabal-version: 2.4-name:          fragment-version:       1--library-  exposed-modules:  Example--  -- cabal-gild: fragment multiple.fragment-  build-depends:    base-  hs-source-dirs:   src-  default-language: Haskell2010
− fixtures/fragment-section.cabal
@@ -1,12 +0,0 @@-cabal-version:       2.4-name:                fragment-version:             1---- cabal-gild: fragment common.fragment-common deps--library-  import: deps-  exposed-modules:     Example-  hs-source-dirs:      src-  default-language:    Haskell2010
− fixtures/fragment-section.format
@@ -1,18 +0,0 @@-cabal-version: 2.4-name:          fragment-version:       1---- cabal-gild: fragment common.fragment-common deps-  build-depends:-    , base-    , bytestring-    , containers--  ghc-options:   -Wall--library-  import:           deps-  exposed-modules:  Example-  hs-source-dirs:   src-  default-language: Haskell2010
− fixtures/fragment-wrong-field.cabal
@@ -1,10 +0,0 @@-cabal-version:       2.4-name:                fragment-version:             1--library-  exposed-modules:     Example-  -- cabal-gild: fragment tested-with.fragment-  build-depends:       base >=4.3 && <4.13-  hs-source-dirs:      src-  default-language:    Haskell2010
− fixtures/fragment-wrong-field.format
@@ -1,12 +0,0 @@--- Fragment tested-with.fragment contains field "tested-with", expecting field "build-depends".-cabal-version: 2.4-name:          fragment-version:       1--library-  exposed-modules:  Example--  -- cabal-gild: fragment tested-with.fragment-  build-depends:    base >=4.3 && <4.13-  hs-source-dirs:   src-  default-language: Haskell2010
− fixtures/fragment-wrong-type.cabal
@@ -1,10 +0,0 @@-cabal-version:       2.4-name:                fragment-version:             1--library-  exposed-modules:     Example-  -- cabal-gild: fragment common.fragment-  build-depends:       base >=4.3 && <4.13-  hs-source-dirs:      src-  default-language:    Haskell2010
− fixtures/fragment-wrong-type.format
@@ -1,12 +0,0 @@--- Fragment common.fragment contains a section "common deps", expecting field "build-depends".-cabal-version: 2.4-name:          fragment-version:       1--library-  exposed-modules:  Example--  -- cabal-gild: fragment common.fragment-  build-depends:    base >=4.3 && <4.13-  hs-source-dirs:   src-  default-language: Haskell2010
− fixtures/issue29.cabal
@@ -1,22 +0,0 @@-cabal-version:      3.0-name:               issue29-version:            0-description:-  First Paragraph-  -----  Second Paragraph--library-  default-language: Haskell2010-  hs-source-dirs:   src-  build-depends:-      base        >=4.3   && <4.18--  exposed-modules:-    Data.Bifunctor.Assoc-    Data.Bifunctor.Swap-
− fixtures/issue29.format
@@ -1,15 +0,0 @@-cabal-version: 3.0-name:          issue29-version:       0-description:-  First Paragraph--  Second Paragraph--library-  default-language: Haskell2010-  hs-source-dirs:   src-  build-depends:    base >=4.3 && <4.18-  exposed-modules:-    Data.Bifunctor.Assoc-    Data.Bifunctor.Swap
− fixtures/issue69.cabal
@@ -1,18 +0,0 @@-cabal-version:      1.12-name:               issue69-version:            0--library-  default-language: Haskell2010-  hs-source-dirs:   src-  build-depends:-      base        >=4.3   && <4.18-    , bifunctors  >=5.5.5 && <5.6-    , tagged      >=0.8.6 && <0.9-    , inline-r    >1.0.0.0--  exposed-modules:-    Data.Bifunctor.Assoc-    Data.Bifunctor.Swap--  other-extensions: TypeFamilies
− fixtures/issue69.format
@@ -1,18 +0,0 @@-cabal-version: 1.12-name:          issue69-version:       0--library-  default-language: Haskell2010-  hs-source-dirs:   src-  build-depends:-      base        >=4.3       && <4.18-    , bifunctors  >=5.5.5     && <5.6-    , inline-r    >=1.0.0.0.0-    , tagged      >=0.8.6     && <0.9--  exposed-modules:-    Data.Bifunctor.Assoc-    Data.Bifunctor.Swap--  other-extensions: TypeFamilies
− fixtures/simple-example.cabal
@@ -1,74 +0,0 @@-name:                simple-example-version:             1-synopsis:            Simple example of cabal-doctest demonstrating a library-                     with doctests-description:         A package skeleton, to demostrate the use of cabal-doctest-homepage:            https://github.com/phadej/cabal-doctest-license:             BSD3-license-file:        LICENSE-author:              Oleg Grenrus <oleg.grenrus@iki.fi>-maintainer:          Oleg Grenrus <oleg.grenrus@iki.fi>-copyright:           (c) 2017 Oleg Grenrus-category:            Example-build-type:          Custom-cabal-version:       1.12--tested-with:-  GHC==7.0.4,-  GHC==7.2.2,-  GHC==7.4.2,-  GHC==7.6.3,-  GHC==7.8.4,-  GHC==7.10.3,-  GHC==8.0.2,-  GHC==8.2.2,-  GHC==8.4.4,-  GHC==8.6.3--custom-setup-  setup-depends:-    base, Cabal, cabal-doctest >=1.0.6 && <1.1--library-  exposed-modules:     Example-  default-extensions:  ScopedTypeVariables RankNTypes-  build-depends:       base >=4.3 && <4.13-  hs-source-dirs:      src-  default-language:    Haskell2010--  if impl(ghcjs)-    cpp-options: -DFOOBAR--  if impl(ghc)-    -- cabal-gild: glob-files cbits/**/*.c-    c-sources:--  -- empty interval-  if impl(hugs)-    build-depends: unbuildable <0-    build-depends: unbuildable <0, unbuildable2 <0--  -- full interval-  build-depends: text <1 || >=1-  build-depends: containers <1 || >=1, pretty <1 || >=1--  -- only upper bound-  build-depends: foo <1-  build-depends: foo <2-  build-depends: abc <1, def <1, ghj <2--  -- build-tool-depends are formatted like build-depends-  build-tool-depends: happy:happy--  build-tool-depends: happy:happy >=1, alex:alex >=1--test-suite doctests-  type:                exitcode-stdio-1.0-  main-is:             doctests.hs--  -- cabal-gild: fragment build-depends.fragment-  build-depends:--  ghc-options:         -Wall -threaded-  hs-source-dirs:      tests-  default-language:    Haskell2010
− fixtures/simple-example.format
@@ -1,96 +0,0 @@-name:          simple-example-version:       1-synopsis:-  Simple example of cabal-doctest demonstrating a library-  with doctests--description:   A package skeleton, to demostrate the use of cabal-doctest-homepage:      https://github.com/phadej/cabal-doctest-license:       BSD3-license-file:  LICENSE-author:        Oleg Grenrus <oleg.grenrus@iki.fi>-maintainer:    Oleg Grenrus <oleg.grenrus@iki.fi>-copyright:     (c) 2017 Oleg Grenrus-category:      Example-build-type:    Custom-cabal-version: 1.12-tested-with:-  GHC ==7.0.4-   || ==7.2.2-   || ==7.4.2-   || ==7.6.3-   || ==7.8.4-   || ==7.10.3-   || ==8.0.2-   || ==8.2.2-   || ==8.4.4-   || ==8.6.3--custom-setup-  setup-depends:-      base-    , Cabal-    , cabal-doctest  >=1.0.6 && <1.1--library-  exposed-modules:    Example-  default-extensions:-    RankNTypes-    ScopedTypeVariables--  build-depends:      base >=4.3 && <4.13-  hs-source-dirs:     src-  default-language:   Haskell2010--  if impl(ghcjs)-    cpp-options: -DFOOBAR--  if impl(ghc)-    -- cabal-gild: glob-files cbits/**/*.c-    c-sources:-      cbits/source1.c-      cbits/source2.c-      cbits/sub/source3.c--  -- empty interval-  if impl(hugs)-    build-depends: unbuildable <0-    build-depends:-        unbuildable   <0-      , unbuildable2  <0--  -- full interval-  build-depends:      text-  build-depends:-      containers-    , pretty--  -- only upper bound-  build-depends:      foo <1-  build-depends:      foo <2-  build-depends:-      abc  <1-    , def  <1-    , ghj  <2--  -- build-tool-depends are formatted like build-depends-  build-tool-depends: happy:happy-  build-tool-depends:-      alex:alex    >=1-    , happy:happy  >=1--test-suite doctests-  type:             exitcode-stdio-1.0-  main-is:          doctests.hs--  -- cabal-gild: fragment build-depends.fragment-  build-depends:-      base-    , doctest           >=0.15 && <0.17-    , QuickCheck        >=2.12 && <2.13-    , simple-example-    , template-haskell--  ghc-options:      -Wall -threaded-  hs-source-dirs:   tests-  default-language: Haskell2010
− fixtures/tree-diff.cabal
@@ -1,190 +0,0 @@-cabal-version:      2.2-name:               tree-diff-version:            0.2.2-synopsis:           Diffing of (expression) trees.-category:           Data, Testing-description:-  Common diff algorithm works on list structures:-  .-  @-  diff :: Eq a => [a] -> [a] -> [Edit a]-  @-  .-  This package works on trees.-  .-  @-  treeDiff :: Eq a => Tree a -> Tree a -> Edit (EditTree a)-  @-  .-  This package also provides a way to diff arbitrary ADTs,-  using @Generics@-derivable helpers.-  .-  This package differs from <http://hackage.haskell.org/package/gdiff gdiff>,-  in a two ways: @tree-diff@ doesn't have patch function,-  and the "edit-script" is a tree itself, which is useful for pretty-printing.-  .-  @-  >>> prettyEditExpr $ ediff (Foo 42 [True, False] "old") (Foo 42 [False, False, True] "new")-  Foo-  \  {fooBool = [-True, +False, False, +True],-  \   fooInt = 42,-  \   fooString = -"old" +"new"}-  @--homepage:           https://github.com/phadej/tree-diff-bug-reports:        https://github.com/phadej/tree-diff/issues-license:            GPL-2.0-or-later-license-file:       LICENSE-author:             Oleg Grenrus <oleg.grenrus@iki.fi>-maintainer:         Oleg.Grenrus <oleg.grenrus@iki.fi>-copyright:          (c) 2017-2021 Oleg Grenrus-build-type:         Simple-extra-source-files:-  ChangeLog.md-  README.md--tested-with:-    GHC ==7.4.2-     || ==7.6.3-     || ==7.8.4-     || ==7.10.3-     || ==8.0.2-     || ==8.2.2-     || ==8.4.4-     || ==8.6.5-     || ==8.8.4-     || ==8.10.4-     || ==9.0.2-     || ==9.2.4-     || ==9.4.1-  , GHCJS ==8.4--extra-source-files:-  fixtures/exfoo.expr-  fixtures/MyInt1.expr-  fixtures/MyInt2.expr-  fixtures/MyInt3.expr-  fixtures/Positional.expr--source-repository head-  type:     git-  location: https://github.com/phadej/tree-diff.git--library-  exposed-modules:-    Data.TreeDiff-    Data.TreeDiff.Class-    Data.TreeDiff.Expr-    Data.TreeDiff.Golden-    Data.TreeDiff.List-    Data.TreeDiff.OMap-    Data.TreeDiff.Parser-    Data.TreeDiff.Pretty-    Data.TreeDiff.QuickCheck-    Data.TreeDiff.Tree--  -- GHC boot libraries-  build-depends:-    , base        >=4.5      && <4.18-    , bytestring  ^>=0.9.2.1 || ^>=0.10.0.2 || ^>=0.11.0.0-    , containers  ^>=0.4.2.1 || ^>=0.5.0.0 || ^>=0.6.0.1-    , deepseq     ^>=1.3.0.0 || ^>=1.4.0.0-    , parsec      ^>=3.1.13.0-    , pretty      ^>=1.1.1.0-    , text        ^>=1.2.3.0 || ^>=2.0-    , time        ^>=1.4      || ^>=1.5.0.1  || ^>=1.6.0.1  || ^>=1.8.0.2 || >=1.9.3 && <1.13--  build-depends:-    , aeson                 ^>=1.4.6.0 || ^>=1.5.6.0 || ^>=2.0.0.0 || ^>=2.1.0.0-    , ansi-terminal         >=0.10       && <0.12-    , ansi-wl-pprint        ^>=0.6.8.2-    , base-compat           ^>=0.10.5 || ^>=0.11.0 || ^>=0.12.0-    , bytestring-builder    ^>=0.10.8.2.0-    , hashable              ^>=1.2.7.0 || ^>=1.3.0.0 || ^>=1.4.0.1-    , parsers               ^>=0.12.10-    , primitive             ^>=0.7.1.0-    , QuickCheck            ^>=2.14.2-    , scientific            ^>=0.3.6.2-    , semialign             ^>=1.2.0.1-    , strict                ^>=0.4.0.1-    , tagged                ^>=0.8.6-    , these                 ^>=1.1.1.1-    , unordered-containers  ^>=0.2.8.0-    , uuid-types            ^>=1.0.3-    , vector                ^>=0.12.0.0 || ^>=0.13.0.0--  if impl(ghc <7.5)-    build-depends: ghc-prim--  if !impl(ghc >=8.0)-    build-depends: semigroups >=0.19.1 && <0.21--  if !impl(ghc >=7.8)-    build-depends: generic-deriving >=1.13.1 && <1.15--  if !impl(ghc >=7.10)-    build-depends:-      , nats          ^>=1.1.2-      , transformers  ^>=0.3.0.0 || ^>=0.4.2.0 || ^>=0.5.2.0-      , void          ^>=0.7.3--  other-extensions:-    CPP-    ConstraintKinds-    DefaultSignatures-    FlexibleContexts-    GADTs-    RankNTypes-    ScopedTypeVariables-    TypeOperators--  hs-source-dirs:   src-  default-language: Haskell2010--test-suite tree-diff-test-  default-language: Haskell2010-  type:             exitcode-stdio-1.0-  main-is:          Tests.hs-  hs-source-dirs:   tests src-diff-  ghc-options:      -Wall -threaded-  other-modules:    RefDiffBy--  -- dependencies from library-  build-depends:-    , ansi-terminal-    , ansi-wl-pprint-    , base-    , base-compat-    , parsec-    , primitive-    , QuickCheck-    , tagged-    , tree-diff--  if impl(ghc <7.5)-    build-depends: ghc-prim--  -- extra dependencies-  build-depends:-    , tasty             ^>=1.2 || ^>=1.3.1 || ^>=1.4.2-    , tasty-golden      ^>=2.3.1.1-    , tasty-quickcheck  ^>=0.10.1-    , trifecta          >=2       && <2.2--benchmark tree-diff-bench-  default-language: Haskell2010-  type:             exitcode-stdio-1.0-  main-is:          tree-diff-bench.hs-  hs-source-dirs:   bench-  ghc-options:      -Wall -threaded--  -- dependencies from library-  build-depends:-    , base-    , deepseq-    , tree-diff--  -- extra dependencies-  build-depends:-    , criterion  ^>=1.6.0.0-    , Diff       ^>=0.4.0
− fixtures/tree-diff.format
@@ -1,190 +0,0 @@-cabal-version:      2.2-name:               tree-diff-version:            0.2.2-synopsis:           Diffing of (expression) trees.-category:           Data, Testing-description:-  Common diff algorithm works on list structures:-  .-  @-  diff :: Eq a => [a] -> [a] -> [Edit a]-  @-  .-  This package works on trees.-  .-  @-  treeDiff :: Eq a => Tree a -> Tree a -> Edit (EditTree a)-  @-  .-  This package also provides a way to diff arbitrary ADTs,-  using @Generics@-derivable helpers.-  .-  This package differs from <http://hackage.haskell.org/package/gdiff gdiff>,-  in a two ways: @tree-diff@ doesn't have patch function,-  and the "edit-script" is a tree itself, which is useful for pretty-printing.-  .-  @-  >>> prettyEditExpr $ ediff (Foo 42 [True, False] "old") (Foo 42 [False, False, True] "new")-  Foo-  \  {fooBool = [-True, +False, False, +True],-  \   fooInt = 42,-  \   fooString = -"old" +"new"}-  @--homepage:           https://github.com/phadej/tree-diff-bug-reports:        https://github.com/phadej/tree-diff/issues-license:            GPL-2.0-or-later-license-file:       LICENSE-author:             Oleg Grenrus <oleg.grenrus@iki.fi>-maintainer:         Oleg.Grenrus <oleg.grenrus@iki.fi>-copyright:          (c) 2017-2021 Oleg Grenrus-build-type:         Simple-extra-source-files:-  ChangeLog.md-  README.md--tested-with:-    GHC ==7.4.2-     || ==7.6.3-     || ==7.8.4-     || ==7.10.3-     || ==8.0.2-     || ==8.2.2-     || ==8.4.4-     || ==8.6.5-     || ==8.8.4-     || ==8.10.4-     || ==9.0.2-     || ==9.2.4-     || ==9.4.1-  , GHCJS ==8.4--extra-source-files:-  fixtures/exfoo.expr-  fixtures/MyInt1.expr-  fixtures/MyInt2.expr-  fixtures/MyInt3.expr-  fixtures/Positional.expr--source-repository head-  type:     git-  location: https://github.com/phadej/tree-diff.git--library-  exposed-modules:-    Data.TreeDiff-    Data.TreeDiff.Class-    Data.TreeDiff.Expr-    Data.TreeDiff.Golden-    Data.TreeDiff.List-    Data.TreeDiff.OMap-    Data.TreeDiff.Parser-    Data.TreeDiff.Pretty-    Data.TreeDiff.QuickCheck-    Data.TreeDiff.Tree--  -- GHC boot libraries-  build-depends:-    , base        >=4.5       && <4.18-    , bytestring  ^>=0.9.2.1  || ^>=0.10.0.2 || ^>=0.11.0.0-    , containers  ^>=0.4.2.1  || ^>=0.5.0.0  || ^>=0.6.0.1-    , deepseq     ^>=1.3.0.0  || ^>=1.4.0.0-    , parsec      ^>=3.1.13.0-    , pretty      ^>=1.1.1.0-    , text        ^>=1.2.3.0  || ^>=2.0-    , time        ^>=1.4      || ^>=1.5.0.1  || ^>=1.6.0.1  || ^>=1.8.0.2 || ^>=1.9.3 || ^>=1.10 || ^>=1.11 || ^>=1.12--  build-depends:-    , aeson                 ^>=1.4.6.0    || ^>=1.5.6.0  || ^>=2.0.0.0 || ^>=2.1.0.0-    , ansi-terminal         >=0.10        && <0.12-    , ansi-wl-pprint        ^>=0.6.8.2-    , base-compat           ^>=0.10.5     || ^>=0.11.0   || ^>=0.12.0-    , bytestring-builder    ^>=0.10.8.2.0-    , hashable              ^>=1.2.7.0    || ^>=1.3.0.0  || ^>=1.4.0.1-    , parsers               ^>=0.12.10-    , primitive             ^>=0.7.1.0-    , QuickCheck            ^>=2.14.2-    , scientific            ^>=0.3.6.2-    , semialign             ^>=1.2.0.1-    , strict                ^>=0.4.0.1-    , tagged                ^>=0.8.6-    , these                 ^>=1.1.1.1-    , unordered-containers  ^>=0.2.8.0-    , uuid-types            ^>=1.0.3-    , vector                ^>=0.12.0.0   || ^>=0.13.0.0--  if impl(ghc <7.5)-    build-depends: ghc-prim--  if !impl(ghc >=8.0)-    build-depends: semigroups >=0.19.1 && <0.21--  if !impl(ghc >=7.8)-    build-depends: generic-deriving >=1.13.1 && <1.15--  if !impl(ghc >=7.10)-    build-depends:-      , nats          ^>=1.1.2-      , transformers  ^>=0.3.0.0 || ^>=0.4.2.0 || ^>=0.5.2.0-      , void          ^>=0.7.3--  other-extensions:-    CPP-    ConstraintKinds-    DefaultSignatures-    FlexibleContexts-    GADTs-    RankNTypes-    ScopedTypeVariables-    TypeOperators--  hs-source-dirs:   src-  default-language: Haskell2010--test-suite tree-diff-test-  default-language: Haskell2010-  type:             exitcode-stdio-1.0-  main-is:          Tests.hs-  hs-source-dirs:   tests src-diff-  ghc-options:      -Wall -threaded-  other-modules:    RefDiffBy--  -- dependencies from library-  build-depends:-    , ansi-terminal-    , ansi-wl-pprint-    , base-    , base-compat-    , parsec-    , primitive-    , QuickCheck-    , tagged-    , tree-diff--  if impl(ghc <7.5)-    build-depends: ghc-prim--  -- extra dependencies-  build-depends:-    , tasty             ^>=1.2     || ^>=1.3.1 || ^>=1.4.2-    , tasty-golden      ^>=2.3.1.1-    , tasty-quickcheck  ^>=0.10.1-    , trifecta          >=2        && <2.2--benchmark tree-diff-bench-  default-language: Haskell2010-  type:             exitcode-stdio-1.0-  main-is:          tree-diff-bench.hs-  hs-source-dirs:   bench-  ghc-options:      -Wall -threaded--  -- dependencies from library-  build-depends:-    , base-    , deepseq-    , tree-diff--  -- extra dependencies-  build-depends:-    , criterion  ^>=1.6.0.0-    , Diff       ^>=0.4.0
− fixtures/with-sublibs.cabal
@@ -1,36 +0,0 @@-cabal-version: 3.0-name:          with-sublibs-version:       1--library-  hs-source-dirs:     src-  default-language:   Haskell2010-  build-depends:-    test1,-    test1:sub,-    test2    >=1   &&  <3,-    test2:sub    >=2 &&   <3--  build-depends:-    test1--  build-depends:-    test2 >=1--  build-depends:-    test2:sub--  build-depends:-    test2:{sub}--  build-depends:-    test2:{sub1, sub2}--  build-depends:-    test2:sub   >=1      && <3--  build-depends:-    test2:{sub}   >=2   && <3--  build-depends:-    test2:{sub1, sub2}   >=3 &&   <4
− fixtures/with-sublibs.format
@@ -1,20 +0,0 @@-Up to date-cabal-version: 3.0-name:          with-sublibs-version:       1--library-  hs-source-dirs:   src-  default-language: Haskell2010-  build-depends:-    , test1:{test1, sub}-    , test2:{test2, sub}  >=2 && <3--  build-depends:    test1-  build-depends:    test2 >=1-  build-depends:    test2:sub-  build-depends:    test2:sub-  build-depends:    test2:{sub1, sub2}-  build-depends:    test2:sub >=1 && <3-  build-depends:    test2:sub >=2 && <3-  build-depends:    test2:{sub1, sub2} >=3 && <4
source/executable/Main.hs view
@@ -1,6 +1,4 @@--- |--- License: BSD-3-Clause--- Copyright: Oleg Grenrus-module Main (CabalGild.Main.main) where- import qualified CabalGild.Main++main :: IO ()+main = CabalGild.Main.defaultMain
− source/library/CabalGild.hs
@@ -1,210 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE OverloadedStrings #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus------ This is a demo application of how you can make Cabal-like--- file formatter.-module CabalGild (cabalGild) where--import CabalGild.Comments-import CabalGild.Fields-import CabalGild.Fields.BuildDepends-import CabalGild.Fields.Extensions-import CabalGild.Fields.Modules-import CabalGild.Fields.SourceFiles-import CabalGild.Fields.TestedWith-import CabalGild.FreeText-import CabalGild.Monad-import CabalGild.Options-import CabalGild.Parser-import CabalGild.Pragma-import CabalGild.Refactoring-import Control.Monad (join)-import qualified Control.Monad.Except as Except-import Control.Monad.Reader (asks, local)-import qualified Data.ByteString as BS-import qualified Data.Either as Either-import qualified Data.Foldable as Foldable-import Data.Function ((&))-import Data.Functor (($>))-import qualified Data.Maybe as Maybe-import qualified Distribution.CabalSpecVersion as C-import qualified Distribution.Compat.Lens as Lens-import qualified Distribution.FieldGrammar.Parsec as C-import qualified Distribution.Fields as C-import qualified Distribution.Fields.ConfVar as C-import qualified Distribution.Fields.Pretty as C-import qualified Distribution.PackageDescription.FieldGrammar as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified Distribution.Types.Condition as C-import qualified Distribution.Types.ConfVar as C-import qualified Distribution.Types.GenericPackageDescription as C-import qualified Distribution.Types.PackageDescription as C-import qualified Distribution.Types.VersionRange as C-import qualified Distribution.Utils.Generic as C-import qualified Text.PrettyPrint as PP------------------------------------------------------------------------------------ Main----------------------------------------------------------------------------------cabalGild :: (MonadCabalGild r m) => FilePath -> BS.ByteString -> m String-cabalGild filepath contents = do-  -- determine cabal-version-  cabalFile <- asks (optCabalFile . Lens.view options)-  csv <--    if cabalFile-      then do-        gpd <- parseGpd filepath contents-        return $-          C.specVersion $-            C.packageDescription gpd-      else return C.cabalSpecLatest--  inputFields' <- parseFields contents-  let (inputFieldsC, endComments) = attachComments contents inputFields'--  -- parse pragmas-  let parse :: (MonadCabalGild r f) => (a, Comments) -> f (a, Comments, [Pragma])-      parse (pos, c) = case parsePragmas c of (ws, ps) -> Foldable.traverse_ displayWarning ws $> (pos, c, ps)-  inputFieldsP' <- traverse (traverse parse) inputFieldsC-  endCommentsPragmas <- case parsePragmas endComments of-    (ws, ps) -> Foldable.traverse_ displayWarning ws $> ps--  -- apply refactorings-  let inputFieldsP :: [C.Field CommentsPragmas]-      inputFieldsP = map (fmap (fmap (snd . partitionPragmas))) inputFieldsP'--  inputFieldsR <- refactor inputFieldsP--  -- options morphisms-  let pragmas :: [GlobalPragma]-      pragmas =-        fst $-          partitionPragmas $-            foldMap (foldMap $ \(_, _, z) -> z) inputFieldsP' <> endCommentsPragmas--      optsEndo :: OptionsMorphism-      optsEndo = foldMap pragmaToOM pragmas--  local (Lens.over options $ \o -> runOptionsMorphism optsEndo $ o {optSpecVersion = csv}) $ do-    indentWith <- asks (optIndent . Lens.view options)-    let inputFields = inputFieldsR--    outputPrettyFields <--      genericFromParsecFields-        (\n (x, _, _) -> prettyFieldLines n x)-        prettySectionArgs-        inputFields--    return $-      C.showFields' (fromComments . (\(_, y, _) -> y)) (const id) indentWith outputPrettyFields-        & if nullComments endComments-          then id-          else (++ unlines ("" : [C.fromUTF8BS c | c <- unComments endComments]))--fromComments :: Comments -> C.CommentPosition-fromComments (Comments []) = C.NoComment-fromComments (Comments bss) = C.CommentBefore (map C.fromUTF8BS bss)--genericFromParsecFields ::-  (Applicative f) =>-  -- | transform field contents-  (C.FieldName -> ann -> [C.FieldLine ann] -> f PP.Doc) ->-  -- | transform section arguments-  (C.FieldName -> [C.SectionArg ann] -> f [PP.Doc]) ->-  [C.Field ann] ->-  f [C.PrettyField ann]-genericFromParsecFields f g = goMany-  where-    goMany = traverse go--    go (C.Field (C.Name ann name) fls) = C.PrettyField ann name <$> f name ann fls-    go (C.Section (C.Name ann name) secargs fs) = C.PrettySection ann name <$> g name secargs <*> goMany fs------------------------------------------------------------------------------------ Field prettyfying----------------------------------------------------------------------------------prettyFieldLines :: (MonadCabalGild r m) => C.FieldName -> C.Position -> [C.FieldLine CommentsPragmas] -> m PP.Doc-prettyFieldLines fn pos fls =-  Maybe.fromMaybe (C.prettyFieldLines fn fls) <$> knownField fn pos fls--knownField :: (MonadCabalGild r m) => C.FieldName -> C.Position -> [C.FieldLine CommentsPragmas] -> m (Maybe PP.Doc)-knownField fn pos fls = do-  opts <- asks (Lens.view options)-  let v = optSpecVersion opts-  let ft = fieldlinesToFreeText v pos (fmap (fmap $ \(x, _, _) -> x) fls)-  let ft' = showFreeText v ft--  return $ join $ fieldDescrLookup (fieldDescrs opts) fn (Just ft') $ \p pp ->-    case C.runParsecParser' v p "<input>" (C.fieldLinesToStream fls) of-      Right x -> Just (pp x)-      Left _ -> Nothing--fieldDescrs :: Options -> FieldDescrs () ()-fieldDescrs opts =-  buildDependsF opts-    <> buildToolDependsF opts-    <> setupDependsF opts-    <> defaultExtensionsF-    <> otherExtensionsF-    <> exposedModulesF-    <> otherModulesF-    <> testedWithF opts-    <> mconcat sourceFilesF-    <> coerceFieldDescrs C.packageDescriptionFieldGrammar-    <> coerceFieldDescrs C.buildInfoFieldGrammar------------------------------------------------------------------------------------ Sections----------------------------------------------------------------------------------prettySectionArgs :: (MonadCabalGild r m) => C.FieldName -> [C.SectionArg ann] -> m [PP.Doc]-prettySectionArgs x args =-  prettySectionArgs' x args `Except.catchError` \_ ->-    return (C.prettySectionArgs x args)--prettySectionArgs' :: (MonadCabalGild r m) => a -> [C.SectionArg ann] -> m [PP.Doc]-prettySectionArgs' _ args = do-  c <- runParseResult "<args>" "" $ C.parseConditionConfVar (map (C.zeroPos <$) args)-  return [ppCondition c]------------------------------------------------------------------------------------ PrettyPrint condition------------------------------------------------------------------------------------ This is originally from Cabal--ppCondition :: C.Condition C.ConfVar -> PP.Doc-ppCondition (C.Var x) = ppConfVar x-ppCondition (C.Lit b) = PP.text (show b)-ppCondition (C.CNot c) = PP.char '!' PP.<> ppCondition c-ppCondition (C.COr c1 c2) = PP.parens (PP.hsep [ppCondition c1, PP.text "||", ppCondition c2])-ppCondition (C.CAnd c1 c2) = PP.parens (PP.hsep [ppCondition c1, PP.text "&&", ppCondition c2])--ppConfVar :: C.ConfVar -> PP.Doc-ppConfVar (C.OS os) = PP.text "os" PP.<> PP.parens (C.pretty os)-ppConfVar (C.Arch arch) = PP.text "arch" PP.<> PP.parens (C.pretty arch)-ppConfVar (C.PackageFlag name) = PP.text "flag" PP.<> PP.parens (C.pretty name)-ppConfVar (C.Impl c v)-  | v == C.anyVersion = PP.text "impl" PP.<> PP.parens (C.pretty c)-  | otherwise = PP.text "impl" PP.<> PP.parens (C.pretty c PP.<+> C.pretty v)------------------------------------------------------------------------------------ Pragma to OM----------------------------------------------------------------------------------partitionPragmas :: [Pragma] -> ([GlobalPragma], [FieldPragma])-partitionPragmas = Either.partitionEithers . map p-  where-    p (GlobalPragma x) = Left x-    p (FieldPragma x) = Right x--pragmaToOM :: GlobalPragma -> OptionsMorphism-pragmaToOM (PragmaOptIndent n) = mkOptionsMorphism $ \opts -> opts {optIndent = n}-pragmaToOM (PragmaOptTabular b) = mkOptionsMorphism $ \opts -> opts {optTabular = b}
+ source/library/CabalGild/Action/AttachComments.hs view
@@ -0,0 +1,78 @@+module CabalGild.Action.AttachComments where++import qualified CabalGild.Type.Comment as Comment+import qualified Control.Monad.Trans.State as StateT+import qualified Distribution.Fields as Fields++run ::+  (Applicative m, Ord p) =>+  ([Fields.Field p], [Comment.Comment p]) ->+  m ([Fields.Field (p, [Comment.Comment p])], [Comment.Comment p])+run (fs, cs) = pure $ StateT.runState (fields fs) cs++fields ::+  (Ord p) =>+  [Fields.Field p] ->+  StateT.State [Comment.Comment p] [Fields.Field (p, [Comment.Comment p])]+fields = traverse field++field ::+  (Ord p) =>+  Fields.Field p ->+  StateT.State [Comment.Comment p] (Fields.Field (p, [Comment.Comment p]))+field f = case f of+  Fields.Field n fls ->+    Fields.Field+      <$> name n+      <*> traverse fieldLine fls+  Fields.Section n sas fs ->+    Fields.Section+      <$> name n+      <*> traverse sectionArg sas+      <*> traverse field fs++name ::+  (Ord p) =>+  Fields.Name p ->+  StateT.State [Comment.Comment p] (Fields.Name (p, [Comment.Comment p]))+name (Fields.Name p fn) =+  Fields.Name+    <$> toPosition p+    <*> pure fn++fieldLine ::+  (Ord p) =>+  Fields.FieldLine p ->+  StateT.State [Comment.Comment p] (Fields.FieldLine (p, [Comment.Comment p]))+fieldLine (Fields.FieldLine p bs) =+  Fields.FieldLine+    <$> toPosition p+    <*> pure bs++sectionArg ::+  (Ord p) =>+  Fields.SectionArg p ->+  StateT.State [Comment.Comment p] (Fields.SectionArg (p, [Comment.Comment p]))+sectionArg sa = case sa of+  Fields.SecArgName p bs ->+    Fields.SecArgName+      <$> toPosition p+      <*> pure bs+  Fields.SecArgStr p bs ->+    Fields.SecArgStr+      <$> toPosition p+      <*> pure bs+  Fields.SecArgOther p bs ->+    Fields.SecArgOther+      <$> toPosition p+      <*> pure bs++toPosition ::+  (Ord p) =>+  p ->+  StateT.State [Comment.Comment p] (p, [Comment.Comment p])+toPosition p = do+  cs <- StateT.get+  let (xs, ys) = span ((<= p) . Comment.annotation) cs+  StateT.put ys+  pure (p, xs)
+ source/library/CabalGild/Action/Discover.hs view
@@ -0,0 +1,65 @@+module CabalGild.Action.Discover where++import qualified CabalGild.Class.MonadWalk as MonadWalk+import qualified CabalGild.Extra.ModuleName as ModuleName+import qualified CabalGild.Extra.Name as Name+import qualified CabalGild.Extra.String as String+import qualified CabalGild.Type.Comment as Comment+import qualified CabalGild.Type.Pragma as Pragma+import qualified Control.Monad as Monad+import qualified Control.Monad.Catch as Exception+import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.Maybe as MaybeT+import qualified Data.Maybe as Maybe+import qualified Data.Set as Set+import qualified Distribution.Fields as Fields+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Utils.Generic as Utils+import qualified System.FilePath as FilePath++run ::+  (Exception.MonadThrow m, MonadWalk.MonadWalk m) =>+  FilePath ->+  ([Fields.Field [Comment.Comment a]], cs) ->+  m ([Fields.Field [Comment.Comment a]], cs)+run p (fs, cs) = (,) <$> fields p fs <*> pure cs++fields ::+  (Exception.MonadThrow m, MonadWalk.MonadWalk m) =>+  FilePath ->+  [Fields.Field [Comment.Comment a]] ->+  m [Fields.Field [Comment.Comment a]]+fields = mapM . field++field ::+  (Exception.MonadThrow m, MonadWalk.MonadWalk m) =>+  FilePath ->+  Fields.Field [Comment.Comment a] ->+  m (Fields.Field [Comment.Comment a])+field p f = case f of+  Fields.Field n _ -> fmap (Maybe.fromMaybe f) . MaybeT.runMaybeT $ do+    Monad.guard $ Set.member (Name.value n) relevantFieldNames+    c <- hoistMaybe . Utils.safeLast $ Name.annotation n+    Pragma.Discover x <- hoistMaybe . Parsec.simpleParsecBS $ Comment.value c+    let d = FilePath.combine (FilePath.takeDirectory p) x+    fs <- Trans.lift $ MonadWalk.walk d+    pure+      . Fields.Field n+      . fmap (ModuleName.toFieldLine [])+      . Maybe.mapMaybe (ModuleName.fromFilePath . FilePath.makeRelative d)+      $ Maybe.mapMaybe (FilePath.stripExtension "hs") fs+  Fields.Section n sas fs -> Fields.Section n sas <$> fields p fs++relevantFieldNames :: Set.Set Fields.FieldName+relevantFieldNames =+  Set.fromList $+    fmap+      String.toUtf8+      [ "exposed-modules",+        "other-modules"+      ]++-- This was added in transformers-0.6.0.0. See+-- <https://hub.darcs.net/ross/transformers/issue/49>.+hoistMaybe :: (Applicative f) => Maybe a -> MaybeT.MaybeT f a+hoistMaybe = MaybeT.MaybeT . pure
+ source/library/CabalGild/Action/ExtractComments.hs view
@@ -0,0 +1,40 @@+module CabalGild.Action.ExtractComments where++import qualified CabalGild.Type.Comment as Comment+import qualified Control.Applicative as Applicative+import qualified Control.Monad as Monad+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Latin1+import qualified Data.ByteString.Internal as ByteStringInternal+import qualified Data.Maybe as Maybe+import qualified Data.Word as Word+import qualified Distribution.Parsec.Position as Position++fromByteString :: ByteString.ByteString -> [Comment.Comment Position.Position]+fromByteString =+  Maybe.mapMaybe (uncurry fromLine)+    . zip [1 ..]+    . Latin1.lines++fromLine ::+  (Applicative.Alternative m, Monad m) =>+  Int ->+  ByteString.ByteString ->+  m (Comment.Comment Position.Position)+fromLine row line = do+  let (before, after) = breakComment line+  rest <-+    maybe Applicative.empty pure $+      ByteString.stripPrefix Comment.delimiter after+  Monad.guard $ ByteString.all isBlank before+  pure+    Comment.Comment+      { Comment.annotation = Position.Position row $ 1 + ByteString.length before,+        Comment.value = ByteString.dropWhileEnd isBlank rest+      }++breakComment :: ByteString.ByteString -> (ByteString.ByteString, ByteString.ByteString)+breakComment = ByteString.breakSubstring Comment.delimiter++isBlank :: Word.Word8 -> Bool+isBlank = ByteStringInternal.isSpaceWord8
+ source/library/CabalGild/Action/Format.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE TypeApplications #-}++module CabalGild.Action.Format where++import CabalGild.Compat.Cabal ()+import qualified CabalGild.Extra.FieldLine as FieldLine+import qualified CabalGild.Extra.Name as Name+import qualified CabalGild.Extra.String as String+import qualified CabalGild.Type.SomeParsecParser as SPP+import qualified Data.Functor.Identity as Identity+import qualified Data.Map as Map+import qualified Distribution.CabalSpecVersion as CabalSpecVersion+import qualified Distribution.FieldGrammar.Newtypes as Newtypes+import qualified Distribution.Fields as Fields+import qualified Distribution.ModuleName as ModuleName+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Pretty as Pretty+import qualified Distribution.Types.Dependency as Dependency+import qualified Distribution.Types.ExeDependency as ExeDependency+import qualified Distribution.Types.ForeignLibOption as ForeignLibOption+import qualified Distribution.Types.LegacyExeDependency as LegacyExeDependency+import qualified Distribution.Types.Mixin as Mixin+import qualified Distribution.Types.ModuleReexport as ModuleReexport+import qualified Distribution.Types.PkgconfigDependency as PkgconfigDependency+import qualified Language.Haskell.Extension as Extension+import qualified Text.PrettyPrint as PrettyPrint++run ::+  (Applicative m, Monoid cs) =>+  CabalSpecVersion.CabalSpecVersion ->+  ([Fields.Field cs], cs) ->+  m ([Fields.Field cs], cs)+run csv (fs, cs) = pure (fields csv fs, cs)++fields ::+  (Monoid cs) =>+  CabalSpecVersion.CabalSpecVersion ->+  [Fields.Field cs] ->+  [Fields.Field cs]+fields = fmap . field++field ::+  (Monoid cs) =>+  CabalSpecVersion.CabalSpecVersion ->+  Fields.Field cs ->+  Fields.Field cs+field csv f = case f of+  Fields.Field n fls -> case Map.lookup (Name.value n) parsers of+    Nothing -> f+    Just spp -> Fields.Field n $ fieldLines csv fls spp+  Fields.Section n sas fs -> Fields.Section n sas $ fields csv fs++fieldLines ::+  (Monoid cs) =>+  CabalSpecVersion.CabalSpecVersion ->+  [Fields.FieldLine cs] ->+  SPP.SomeParsecParser ->+  [Fields.FieldLine cs]+fieldLines csv fls (SPP.SomeParsecParser pp) =+  case Parsec.runParsecParser' csv pp "" $ FieldLine.toFieldLineStream fls of+    Left _ ->+      -- Parsing failed, so simply return the field lines as is.+      fls+    Right r ->+      fmap (\(c, l) -> Fields.FieldLine c $ String.toUtf8 l)+        . zip (foldMap FieldLine.annotation fls : repeat mempty)+        . lines+        . PrettyPrint.renderStyle style+        $ Pretty.prettyVersioned csv r++style :: PrettyPrint.Style+style =+  -- Everything should be on its own line.+  PrettyPrint.Style+    { PrettyPrint.mode = PrettyPrint.PageMode,+      PrettyPrint.lineLength = 0,+      PrettyPrint.ribbonsPerLine = 1+    }++parsers :: Map.Map Fields.FieldName SPP.SomeParsecParser+parsers =+  -- Perhaps these should use paths as keys rather than field names. That's+  -- because some fields are only supposed to occur within certain sections.+  -- For example, `exposed-modules` occurs in (at least) `library`. Fortunately+  -- field names are unique enough for this not to be a problem.+  let (=:) :: String -> SPP.SomeParsecParser -> (Fields.FieldName, SPP.SomeParsecParser)+      (=:) = (,) . String.toUtf8+   in Map.fromList+        [ "asm-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "asm-sources" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "autogen-includes" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "autogen-modules" =: SPP.set @Newtypes.VCat @(Newtypes.MQuoted ModuleName.ModuleName),+          "build-depends" =: SPP.set @Newtypes.CommaVCat @(Identity.Identity Dependency.Dependency),+          "build-tool-depends" =: SPP.set @Newtypes.CommaFSep @(Identity.Identity ExeDependency.ExeDependency),+          "build-tools" =: SPP.set @Newtypes.CommaFSep @(Identity.Identity LegacyExeDependency.LegacyExeDependency),+          "c-sources" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "cc-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "cmm-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "cmm-sources" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "code-generators" =: SPP.list @Newtypes.CommaFSep @Newtypes.Token,+          "cpp-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "cxx-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "cxx-sources" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "data-files" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "default-extensions" =: SPP.set @Newtypes.FSep @(Newtypes.MQuoted Extension.Extension),+          "exposed-modules" =: SPP.set @Newtypes.VCat @(Newtypes.MQuoted ModuleName.ModuleName),+          "extensions" =: SPP.set @Newtypes.FSep @(Newtypes.MQuoted Extension.Extension),+          "extra-bundled-libraries" =: SPP.set @Newtypes.VCat @Newtypes.Token,+          "extra-doc-files" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "extra-dynamic-library-flavours" =: SPP.set @Newtypes.VCat @Newtypes.Token,+          "extra-framework-dirs" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "extra-ghci-libraries" =: SPP.set @Newtypes.VCat @Newtypes.Token,+          "extra-lib-dirs-static" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "extra-lib-dirs" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "extra-libraries-static" =: SPP.set @Newtypes.VCat @Newtypes.Token,+          "extra-libraries" =: SPP.set @Newtypes.VCat @Newtypes.Token,+          "extra-library-flavours" =: SPP.set @Newtypes.VCat @Newtypes.Token,+          "extra-source-files" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "extra-tmp-files" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "frameworks" =: SPP.set @Newtypes.FSep @Newtypes.Token,+          "ghc-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "ghc-prof-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "ghc-shared-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "ghcjs-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "ghcjs-prof-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "ghcjs-shared-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "hs-source-dirs" =: SPP.list @Newtypes.FSep @Newtypes.FilePathNT,+          "hsc2hs-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "include-dirs" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "includes" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "install-includes" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "js-sources" =: SPP.set @Newtypes.VCat @Newtypes.FilePathNT,+          "ld-options" =: SPP.list @Newtypes.NoCommaFSep @Newtypes.Token',+          "license-files" =: SPP.set @Newtypes.FSep @Newtypes.FilePathNT,+          "mixins" =: SPP.set @Newtypes.CommaVCat @(Identity.Identity Mixin.Mixin),+          "options" =: SPP.set @Newtypes.FSep @(Identity.Identity ForeignLibOption.ForeignLibOption),+          "other-extensions" =: SPP.set @Newtypes.FSep @(Newtypes.MQuoted Extension.Extension),+          "other-languages" =: SPP.set @Newtypes.FSep @(Newtypes.MQuoted Extension.Language),+          "other-modules" =: SPP.set @Newtypes.VCat @(Newtypes.MQuoted ModuleName.ModuleName),+          "pkgconfig-depends" =: SPP.set @Newtypes.CommaFSep @(Identity.Identity PkgconfigDependency.PkgconfigDependency),+          "reexported-modules" =: SPP.set @Newtypes.CommaVCat @(Identity.Identity ModuleReexport.ModuleReexport),+          "setup-depends" =: SPP.set @Newtypes.CommaVCat @(Identity.Identity Dependency.Dependency),+          "signatures" =: SPP.set @Newtypes.VCat @(Newtypes.MQuoted ModuleName.ModuleName),+          "tested-with" =: SPP.set @Newtypes.FSep @Newtypes.TestedWith,+          "virtual-modules" =: SPP.set @Newtypes.VCat @(Newtypes.MQuoted ModuleName.ModuleName)+        ]
+ source/library/CabalGild/Action/GetCabalVersion.hs view
@@ -0,0 +1,34 @@+module CabalGild.Action.GetCabalVersion where++import qualified CabalGild.Extra.Either as Either+import qualified CabalGild.Extra.FieldLine as FieldLine+import qualified CabalGild.Extra.Name as Name+import qualified CabalGild.Extra.String as String+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Distribution.CabalSpecVersion as CabalSpecVersion+import qualified Distribution.FieldGrammar.Newtypes as Newtypes+import qualified Distribution.Fields as Fields+import qualified Distribution.Parsec as Parsec++fromFields :: [Fields.Field a] -> CabalSpecVersion.CabalSpecVersion+fromFields fs = Maybe.fromMaybe CabalSpecVersion.CabalSpecV1_0 $ do+  f <- List.find isCabalVersion fs+  fls <- getFieldLines f+  Newtypes.getSpecVersion <$> fromFieldLines fls++isCabalVersion :: Fields.Field a -> Bool+isCabalVersion f = case f of+  Fields.Field n _ -> Name.value n == String.toUtf8 "cabal-version"+  Fields.Section {} -> False++getFieldLines :: Fields.Field a -> Maybe [Fields.FieldLine a]+getFieldLines f = case f of+  Fields.Field _ fls -> Just fls+  Fields.Section {} -> Nothing++fromFieldLines :: [Fields.FieldLine a] -> Maybe Newtypes.SpecVersion+fromFieldLines =+  Either.hush+    . Parsec.runParsecParser Parsec.parsec ""+    . FieldLine.toFieldLineStream
+ source/library/CabalGild/Action/Reindent.hs view
@@ -0,0 +1,108 @@+module CabalGild.Action.Reindent where++import qualified CabalGild.Extra.Field as Field+import qualified CabalGild.Extra.FieldLine as FieldLine+import qualified CabalGild.Extra.List as List+import qualified CabalGild.Extra.Name as Name+import qualified CabalGild.Extra.String as String+import qualified CabalGild.Type.Comment as Comment+import qualified Data.ByteString as ByteString+import qualified Data.Set as Set+import qualified Distribution.CabalSpecVersion as CabalSpecVersion+import qualified Distribution.Fields as Fields+import qualified Distribution.Parsec.Position as Position++run ::+  (Applicative m) =>+  CabalSpecVersion.CabalSpecVersion ->+  ([Fields.Field (Position.Position, [Comment.Comment Position.Position])], cs) ->+  m ([Fields.Field (Position.Position, [Comment.Comment Position.Position])], cs)+run csv (fs, cs) = pure (fields csv fs, cs)++fields ::+  CabalSpecVersion.CabalSpecVersion ->+  [Fields.Field (Position.Position, [Comment.Comment Position.Position])] ->+  [Fields.Field (Position.Position, [Comment.Comment Position.Position])]+fields csv fs =+  -- Note that we want to do this after comments have been attached because we+  -- want comments to come as late as possible. In other words, we don't want a+  -- comment attached to a blank line.+  if csv >= CabalSpecVersion.CabalSpecV3_0+    then fmap field fs+    else fs++field ::+  Fields.Field (Position.Position, [Comment.Comment Position.Position]) ->+  Fields.Field (Position.Position, [Comment.Comment Position.Position])+field f = case f of+  Fields.Field n fls ->+    if Set.member (Name.value n) relevantFieldNames && List.compareLength fls 1 == GT+      then Fields.Field n $ fieldLines f fls+      else f+  Fields.Section n sas fs -> Fields.Section n sas $ fmap field fs++relevantFieldNames :: Set.Set Fields.FieldName+relevantFieldNames =+  Set.fromList $+    fmap+      String.toUtf8+      [ "description"+      ]++fieldLines ::+  Fields.Field (Position.Position, [Comment.Comment Position.Position]) ->+  [Fields.FieldLine (Position.Position, [Comment.Comment Position.Position])] ->+  [Fields.FieldLine (Position.Position, [Comment.Comment Position.Position])]+fieldLines f = fixRows . fixCols f++fixRows ::+  [Fields.FieldLine (Position.Position, [Comment.Comment Position.Position])] ->+  [Fields.FieldLine (Position.Position, [Comment.Comment Position.Position])]+fixRows fls = case fls of+  x : y : zs ->+    x+      : fmap rowToFieldLine [fieldLineToLastRow x + 1 .. fieldLineToFirstRow y - 1]+        <> fixRows (y : zs)+  _ -> fls++fixCols ::+  Fields.Field (Position.Position, [Comment.Comment Position.Position]) ->+  [Fields.FieldLine (Position.Position, [Comment.Comment Position.Position])] ->+  [Fields.FieldLine (Position.Position, [Comment.Comment Position.Position])]+fixCols f fls = case fls of+  [] -> fls+  x : xs ->+    let col = foldr (min . fieldLineToCol) (fieldLineToCol x) xs+     in if fieldToRow f == fieldLineToFirstRow x+          then x : fmap (reindent col) xs+          else fmap (reindent col) fls++fieldLineToCol :: Fields.FieldLine (Position.Position, cs) -> Int+fieldLineToCol = Position.positionCol . fst . FieldLine.annotation++fieldLineToFirstRow ::+  Fields.FieldLine (Position.Position, [Comment.Comment Position.Position]) ->+  Int+fieldLineToFirstRow =+  -- A field line's first row might belong to one of its comments.+  Position.positionRow+    . uncurry (foldr (min . Comment.annotation))+    . FieldLine.annotation++fieldLineToLastRow :: Fields.FieldLine (Position.Position, cs) -> Int+fieldLineToLastRow = Position.positionRow . fst . FieldLine.annotation++fieldToRow :: Fields.Field (Position.Position, cs) -> Int+fieldToRow = Position.positionRow . fst . Name.annotation . Field.name++reindent ::+  Int ->+  Fields.FieldLine (Position.Position, cs) ->+  Fields.FieldLine (Position.Position, cs)+reindent col (Fields.FieldLine (p, cs) b) =+  Fields.FieldLine (p, cs) $ ByteString.replicate (Position.positionCol p - col) 0x20 <> b++rowToFieldLine ::+  Int ->+  Fields.FieldLine (Position.Position, [c])+rowToFieldLine r = Fields.FieldLine (Position.Position r 1, []) ByteString.empty
+ source/library/CabalGild/Action/RemovePositions.hs view
@@ -0,0 +1,60 @@+module CabalGild.Action.RemovePositions where++import qualified CabalGild.Type.Comment as Comment+import qualified Distribution.Fields as Fields++run ::+  (Applicative m) =>+  ([Fields.Field (p, [Comment.Comment p])], [Comment.Comment p]) ->+  m ([Fields.Field [Comment.Comment ()]], [Comment.Comment ()])+run (fs, cs) = pure (fields fs, comments cs)++fields ::+  [Fields.Field (p, [Comment.Comment p])] ->+  [Fields.Field [Comment.Comment ()]]+fields = fmap field++field ::+  Fields.Field (p, [Comment.Comment p]) ->+  Fields.Field [Comment.Comment ()]+field f = case f of+  Fields.Field n fls -> Fields.Field (name n) $ fieldLines fls+  Fields.Section n sas fs -> Fields.Section (name n) (sectionArgs sas) $ fields fs++name ::+  Fields.Name (p, [Comment.Comment p]) ->+  Fields.Name [Comment.Comment ()]+name (Fields.Name (_, cs) x) = Fields.Name (comments cs) x++fieldLines ::+  [Fields.FieldLine (p, [Comment.Comment p])] ->+  [Fields.FieldLine [Comment.Comment ()]]+fieldLines = fmap fieldLine++fieldLine ::+  Fields.FieldLine (p, [Comment.Comment p]) ->+  Fields.FieldLine [Comment.Comment ()]+fieldLine (Fields.FieldLine (_, cs) x) = Fields.FieldLine (comments cs) x++sectionArgs ::+  [Fields.SectionArg (p, [Comment.Comment p])] ->+  [Fields.SectionArg [Comment.Comment ()]]+sectionArgs = fmap sectionArg++sectionArg ::+  Fields.SectionArg (p, [Comment.Comment p]) ->+  Fields.SectionArg [Comment.Comment ()]+sectionArg sa = case sa of+  Fields.SecArgName (_, cs) x -> Fields.SecArgName (comments cs) x+  Fields.SecArgStr (_, cs) x -> Fields.SecArgStr (comments cs) x+  Fields.SecArgOther (_, cs) x -> Fields.SecArgOther (comments cs) x++comments ::+  [Comment.Comment p] ->+  [Comment.Comment ()]+comments = fmap comment++comment ::+  Comment.Comment p ->+  Comment.Comment ()+comment c = c {Comment.annotation = ()}
+ source/library/CabalGild/Action/Render.hs view
@@ -0,0 +1,119 @@+module CabalGild.Action.Render where++import qualified CabalGild.Extra.FieldLine as FieldLine+import qualified CabalGild.Extra.Name as Name+import qualified CabalGild.Extra.SectionArg as SectionArg+import qualified CabalGild.Type.Block as Block+import qualified CabalGild.Type.Chunk as Chunk+import qualified CabalGild.Type.Comment as Comment+import qualified CabalGild.Type.Line as Line+import qualified Data.ByteString as ByteString+import qualified Distribution.Compat.Lens as Lens+import qualified Distribution.Fields as Fields++run ::+  (Applicative m) =>+  ([Fields.Field [Comment.Comment a]], [Comment.Comment a]) ->+  m ByteString.ByteString+run = pure . uncurry toByteString++toByteString ::+  [Fields.Field [Comment.Comment a]] ->+  [Comment.Comment a] ->+  ByteString.ByteString+toByteString fs cs =+  let i = 0 :: Int+   in Block.toByteString+        . Lens.set Block.lineBeforeLens False+        . Lens.set Block.lineAfterLens True+        $ fields i fs <> comments i cs++fields :: Int -> [Fields.Field [Comment.Comment a]] -> Block.Block+fields = foldMap . field++field :: Int -> Fields.Field [Comment.Comment a] -> Block.Block+field i f = case f of+  Fields.Field n fls -> case fls of+    [fl]+      | null $ FieldLine.annotation fl ->+          -- If the field only has one line and no comments, then it can be+          -- rendered all on one line.+          comments i (Name.annotation n)+            <> ( Block.fromLine+                   . Lens.over Line.chunkLens (mappend $ name n <> Chunk.colon)+                   $ fieldLine i fl+               )+    _ ->+      Lens.set Block.lineAfterLens True $+        comments i (Name.annotation n)+          <> Block.fromLine+            Line.Line+              { Line.indent = i,+                Line.chunk = name n <> Chunk.colon+              }+          <> fieldLines (i + 1) fls+  Fields.Section n sas fs ->+    Lens.set Block.lineBeforeLens True+      . Lens.set Block.lineAfterLens True+      $ comments i (Name.annotation n)+        -- Section arguments should never have comments in practice. This is+        -- here simply to ensure that they aren't lost.+        <> comments i (concatMap SectionArg.annotation sas)+        <> Block.fromLine+          Line.Line+            { Line.indent = i,+              Line.chunk = Lens.set Chunk.spaceAfterLens True (name n) <> sectionArgs sas+            }+        <> Lens.set Block.lineBeforeLens False (fields (i + 1) fs)++name :: Fields.Name a -> Chunk.Chunk+name = Chunk.fromByteString . Name.value++fieldLines :: Int -> [Fields.FieldLine [Comment.Comment a]] -> Block.Block+fieldLines = foldMap . fieldLineC++fieldLineC :: Int -> Fields.FieldLine [Comment.Comment a] -> Block.Block+fieldLineC i fl =+  comments i (FieldLine.annotation fl)+    <> Block.fromLine (fieldLine i fl)++fieldLine :: Int -> Fields.FieldLine a -> Line.Line+fieldLine i =+  Line.Line i+    . Lens.set Chunk.spaceBeforeLens True+    . Chunk.fromByteString+    . FieldLine.value++sectionArgs :: [Fields.SectionArg a] -> Chunk.Chunk+sectionArgs = Lens.set Chunk.spaceBeforeLens True . foldMap sectionArg++sectionArg :: Fields.SectionArg a -> Chunk.Chunk+sectionArg sa = case sa of+  Fields.SecArgName _ bs ->+    Lens.set Chunk.spaceBeforeLens True+      . Lens.set Chunk.spaceAfterLens True+      $ Chunk.fromByteString bs+  Fields.SecArgStr _ bs ->+    Lens.set Chunk.spaceBeforeLens True+      . Lens.set Chunk.spaceAfterLens True+      . Chunk.fromByteString+      . flip ByteString.snoc 0x22+      $ ByteString.cons 0x22 bs+  Fields.SecArgOther _ bs ->+    let b =+          bs /= ByteString.singleton 0x21 -- !+            && bs /= ByteString.singleton 0x28 -- (+            && bs /= ByteString.singleton 0x29 -- )+     in Lens.set Chunk.spaceBeforeLens b+          . Lens.set Chunk.spaceAfterLens b+          $ Chunk.fromByteString bs++comments :: Int -> [Comment.Comment a] -> Block.Block+comments i cs = mempty {Block.lines = fmap (comment i) cs}++comment :: Int -> Comment.Comment a -> Line.Line+comment i =+  Line.Line i+    . Chunk.fromByteString+    . mappend Comment.delimiter+    . Comment.value
+ source/library/CabalGild/Class/MonadLog.hs view
@@ -0,0 +1,10 @@+module CabalGild.Class.MonadLog where++class (Monad m) => MonadLog m where+  log :: String -> m ()++instance MonadLog IO where+  log = putStr++logLn :: (MonadLog m) => String -> m ()+logLn = CabalGild.Class.MonadLog.log . (<> "\n")
+ source/library/CabalGild/Class/MonadRead.hs view
@@ -0,0 +1,9 @@+module CabalGild.Class.MonadRead where++import qualified Data.ByteString as ByteString++class (Monad m) => MonadRead m where+  read :: Maybe FilePath -> m ByteString.ByteString++instance MonadRead IO where+  read = maybe ByteString.getContents ByteString.readFile
+ source/library/CabalGild/Class/MonadWalk.hs view
@@ -0,0 +1,21 @@+module CabalGild.Class.MonadWalk where++import qualified System.Directory as Directory+import qualified System.FilePath as FilePath++class (Monad m) => MonadWalk m where+  walk :: FilePath -> m [FilePath]++instance MonadWalk IO where+  walk = listDirectoryRecursively++listDirectoryRecursively :: FilePath -> IO [FilePath]+listDirectoryRecursively d = do+  es <- Directory.listDirectory d+  let f e = do+        let p = FilePath.combine d e+        b <- Directory.doesDirectoryExist p+        if b+          then listDirectoryRecursively p+          else pure [p]+  concat <$> mapM f es
+ source/library/CabalGild/Class/MonadWrite.hs view
@@ -0,0 +1,9 @@+module CabalGild.Class.MonadWrite where++import qualified Data.ByteString as ByteString++class (Monad m) => MonadWrite m where+  write :: Maybe FilePath -> ByteString.ByteString -> m ()++instance MonadWrite IO where+  write = maybe ByteString.putStr ByteString.writeFile
− source/library/CabalGild/Comments.hs
@@ -1,160 +0,0 @@-{-# LANGUAGE DerivingStrategies #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Comments where--import qualified Data.ByteString as BS-import qualified Data.ByteString.Char8 as BS8-import qualified Data.Map.Strict as Map-import qualified Data.Maybe as Maybe-import qualified Distribution.Fields as C-import qualified Distribution.Fields.Field as C-import qualified Distribution.Parsec as C------------------------------------------------------------------------------------ Comments wrapper----------------------------------------------------------------------------------newtype Comments = Comments [BS.ByteString]-  deriving stock (Show)-  deriving newtype (Semigroup, Monoid)--unComments :: Comments -> [BS.ByteString]-unComments (Comments cs) = cs--nullComments :: Comments -> Bool-nullComments (Comments cs) = null cs------------------------------------------------------------------------------------ Attach comments------------------------------------------------------------------------------------ | Returns a 'C.Field' forest with comments attached.------ * Comments are attached to the field after it.--- * A glitch: comments "inside" the field are attached to the field after it.--- * End-of-file comments are returned separately.-attachComments ::-  -- | source with comments-  BS.ByteString ->-  -- | parsed source fields-  [C.Field C.Position] ->-  ([C.Field (C.Position, Comments)], Comments)-attachComments input inputFields =-  (overAnn attach attach' inputFields, endComments)-  where-    inputFieldsU :: [(FieldPath, C.Field C.Position)]-    inputFieldsU = fieldUniverseN inputFields--    comments :: [(Int, Comments)]-    comments = extractComments input--    comments' :: Map.Map FieldPath Comments-    comments' =-      Map.fromListWith-        (flip (<>))-        [ (path, cs)-          | (l, cs) <- comments,-            path <- Maybe.maybeToList (findPath C.fieldAnn l inputFieldsU)-        ]--    endComments :: Comments-    endComments =-      mconcat-        [ cs-          | (l, cs) <- comments,-            Maybe.isNothing (findPath C.fieldAnn l inputFieldsU)-        ]--    attach :: FieldPath -> C.Position -> (C.Position, Comments)-    attach fp pos = (pos, Maybe.fromMaybe mempty (Map.lookup fp comments'))--    attach' :: C.Position -> (C.Position, Comments)-    attach' pos = (pos, mempty)--overAnn :: forall a b. (FieldPath -> a -> b) -> (a -> b) -> [C.Field a] -> [C.Field b]-overAnn f h = go' id-  where-    go :: (FieldPath -> FieldPath) -> Int -> C.Field a -> C.Field b-    go g i (C.Field (C.Name a name) fls) =-      C.Field (C.Name b name) (h <$$> fls)-      where-        b = f (g (Nth i End)) a-    go g i (C.Section (C.Name a name) args fls) =-      C.Section (C.Name b name) (h <$$> args) (go' (g . Nth i) fls)-      where-        b = f (g (Nth i End)) a--    go' :: (FieldPath -> FieldPath) -> [C.Field a] -> [C.Field b]-    go' g = zipWith (go g) [0 ..]--    (<$$>) :: (Functor f1, Functor f2) => (x -> y) -> f1 (f2 x) -> f1 (f2 y)-    x <$$> y = (x <$>) <$> y------------------------------------------------------------------------------------ Find comments in the input----------------------------------------------------------------------------------extractComments :: BS.ByteString -> [(Int, Comments)]-extractComments = go . zip [1 ..] . map (BS.dropWhileEnd isCR . BS.dropWhile isSpace8) . BS8.lines-  where-    go :: [(Int, BS.ByteString)] -> [(Int, Comments)]-    go [] = []-    go ((n, bs) : rest)-      | isComment bs = case span ((isComment .|| BS.null) . snd) rest of-          (h, t) -> (n, Comments $ bs : map snd h) : go t-      | otherwise = go rest--    (.||) :: (t -> Bool) -> (t -> Bool) -> t -> Bool-    (f .|| g) x = f x || g x--    isSpace8 :: (Eq a, Num a) => a -> Bool-    isSpace8 w = w == 9 || w == 32--    isCR :: (Eq a, Num a) => a -> Bool-    isCR = (==) 13--    isComment :: BS.ByteString -> Bool-    isComment = BS.isPrefixOf "--"------------------------------------------------------------------------------------ FieldPath------------------------------------------------------------------------------------ | Paths input paths. Essentially a list of offsets. Own type ofr safety.-data FieldPath-  = End-  | Nth Int FieldPath -- nth field-  deriving (Eq, Ord, Show)--fieldUniverseN :: [C.Field ann] -> [(FieldPath, C.Field ann)]-fieldUniverseN = concat . zipWith g [0 ..]-  where-    g :: Int -> C.Field ann -> [(FieldPath, C.Field ann)]-    g n f' = [(Nth n p, f'') | (p, f'') <- fieldUniverse f']--fieldUniverse :: C.Field ann -> [(FieldPath, C.Field ann)]-fieldUniverse f@(C.Section _ _ fs) = (End, f) : concat (zipWith g [0 ..] fs)-  where-    g :: Int -> C.Field ann -> [(FieldPath, C.Field ann)]-    g n f' = [(Nth n p, f'') | (p, f'') <- fieldUniverse f']-fieldUniverse f@(C.Field _ _) = [(End, f)]---- note: fieldUniverse* should produce 'FieldPath's in increasing order--- that helps-findPath :: (a -> C.Position) -> Int -> [(FieldPath, a)] -> Maybe FieldPath-findPath _ _ [] = Nothing-findPath f l [(p, x)]-  | C.Position k _ <- f x =-      if l < k then Just p else Nothing-findPath f l ((_, x) : rest@((p, x') : _))-  | C.Position k _ <- f x,-    C.Position k' _ <- f x' =-      if k < l && l < k'-        then Just p-        else findPath f l rest
+ source/library/CabalGild/Compat/Cabal.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module CabalGild.Compat.Cabal where++#if !MIN_VERSION_Cabal_syntax(3, 10, 1)+import qualified Distribution.Types.Dependency as Dependency+import qualified Distribution.Types.VersionRange.Internal as VersionRange+import qualified Distribution.Types.ExeDependency as ExeDependency+import qualified Distribution.Types.LegacyExeDependency as LegacyExeDependency+import qualified Distribution.Types.ForeignLibOption as ForeignLibOption+import qualified Distribution.Types.PkgconfigDependency as PkgconfigDependency+import qualified Distribution.Types.PkgconfigVersionRange as PkgconfigVersionRange+import qualified Distribution.Types.ModuleReexport as ModuleReexport+import qualified Language.Haskell.Extension as Extension++deriving instance Ord Dependency.Dependency+deriving instance Ord ForeignLibOption.ForeignLibOption+deriving instance Ord ExeDependency.ExeDependency+deriving instance Ord Extension.Language+deriving instance Ord LegacyExeDependency.LegacyExeDependency+deriving instance Ord ModuleReexport.ModuleReexport+deriving instance Ord PkgconfigDependency.PkgconfigDependency+deriving instance Ord PkgconfigVersionRange.PkgconfigVersionRange+deriving instance Ord VersionRange.VersionRange+#endif
− source/library/CabalGild/Error.hs
@@ -1,128 +0,0 @@--- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Error (Error (..), renderError) where--import Control.Exception (Exception)-import qualified Data.ByteString as BS-import qualified Data.ByteString.Char8 as BS8-import Data.List.NonEmpty (NonEmpty)-import qualified Distribution.Parsec as C-import qualified Distribution.Types.Version as C-import qualified Distribution.Utils.Generic as C (fromUTF8BS)-import System.FilePath (normalise)-import System.IO (hPutStr, hPutStrLn, stderr)-import Text.Parsec.Error (ParseError)--data Error-  = SomeError String-  | CabalParseError FilePath BS.ByteString (NonEmpty C.PError) (Maybe C.Version) [C.PWarning]-  | PanicCannotParseInput ParseError-  | WarningError String-  deriving (Show)--instance Exception Error--renderError :: Error -> IO ()-renderError (SomeError err) = hPutStrLn stderr $ "error: " ++ err-renderError (PanicCannotParseInput err) = hPutStrLn stderr $ "panic! " ++ show err-renderError (CabalParseError filepath contents errors _ warnings) =-  hPutStr stderr $ renderParseError filepath contents errors warnings-renderError (WarningError w) = hPutStrLn stderr $ "error (-Werror): " ++ w------------------------------------------------------------------------------------ Rendering of Cabal parser error------------------------------------------------------------------------------------ | Render parse error highlighting the part of the input file.-renderParseError ::-  FilePath ->-  BS.ByteString ->-  NonEmpty C.PError ->-  [C.PWarning] ->-  String-renderParseError filepath contents errors warnings =-  unlines $-    [ "Errors encountered when parsing cabal file " <> filepath <> ":"-    ]-      ++ renderedErrors-      ++ renderedWarnings-  where-    filepath' = normalise filepath--    -- lines of the input file. 'lines' is taken, so they are called rows-    -- contents, line number, whether it's empty line-    rows :: [(String, Int, Bool)]-    rows = zipWith f (BS8.lines contents) [1 ..]-      where-        f :: BS8.ByteString -> b -> (String, b, Bool)-        f bs i = let s = C.fromUTF8BS bs in (s, i, isEmptyOrComment s)--    rowsZipper = listToZipper rows--    isEmptyOrComment :: String -> Bool-    isEmptyOrComment s = case dropWhile (== ' ') s of-      "" -> True -- empty-      ('-' : '-' : _) -> True -- comment-      _ -> False--    renderedErrors = concatMap renderError' errors-    renderedWarnings = concatMap renderWarning warnings--    renderError' :: C.PError -> [String]-    renderError' (C.PError pos@(C.Position row col) msg)-      -- if position is 0:0, then it doesn't make sense to show input-      -- looks like, Parsec errors have line-feed in them-      | pos == C.zeroPos = msgs-      | otherwise = msgs ++ formatInput row col-      where-        msgs = ["", filepath' ++ ":" ++ C.showPos pos ++ ": error:", trimLF msg, ""]--    renderWarning :: C.PWarning -> [String]-    renderWarning (C.PWarning _ pos@(C.Position row col) msg)-      | pos == C.zeroPos = msgs-      | otherwise = msgs ++ formatInput row col-      where-        msgs = ["", filepath' ++ ":" ++ C.showPos pos ++ ": warning:", trimLF msg, ""]--    -- sometimes there are (especially trailing) newlines.-    trimLF :: String -> String-    trimLF = dropWhile (== '\n') . reverse . dropWhile (== '\n') . reverse--    -- format line: prepend the given line number-    formatInput :: Int -> Int -> [String]-    formatInput row col = case advance (row - 1) rowsZipper of-      Zipper xs ys -> before ++ after-        where-          before = case span (\(_, _, b) -> b) xs of-            (_, []) -> []-            (zs, z : _) -> map formatInputLine $ z : reverse zs--          after = case ys of-            [] -> []-            (z : _zs) ->-              [ formatInputLine z, -- error line-                "      | " ++ replicate (col - 1) ' ' ++ "^" -- pointer: ^-              ]-    -- do we need rows after?-    -- ++ map formatInputLine (take 1 zs)           -- one row after--    formatInputLine :: (String, Int, Bool) -> String-    formatInputLine (str, row, _) = leftPadShow row ++ " | " ++ str--    -- hopefully we don't need to work with over 99999 lines .cabal files-    -- at that point small glitches in error messages are hopefully fine.-    leftPadShow :: Int -> String-    leftPadShow n = let s = show n in replicate (5 - length s) ' ' ++ s--data Zipper a = Zipper [a] [a]--listToZipper :: [a] -> Zipper a-listToZipper = Zipper []--advance :: Int -> Zipper a -> Zipper a-advance n z@(Zipper xs ys)-  | n <= 0 = z-  | otherwise = case ys of-      [] -> z-      (y : ys') -> advance (n - 1) $ Zipper (y : xs) ys'
+ source/library/CabalGild/Exception/CheckFailure.hs view
@@ -0,0 +1,10 @@+module CabalGild.Exception.CheckFailure where++import qualified Control.Monad.Catch as Exception++data CheckFailure+  = CheckFailure+  deriving (Eq, Show)++instance Exception.Exception CheckFailure where+  displayException = const "input is not formatted"
+ source/library/CabalGild/Exception/InvalidMode.hs view
@@ -0,0 +1,13 @@+module CabalGild.Exception.InvalidMode where++import qualified Control.Monad.Catch as Exception++newtype InvalidMode+  = InvalidMode String+  deriving (Eq, Show)++instance Exception.Exception InvalidMode where+  displayException (InvalidMode s) = "invalid mode: " <> s++fromString :: String -> InvalidMode+fromString = InvalidMode
+ source/library/CabalGild/Exception/InvalidOption.hs view
@@ -0,0 +1,15 @@+module CabalGild.Exception.InvalidOption where++import qualified Control.Monad.Catch as Exception+import qualified Data.Char as Char+import qualified Data.List as List++newtype InvalidOption+  = InvalidOption String+  deriving (Eq, Show)++instance Exception.Exception InvalidOption where+  displayException (InvalidOption s) = "invalid option: " <> s++fromString :: String -> InvalidOption+fromString = InvalidOption . List.dropWhileEnd Char.isSpace
+ source/library/CabalGild/Exception/ParseError.hs view
@@ -0,0 +1,15 @@+module CabalGild.Exception.ParseError where++import qualified Control.Monad.Catch as Exception+import qualified Text.Parsec.Error as Parsec++-- This type only exists to add an `Exception` instance to the `ParseError`+-- type. That instance was added in parsec-3.17.0.0. See:+-- <https://github.com/haskell/parsec/pull/178>.+newtype ParseError = ParseError+  { unwrap :: Parsec.ParseError+  }+  deriving (Eq, Show)++instance Exception.Exception ParseError where+  displayException = mappend "parse error: " . show . unwrap
+ source/library/CabalGild/Exception/UnexpectedArgument.hs view
@@ -0,0 +1,13 @@+module CabalGild.Exception.UnexpectedArgument where++import qualified Control.Monad.Catch as Exception++newtype UnexpectedArgument+  = UnexpectedArgument String+  deriving (Eq, Show)++instance Exception.Exception UnexpectedArgument where+  displayException (UnexpectedArgument s) = "unexpected argument: " <> s++fromString :: String -> UnexpectedArgument+fromString = UnexpectedArgument
+ source/library/CabalGild/Exception/UnknownOption.hs view
@@ -0,0 +1,13 @@+module CabalGild.Exception.UnknownOption where++import qualified Control.Monad.Catch as Exception++newtype UnknownOption+  = UnknownOption String+  deriving (Eq, Show)++instance Exception.Exception UnknownOption where+  displayException (UnknownOption s) = "unknown option: " <> s++fromString :: String -> UnknownOption+fromString = UnknownOption
+ source/library/CabalGild/Extra/Either.hs view
@@ -0,0 +1,4 @@+module CabalGild.Extra.Either where++hush :: Either x a -> Maybe a+hush = either (const Nothing) Just
+ source/library/CabalGild/Extra/Field.hs view
@@ -0,0 +1,8 @@+module CabalGild.Extra.Field where++import qualified Distribution.Fields as Fields++name :: Fields.Field a -> Fields.Name a+name f = case f of+  Fields.Field n _ -> n+  Fields.Section n _ _ -> n
+ source/library/CabalGild/Extra/FieldLine.hs view
@@ -0,0 +1,17 @@+module CabalGild.Extra.FieldLine where++import qualified Data.ByteString as ByteString+import qualified Distribution.Fields as Fields+import qualified Distribution.Parsec.FieldLineStream as FieldLineStream++annotation :: Fields.FieldLine a -> a+annotation (Fields.FieldLine x _) = x++value :: Fields.FieldLine a -> ByteString.ByteString+value (Fields.FieldLine _ x) = x++toFieldLineStream :: [Fields.FieldLine a] -> FieldLineStream.FieldLineStream+toFieldLineStream fls = case fls of+  [] -> FieldLineStream.FLSLast ByteString.empty+  [x] -> FieldLineStream.FLSLast $ value x+  x : xs -> FieldLineStream.FLSCons (value x) $ toFieldLineStream xs
+ source/library/CabalGild/Extra/List.hs view
@@ -0,0 +1,9 @@+module CabalGild.Extra.List where++compareLength :: [a] -> Int -> Ordering+compareLength xs n =+  if n < 0+    then GT+    else case xs of+      [] -> compare 0 n+      _ : ys -> compareLength ys $ n - 1
+ source/library/CabalGild/Extra/ModuleName.hs view
@@ -0,0 +1,15 @@+module CabalGild.Extra.ModuleName where++import qualified CabalGild.Extra.String as String+import qualified Data.List as List+import qualified Distribution.Fields as Fields+import qualified Distribution.ModuleName as ModuleName+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Pretty as Pretty+import qualified System.FilePath as FilePath++fromFilePath :: FilePath -> Maybe ModuleName.ModuleName+fromFilePath = Parsec.simpleParsec . List.intercalate "." . FilePath.splitDirectories++toFieldLine :: a -> ModuleName.ModuleName -> Fields.FieldLine a+toFieldLine a = Fields.FieldLine a . String.toUtf8 . Pretty.prettyShow
+ source/library/CabalGild/Extra/Name.hs view
@@ -0,0 +1,9 @@+module CabalGild.Extra.Name where++import qualified Distribution.Fields as Fields++annotation :: Fields.Name a -> a+annotation (Fields.Name x _) = x++value :: Fields.Name a -> Fields.FieldName+value (Fields.Name _ x) = x
+ source/library/CabalGild/Extra/SectionArg.hs view
@@ -0,0 +1,9 @@+module CabalGild.Extra.SectionArg where++import qualified Distribution.Fields as Fields++annotation :: Fields.SectionArg a -> a+annotation sa = case sa of+  Fields.SecArgName x _ -> x+  Fields.SecArgStr x _ -> x+  Fields.SecArgOther x _ -> x
+ source/library/CabalGild/Extra/String.hs view
@@ -0,0 +1,8 @@+module CabalGild.Extra.String where++import qualified Data.ByteString as ByteString+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Encoding++toUtf8 :: String -> ByteString.ByteString+toUtf8 = Encoding.encodeUtf8 . Text.pack
− source/library/CabalGild/Fields.hs
@@ -1,117 +0,0 @@-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE UndecidableInstances #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Fields-  ( FieldDescrs,-    fieldDescrLookup,-    coerceFieldDescrs,-    singletonF,-  )-where--import qualified Data.Map.Strict as Map-import qualified Distribution.Compat.Newtype as Newtype-import qualified Distribution.FieldGrammar as C-import qualified Distribution.Fields.Field as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified Text.PrettyPrint as PP------------------------------------------------------------------------------------ FieldDescr variant------------------------------------------------------------------------------------ strict pair-data SP where-  FreeText :: SP-  SP ::-    !(f -> PP.Doc) ->-    !(forall m. (C.CabalParsing m) => m f) ->-    SP---- | Lookup both pretty-printer and value parser.------ As the value of the field is unknown, we have to work with it universally.-fieldDescrLookup ::-  (C.CabalParsing m) =>-  FieldDescrs s a ->-  C.FieldName ->-  r -> -- field is freetext-  (forall f. m f -> (f -> PP.Doc) -> r) ->-  Maybe r-fieldDescrLookup (F m) fn ft kont = kont' <$> Map.lookup fn m-  where-    kont' (SP a b) = kont b a-    kont' FreeText = ft---- | A collection field parsers and pretty-printers.-newtype FieldDescrs s a = F {runF :: Map.Map C.FieldName SP}-  deriving (Functor)--coerceFieldDescrs :: FieldDescrs s a -> FieldDescrs () ()-coerceFieldDescrs (F a) = F a--instance Semigroup (FieldDescrs s a) where-  F a <> F b = F (a <> b)--instance Monoid (FieldDescrs s a) where-  mempty = F Map.empty-  mappend = (<>)--instance Applicative (FieldDescrs s) where-  pure _ = F mempty-  f <*> x = F (mappend (runF f) (runF x))--singletonF ::-  C.FieldName ->-  (f -> PP.Doc) ->-  (forall m. (C.CabalParsing m) => m f) ->-  FieldDescrs s a-singletonF fn f g = F $ Map.singleton fn (SP f g)--instance C.FieldGrammar PrettyParsec FieldDescrs where-  blurFieldGrammar _ (F m) = F m--  booleanFieldDef fn _ _def = singletonF fn f C.parsec-    where-      f :: Bool -> PP.Doc-      f s = PP.text (show s)--  uniqueFieldAla fn _pack _ =-    singletonF fn (C.pretty . Newtype.pack' _pack) (Newtype.unpack' _pack <$> C.parsec)--  optionalFieldAla fn _pack _ =-    singletonF fn (C.pretty . Newtype.pack' _pack) (Newtype.unpack' _pack <$> C.parsec)--  optionalFieldDefAla fn _pack _ def =-    singletonF fn f (Newtype.unpack' _pack <$> C.parsec)-    where-      f s-        | s == def = PP.empty-        | otherwise = C.pretty (Newtype.pack' _pack s)--  monoidalFieldAla fn _pack _ =-    singletonF fn (C.pretty . Newtype.pack' _pack) (Newtype.unpack' _pack <$> C.parsec)--  freeTextField fn _ = F $ Map.singleton fn FreeText-  freeTextFieldDef fn _ = F $ Map.singleton fn FreeText-  freeTextFieldDefST fn _ = F $ Map.singleton fn FreeText--  prefixedFields _fnPfx _l = F mempty-  knownField _ = pure ()-  deprecatedSince _ _ x = x-  removedIn _ _ x = x-  availableSince _ _ = id-  hiddenField _ = F mempty--class (C.Pretty a, C.Parsec a) => PrettyParsec a--instance (C.Pretty a, C.Parsec a) => PrettyParsec a
− source/library/CabalGild/Fields/BuildDepends.hs
@@ -1,162 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# OPTIONS_GHC -Wno-deprecations #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Fields.BuildDepends-  ( buildDependsF,-    setupDependsF,-    buildToolDependsF,-  )-where--import CabalGild.Fields-import CabalGild.Options-import Control.Arrow ((&&&))-import qualified Data.Char as Char-import Data.List (dropWhileEnd)-import qualified Data.List as List-import qualified Distribution.CabalSpecVersion as C-import qualified Distribution.Compat.Newtype as Newtype-import qualified Distribution.FieldGrammar as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified Distribution.Types.Dependency as C-import qualified Distribution.Types.DependencyMap as C-import qualified Distribution.Types.ExeDependency as C-import qualified Distribution.Types.VersionRange as C-import qualified Text.PrettyPrint as PP-import VersionInterval (ConversionProblem (..), normaliseVersionRange)--setupDependsF :: Options -> FieldDescrs () ()-setupDependsF opts = singletonF "setup-depends" (pretty opts) parse--buildDependsF :: Options -> FieldDescrs () ()-buildDependsF opts = singletonF "build-depends" (pretty opts) parse--buildToolDependsF :: Options -> FieldDescrs () ()-buildToolDependsF opts = singletonF "build-tool-depends" (prettyExe opts) parseExe--parse :: (C.CabalParsing m) => m [C.Dependency]-parse = Newtype.unpack' (C.alaList C.CommaVCat) <$> C.parsec--parseExe :: (C.CabalParsing m) => m [C.ExeDependency]-parseExe = Newtype.unpack' (C.alaList C.CommaVCat) <$> C.parsec--normaliseVersionRange' :: C.VersionRange -> C.VersionRange-normaliseVersionRange' vr = either fromConversionProblem id (normaliseVersionRange vr)-  where-    fromConversionProblem :: ConversionProblem -> C.VersionRange-    fromConversionProblem IntervalsEmpty = C.noVersion-    fromConversionProblem OtherConversionProblem = vr--pretty :: Options -> [C.Dependency] -> PP.Doc-pretty opts deps = case deps of-  [] -> PP.empty-  [dep] -> PP.text (prettyDepNoVersion dep) PP.<+> prettyVR vr'-    where-      vr' = normaliseVersionRange' (C.depVerRange dep)--      prettyVR vr-        | vr == C.anyVersion = PP.empty-        | vr == C.noVersion = PP.text "<0"-        | otherwise = C.pretty vr-  _ -> prettyMany opts deps'-    where-      deps' :: [(String, C.VersionRange)]-      deps' =-        List.sortOn (map Char.toLower . fst) $-          map (prettyDepNoVersion &&& C.depVerRange) $-            C.fromDepMap . C.toDepMap $ -- this combines duplicate packages-              deps-  where-    prettyDepNoVersion :: C.Dependency -> String-    prettyDepNoVersion (C.Dependency pkg _ libs) =-      C.prettyShow (C.Dependency pkg C.anyVersion libs)--prettyExe :: Options -> [C.ExeDependency] -> PP.Doc-prettyExe opts deps = case deps of-  [] -> PP.empty-  [dep] -> PP.text (exeDepExeName dep) PP.<+> prettyVR vr'-    where-      vr' = normaliseVersionRange' (exeDepVerRange dep)--      prettyVR vr-        | vr == C.anyVersion = PP.empty-        | vr == C.noVersion = PP.text "<0"-        | otherwise = C.pretty vr-  _ -> prettyMany opts deps'-    where-      deps' :: [(String, C.VersionRange)]-      deps' =-        List.sortOn (map Char.toLower . fst) $-          map-            (exeDepExeName &&& exeDepVerRange)-            -- C.fromDepMap . C.toDepMap -- this combines duplicate packages-            deps--exeDepExeName :: C.ExeDependency -> String-exeDepExeName (C.ExeDependency name exe _) =-  C.prettyShow name ++ ":" ++ C.prettyShow exe--exeDepVerRange :: C.ExeDependency -> C.VersionRange-exeDepVerRange (C.ExeDependency _ _ vr) = vr--prettyMany :: Options -> [(String, C.VersionRange)] -> PP.Doc-prettyMany Options {optSpecVersion = v, optTabular = tab} deps' =-  PP.vcat $-    map PP.text $-      tbl $-        zipWith cols (True : repeat False) deps'-  where-    cols :: Bool -> (String, C.VersionRange) -> [String]-    cols isFirst (name, vr)-      | full vr' = [comma, name]-      | otherwise = comma : name : "" : words (C.prettyShow vr')-      where-        vr' = normaliseVersionRange' vr--        comma :: String-        comma-          | isFirst, v < C.CabalSpecV2_2 = " "-          | otherwise = ","--    full :: C.VersionRange -> Bool-    full vr = vr == C.anyVersion--    tbl :: [[String]] -> [String]-    tbl = if tab then table else map (concatSpaces . unwords)---- returns rows.-table :: [[String]] -> [String]-table cells = map strip rows-  where-    cols :: Int-    rowWidths :: [Int]-    rows :: [String]--    (cols, rowWidths, rows) = foldr go (0, repeat 0, []) cells--    go :: [String] -> (Int, [Int], [String]) -> (Int, [Int], [String])-    go xs (c, w, yss) =-      ( max c (length xs),-        zipWith max w (map length xs ++ repeat 0),-        unwords (take cols (zipWith fill xs rowWidths))-          : yss-      )--    fill :: String -> Int -> String-    fill s n = s ++ replicate (n - length s) ' '--strip :: String -> String-strip = dropWhileEnd (' ' ==)--concatSpaces :: String -> String-concatSpaces [] = []-concatSpaces (' ' : s) = ' ' : concatSpaces s-concatSpaces (c0 : s0) = c0 : go s0-  where-    go (' ' : ' ' : s) = go (' ' : s)-    go (c : s) = c : go s-    go [] = []
− source/library/CabalGild/Fields/Extensions.hs
@@ -1,31 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Fields.Extensions-  ( otherExtensionsF,-    defaultExtensionsF,-  )-where--import CabalGild.Fields-import qualified Data.List as List-import qualified Distribution.Compat.Newtype as Newtype-import qualified Distribution.FieldGrammar as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified Language.Haskell.Extension as C-import qualified Text.PrettyPrint as PP--otherExtensionsF :: FieldDescrs () ()-otherExtensionsF = singletonF "other-extensions" pretty parse--defaultExtensionsF :: FieldDescrs () ()-defaultExtensionsF = singletonF "default-extensions" pretty parse--parse :: (C.CabalParsing m) => m [C.Extension]-parse = Newtype.unpack' (C.alaList' C.FSep C.MQuoted) <$> C.parsec--pretty :: [C.Extension] -> PP.Doc-pretty = PP.vcat . map C.pretty . List.sortOn C.prettyShow
− source/library/CabalGild/Fields/Modules.hs
@@ -1,55 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Fields.Modules-  ( otherModulesF,-    exposedModulesF,-  )-where--import CabalGild.Fields-import qualified Data.Char as Char-import qualified Data.Function as Function-import qualified Data.List as List-import qualified Distribution.Compat.Newtype as Newtype-import qualified Distribution.FieldGrammar as C-import qualified Distribution.ModuleName as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified Text.PrettyPrint as PP--exposedModulesF :: FieldDescrs () ()-exposedModulesF = singletonF "exposed-modules" pretty parse--otherModulesF :: FieldDescrs () ()-otherModulesF = singletonF "other-modules" pretty parse--parse :: (C.CabalParsing m) => m [C.ModuleName]-parse = Newtype.unpack' (C.alaList' C.VCat C.MQuoted) <$> C.parsec--pretty :: [C.ModuleName] -> PP.Doc-pretty =-  PP.vcat-    . map C.pretty-    . List.nub-    . List.sortBy (cmp `Function.on` map strToLower . C.components)-  where-    cmp :: (Ord a) => [a] -> [a] -> Ordering-    cmp a b = case dropCommonPrefix a b of-      ([], []) -> EQ-      ([], _ : _) -> LT-      (_ : _, []) -> GT-      (a', b') -> compare a' b'--strToLower :: String -> String-strToLower = map Char.toLower--dropCommonPrefix :: (Eq a) => [a] -> [a] -> ([a], [a])-dropCommonPrefix [] [] = ([], [])-dropCommonPrefix [] ys = ([], ys)-dropCommonPrefix xs [] = (xs, [])-dropCommonPrefix xs@(x : xs') ys@(y : ys')-  | x == y = dropCommonPrefix xs' ys'-  | otherwise = (xs, ys)
− source/library/CabalGild/Fields/SourceFiles.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Fields.SourceFiles-  ( sourceFilesF,-    fileFields,-  )-where---- Make sure we explicitly use Posix's splitDirectories--- when parsing glob syntax since only `/` is valid, and not '\\'--import CabalGild.Fields-import qualified Data.Char as Char-import qualified Data.Function as Function-import qualified Data.List as List-import qualified Distribution.Compat.Newtype as Newtype-import qualified Distribution.FieldGrammar as C-import qualified Distribution.Fields as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified System.FilePath.Posix as Posix (splitDirectories)-import qualified Text.PrettyPrint as PP--sourceFilesF :: [FieldDescrs () ()]-sourceFilesF =-  [ singletonF f pretty parse-    | f <- fileFields-  ]--fileFields :: [C.FieldName]-fileFields =-  [ "extra-source-files",-    "extra-doc-files",-    "data-files",-    "license-files",-    "asm-sources",-    "cmm-sources",-    "c-sources",-    "cxx-sources",-    "js-sources",-    "includes",-    "install-includes"-  ]--parse :: (C.CabalParsing m) => m [FilePath]-parse = Newtype.unpack' (C.alaList' C.VCat C.FilePathNT) <$> C.parsec--pretty :: [FilePath] -> PP.Doc-pretty =-  PP.vcat-    . map C.showFilePath-    . List.nub-    . List.sortBy (cmp `Function.on` map strToLower . Posix.splitDirectories)-  where-    cmp :: (Ord a) => [a] -> [a] -> Ordering-    cmp a b = case dropCommonPrefix a b of-      ([], []) -> EQ-      ([], _ : _) -> LT-      (_ : _, []) -> GT-      (a', b') -> compare a' b'--strToLower :: String -> String-strToLower = map Char.toLower--dropCommonPrefix :: (Eq a) => [a] -> [a] -> ([a], [a])-dropCommonPrefix [] [] = ([], [])-dropCommonPrefix [] ys = ([], ys)-dropCommonPrefix xs [] = (xs, [])-dropCommonPrefix xs@(x : xs') ys@(y : ys')-  | x == y = dropCommonPrefix xs' ys'-  | otherwise = (xs, ys)
− source/library/CabalGild/Fields/TestedWith.hs
@@ -1,71 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE OverloadedStrings #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Fields.TestedWith-  ( testedWithF,-  )-where--import CabalGild.Fields-import CabalGild.Options-import qualified Data.Map.Strict as Map-import qualified Data.Set as Set-import qualified Distribution.CabalSpecVersion as C-import qualified Distribution.Compat.Newtype as Newtype-import qualified Distribution.Compiler as C-import qualified Distribution.FieldGrammar as C-import qualified Distribution.Parsec as C-import qualified Distribution.Pretty as C-import qualified Distribution.Version as C-import qualified Text.PrettyPrint as PP--testedWithF :: Options -> FieldDescrs () ()-testedWithF Options {optSpecVersion = ver} = singletonF "tested-with" pretty parse-  where-    parse :: (C.CabalParsing m) => m [(C.CompilerFlavor, C.VersionRange)]-    parse = Newtype.unpack' (C.alaList' C.FSep C.TestedWith) <$> C.parsec--    pretty :: [(C.CompilerFlavor, C.VersionRange)] -> PP.Doc-    pretty tw0 =-      leadingComma-        ver-        [ prettyC c PP.<+> prettyVr vr-          | (c, vr) <- Map.toList tw1-        ]-      where-        tw1 :: Map.Map C.CompilerFlavor C.VersionRange-        tw1 = Map.fromListWith C.unionVersionRanges tw0--        -- TODO: Cabal 3.0 formatting!-        prettyVr vr = case isVersionSet vr of-          Just vs -> PP.sep $ mapTail (\doc -> PP.nest (-3) $ PP.text "||" PP.<+> doc) [C.pretty (C.thisVersion v) | v <- Set.toList vs]-          Nothing -> C.pretty vr--        prettyC C.GHC = PP.text "GHC"-        prettyC C.GHCJS = PP.text "GHCJS"-        prettyC c = C.pretty c--leadingComma :: C.CabalSpecVersion -> [PP.Doc] -> PP.Doc-leadingComma _ [] = PP.empty-leadingComma _ [x] = x-leadingComma v xs = PP.vcat $ zipWith comma (True : repeat False) xs-  where-    comma :: Bool -> PP.Doc -> PP.Doc-    comma isFirst doc-      | isFirst, v < C.CabalSpecV3_0 = PP.char ' ' PP.<+> doc-      | otherwise = PP.char ',' PP.<+> doc--isVersionSet :: C.VersionRange -> Maybe (Set.Set C.Version)-isVersionSet vr = go Set.empty (C.asVersionIntervals vr)-  where-    go !acc [] = Just acc-    go acc (C.VersionInterval (C.LowerBound v C.InclusiveBound) (C.UpperBound u C.InclusiveBound) : vis)-      | v == u = go (Set.insert v acc) vis-    go _ _ = Nothing--mapTail :: (a -> a) -> [a] -> [a]-mapTail _ [] = []-mapTail f (x : xs) = x : map f xs
− source/library/CabalGild/FreeText.hs
@@ -1,86 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module CabalGild.FreeText-  ( fieldlinesToFreeText,-    showFreeText,-  )-where--import Data.List (foldl')-import qualified Data.List as List-import qualified Distribution.CabalSpecVersion as C-import qualified Distribution.Fields.Field as C-import qualified Distribution.Parsec as C-import qualified Distribution.Parsec.Position as C-import qualified Distribution.Pretty as C-import Distribution.Utils.Generic (fromUTF8BS)-import qualified Distribution.Utils.String as C (trim)-import qualified Text.PrettyPrint as PP--showFreeText :: C.CabalSpecVersion -> String -> PP.Doc-showFreeText v-  | v >= C.CabalSpecV3_0 =-      C.showFreeTextV3-  | otherwise =-      C.showFreeText---- This should perfectly be exported from Cabal-syntax-fieldlinesToFreeText :: C.CabalSpecVersion -> C.Position -> [C.FieldLine C.Position] -> String-fieldlinesToFreeText v-  | v >= C.CabalSpecV3_0 =-      fieldlinesToFreeText3-  | otherwise =-      const fieldlinesToFreeText2--fieldlinesToFreeText2 :: [C.FieldLine C.Position] -> String-fieldlinesToFreeText2 [C.FieldLine _ "."] = "."-fieldlinesToFreeText2 fls = List.intercalate "\n" (map go fls)-  where-    go :: C.FieldLine ann -> String-    go (C.FieldLine _ bs)-      | s == "." = ""-      | otherwise = s-      where-        s = C.trim (fromUTF8BS bs)--fieldlinesToFreeText3 :: C.Position -> [C.FieldLine C.Position] -> String-fieldlinesToFreeText3 _ [] = ""-fieldlinesToFreeText3 _ [C.FieldLine _ bs] = fromUTF8BS bs-fieldlinesToFreeText3 pos (C.FieldLine pos1 bs1 : fls2@(C.FieldLine pos2 _ : _))-  -- if first line is on the same line with field name:-  -- the indentation level is either-  -- 1. the indentation of left most line in rest fields-  -- 2. the indentation of the first line-  -- whichever is leftmost-  | C.positionRow pos == C.positionRow pos1 =-      concat $-        fromUTF8BS bs1-          : mealy (mk mcol1) pos1 fls2-  -- otherwise, also indent the first line-  | otherwise =-      concat $-        replicate (C.positionCol pos1 - mcol2) ' '-          : fromUTF8BS bs1-          : mealy (mk mcol2) pos1 fls2-  where-    mcol1 = foldl' (\a b -> min a $ C.positionCol $ C.fieldLineAnn b) (min (C.positionCol pos1) (C.positionCol pos2)) fls2-    mcol2 = foldl' (\a b -> min a $ C.positionCol $ C.fieldLineAnn b) (C.positionCol pos1) fls2--    mk :: Int -> C.Position -> C.FieldLine C.Position -> (C.Position, String)-    mk col p (C.FieldLine q bs) =-      ( q,-        -- in Cabal-syntax there is no upper limit, i.e. no min-        -- we squash multiple empty lines to one-        replicate (min 2 newlines) '\n'-          ++ replicate indent ' '-          ++ fromUTF8BS bs-      )-      where-        newlines = C.positionRow q - C.positionRow p-        indent = C.positionCol q - col--mealy :: (s -> a -> (s, b)) -> s -> [a] -> [b]-mealy f = go-  where-    go _ [] = []-    go s (x : xs) = let ~(s', y) = f s x in y : go s' xs
− source/library/CabalGild/Glob.hs
@@ -1,69 +0,0 @@-module CabalGild.Glob where--import Data.List (isInfixOf)-import Data.List.NonEmpty (NonEmpty (..))-import qualified Data.List.NonEmpty as NonEmpty-import qualified System.FilePath as Native (splitDirectories)-import qualified System.FilePath.Posix as Posix (splitDirectories)--data Glob = Glob FilePath [GlobPiece]-  deriving (Show)--data GlobPiece-  = GlobStarStar-  | GlobPiece (NonEmpty GlobChar)-  deriving (Show)--data GlobChar-  = GlobStar-  | GlobChar Char-  deriving (Show)---- | Match glob------ >>> let Right g = parseGlob "cbits/**/*.c"------ >>> map (match g) ["foo", "cbits/header.h", "cbits/source.c", "cbits/dir/source.c"]--- [False,False,True,True]-match :: Glob -> FilePath -> Bool-match (Glob g1 gs0) fp = go0 (Native.splitDirectories fp)-  where-    go0 [] = False-    go0 (p : ps) = p == g1 && go ps gs0--    go :: [FilePath] -> [GlobPiece] -> Bool-    go [] [] = True-    go [] (_ : _) = False-    go (_ : _) [] = False-    go (s : ss) (GlobStarStar : gs) = go (s : ss) gs || go ss (GlobStarStar : gs)-    go (s : ss) (GlobPiece cs : gs) = matches s (NonEmpty.toList cs) && go ss gs--    matches :: FilePath -> [GlobChar] -> Bool-    matches [] [] = True-    matches (_ : _) [] = False-    matches [] (_ : _) = False-    matches (x : xs) (GlobStar : cs) = matches (x : xs) cs || matches xs (GlobStar : cs)-    matches (x : xs) (GlobChar c : cs) = x == c && matches xs cs--parseGlob :: String -> Either String Glob-parseGlob input = case Posix.splitDirectories input of-  [] -> Left "empty path"-  (x : xs) -> do-    p <- parseFirstPiece x-    ps <- traverse parsePiece xs-    return (Glob p ps)-  where-    parseFirstPiece :: String -> Either String FilePath-    parseFirstPiece "" = Left "empty path segment"-    parseFirstPiece s | "*" `isInfixOf` s = Left "wild card in first path segment"-    parseFirstPiece s = Right s--    parsePiece :: String -> Either String GlobPiece-    parsePiece "" = Left "empty path segment"-    parsePiece "**" = Right GlobStarStar-    parsePiece s | "**" `isInfixOf` s = Left $ "** inside path segment: " ++ s-    parsePiece (c : cs) = Right (GlobPiece (parseChar c :| map parseChar cs))--    parseChar :: Char -> GlobChar-    parseChar '*' = GlobStar-    parseChar c = GlobChar c
source/library/CabalGild/Main.hs view
@@ -1,153 +1,93 @@--- |--- License: BSD-3-Clause--- Copyright: Oleg Grenrus-module CabalGild.Main (main) where+module CabalGild.Main where -import CabalGild (cabalGild)-import CabalGild.Error (Error (SomeError), renderError)-import CabalGild.Monad (runCabalGildIO)-import CabalGild.Options+import qualified CabalGild.Action.AttachComments as AttachComments+import qualified CabalGild.Action.Discover as Discover+import qualified CabalGild.Action.ExtractComments as ExtractComments+import qualified CabalGild.Action.Format as Format+import qualified CabalGild.Action.GetCabalVersion as GetCabalVersion+import qualified CabalGild.Action.Reindent as Reindent+import qualified CabalGild.Action.RemovePositions as RemovePositions+import qualified CabalGild.Action.Render as Render+import qualified CabalGild.Class.MonadLog as MonadLog+import qualified CabalGild.Class.MonadRead as MonadRead+import qualified CabalGild.Class.MonadWalk as MonadWalk+import qualified CabalGild.Class.MonadWrite as MonadWrite+import qualified CabalGild.Exception.CheckFailure as CheckFailure+import qualified CabalGild.Exception.ParseError as ParseError+import qualified CabalGild.Type.Config as Config+import qualified CabalGild.Type.Flag as Flag+import qualified CabalGild.Type.Mode as Mode import qualified Control.Monad as Monad import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as BS import qualified Data.Maybe as Maybe-import Data.Traversable (for) import qualified Data.Version as Version-import Distribution.Utils.Generic (toUTF8BS)+import qualified Distribution.Fields as Fields import qualified Paths_cabal_gild as This import qualified System.Console.GetOpt as GetOpt import qualified System.Environment as Environment-import System.Exit (exitFailure) import qualified System.Exit as Exit-import System.FilePath (takeDirectory)-import System.IO (hPutStrLn, stderr)-import qualified Text.Read as Read+import qualified System.IO as IO -main :: IO ()-main = do+defaultMain :: IO ()+defaultMain = Exception.handle onException $ do+  name <- Environment.getProgName   arguments <- Environment.getArgs-  let (flags, filepaths, unknowns, invalids) = GetOpt.getOpt' GetOpt.Permute flagOptions arguments-  mapM_ (Exception.throwM . userError . mappend "unknown option: ") unknowns-  mapM_ (Exception.throwM . userError . mappend "invalid option: ") invalids-  config <- flagsToConfig flags-  let opts = configOptions config--  Monad.when (configHelp config) $ do-    name <- Environment.getProgName-    putStr $ GetOpt.usageInfo name flagOptions-    Exit.exitSuccess--  Monad.when (configVersion config) $ do-    putStrLn $ Version.showVersion This.version-    Exit.exitSuccess--  notFormatted <--    Maybe.catMaybes <$> case filepaths of-      [] -> fmap pure $ BS.getContents >>= main' opts Nothing-      (_ : _) -> for filepaths $ \filepath -> do-        contents <- BS.readFile filepath-        main' opts (Just filepath) contents--  Monad.when ((optMode opts == ModeCheck) && not (null notFormatted)) $ do-    Monad.forM_ notFormatted $ \filepath ->-      hPutStrLn stderr $ "error: Input " <> filepath <> " is not formatted."-    exitFailure--main' :: Options -> Maybe FilePath -> BS.ByteString -> IO (Maybe FilePath)-main' opts mfilepath input = do-  -- name of the input-  let filepath = Maybe.fromMaybe "<stdin>" mfilepath--  mroot <--    fmap takeDirectory <$> case (mfilepath, optStdinInputFile opts) of-      (Just _, Just _) -> do-        renderError $ SomeError "cannot pass both --stdin-input-file and FILE"-        exitFailure-      (Just f, Nothing) -> pure $ Just f-      (Nothing, Just f) -> pure $ Just f-      (Nothing, Nothing) -> pure Nothing--  -- process-  res <- runCabalGildIO mroot opts (cabalGild filepath input)--  case res of-    Right output -> do-      let outputBS = toUTF8BS output-          formatted = outputBS == input--      case optMode opts of-        ModeStdout -> BS.putStr outputBS-        ModeInplace -> case mfilepath of-          Nothing -> BS.putStr outputBS-          Just _ -> Monad.unless formatted $ BS.writeFile filepath outputBS-        _ -> return ()--      return $ if formatted then Nothing else Just filepath-    Left err -> do-      renderError err-      exitFailure------------------------------------------------------------------------------------ Options parser--------------------------------------------------------------------------------+  mainWith name arguments -data Flag-  = FlagCabalFile Bool-  | FlagError Bool-  | FlagHelp-  | FlagIndent String-  | FlagMode Mode-  | FlagStdinInputFile String-  | FlagTabular Bool-  | FlagVersion-  deriving (Eq, Show)+onException :: Exception.SomeException -> IO a+onException e = case Exception.fromException e of+  Just exitCode -> Exit.exitWith exitCode+  Nothing -> do+    IO.hPutStrLn IO.stderr $ Exception.displayException e+    Exit.exitFailure -flagOptions :: [GetOpt.OptDescr Flag]-flagOptions =-  [ GetOpt.Option [] ["Werror"] (GetOpt.NoArg $ FlagError True) "Treat warnings as errors",-    GetOpt.Option [] ["Wno-error"] (GetOpt.NoArg $ FlagError False) "",-    GetOpt.Option [] ["indent"] (GetOpt.ReqArg FlagIndent "N") "Indentation",-    GetOpt.Option [] ["tabular"] (GetOpt.NoArg $ FlagTabular True) "Tabular formatting",-    GetOpt.Option [] ["no-tabular"] (GetOpt.NoArg $ FlagTabular False) "",-    GetOpt.Option [] ["cabal-file"] (GetOpt.NoArg $ FlagCabalFile True) "",-    GetOpt.Option ['n'] ["no-cabal-file"] (GetOpt.NoArg $ FlagCabalFile False) "Don't parse as .cabal file",-    GetOpt.Option [] ["stdout"] (GetOpt.NoArg $ FlagMode ModeStdout) "Write output to stdout (default)",-    GetOpt.Option ['i'] ["inplace"] (GetOpt.NoArg $ FlagMode ModeInplace) "Process files in-place",-    GetOpt.Option ['c'] ["check"] (GetOpt.NoArg $ FlagMode ModeCheck) "Fail with non-zero exit code if input is not formatted",-    GetOpt.Option [] ["stdin-input-file"] (GetOpt.ReqArg FlagStdinInputFile "FILE") "When reading from STDIN, use this file path to resolve relative references",-    GetOpt.Option ['h'] ["help"] (GetOpt.NoArg FlagHelp) "Show this help text",-    GetOpt.Option [] ["version"] (GetOpt.NoArg FlagVersion) "Show version"-  ]+mainWith ::+  ( MonadLog.MonadLog m,+    MonadRead.MonadRead m,+    Exception.MonadThrow m,+    MonadWalk.MonadWalk m,+    MonadWrite.MonadWrite m+  ) =>+  String ->+  [String] ->+  m ()+mainWith name arguments = do+  flags <- Flag.fromArguments arguments+  config <- Config.fromFlags flags+  let version = Version.showVersion This.version -data Config = Config-  { configHelp :: Bool,-    configOptions :: Options,-    configVersion :: Bool-  }-  deriving (Show)+  Monad.when (Config.help config) $ do+    let header =+          unlines+            [ name <> " version " <> version,+              "",+              "<https://github.com/tfausak/cabal-gild>"+            ]+    MonadLog.log $ GetOpt.usageInfo header Flag.options+    Exception.throwM Exit.ExitSuccess -initialConfig :: Config-initialConfig =-  Config-    { configHelp = False,-      configOptions = defaultOptions,-      configVersion = False-    }+  Monad.when (Config.version config) $ do+    MonadLog.logLn version+    Exception.throwM Exit.ExitSuccess -applyFlag :: (Exception.MonadThrow m) => Config -> Flag -> m Config-applyFlag c f = case f of-  FlagCabalFile b -> pure c {configOptions = (configOptions c) {optCabalFile = b}}-  FlagError b -> pure c {configOptions = (configOptions c) {optError = b}}-  FlagHelp -> pure c {configHelp = True}-  FlagIndent s -> do-    i <- case Read.readMaybe s of-      Nothing -> Exception.throwM . userError $ "invalid indent: " <> show s-      Just i -> pure i-    pure c {configOptions = (configOptions c) {optIndent = i}}-  FlagMode m -> pure c {configOptions = (configOptions c) {optMode = m}}-  FlagStdinInputFile s -> pure c {configOptions = (configOptions c) {optStdinInputFile = Just s}}-  FlagTabular b -> pure c {configOptions = (configOptions c) {optTabular = b}}-  FlagVersion -> pure c {configVersion = True}+  input <- MonadRead.read $ Config.input config+  fields <-+    either (Exception.throwM . ParseError.ParseError) pure $+      Fields.readFields input+  let csv = GetCabalVersion.fromFields fields+      comments = ExtractComments.fromByteString input+  output <-+    ( AttachComments.run+        Monad.>=> Reindent.run csv+        Monad.>=> RemovePositions.run+        Monad.>=> Discover.run (Maybe.fromMaybe (Config.stdin config) $ Config.input config)+        Monad.>=> Format.run csv+        Monad.>=> Render.run+      )+      (fields, comments) -flagsToConfig :: (Exception.MonadThrow m) => [Flag] -> m Config-flagsToConfig = Monad.foldM applyFlag initialConfig+  case Config.mode config of+    Mode.Check ->+      Monad.when (output /= input) $+        Exception.throwM CheckFailure.CheckFailure+    Mode.Format -> MonadWrite.write (Config.output config) output
− source/library/CabalGild/Monad.hs
@@ -1,226 +0,0 @@-{-# LANGUAGE DerivingStrategies #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE ScopedTypeVariables #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Monad-  ( -- * Monad class-    MonadCabalGild (..),-    getFiles,-    Contents (..),--    -- * Pure implementation-    CabalGild,-    runCabalGild,--    -- * IO implementation-    CabalGildIO,-    runCabalGildIO,-  )-where--import CabalGild.Error-import CabalGild.Options-import Control.Exception-  ( IOException,-    catch,-    displayException,-    throwIO,-    try,-  )-import Control.Monad (when)-import Control.Monad.Except (MonadError (..))-import Control.Monad.IO.Class (MonadIO (..))-import Control.Monad.Reader (MonadReader (..), ReaderT (..), asks, runReaderT)-import Control.Monad.Writer (WriterT, runWriterT, tell)-import Data.Bifunctor (first)-import qualified Data.ByteString as BS-import Data.List (isPrefixOf, stripPrefix)-import qualified Data.Map as Map-import Data.Maybe (mapMaybe)-import qualified System.Directory as D-import System.Exit (exitFailure)-import System.FilePath (pathSeparator, (</>))-import System.IO (hPutStrLn, stderr)------------------------------------------------------------------------------------ Class------------------------------------------------------------------------------------ | @cabal-gild@ interface.------ * reader of 'Options'--- * errors of 'Error'--- * can list directories-class (HasOptions r, MonadReader r m, MonadError Error m) => MonadCabalGild r m | m -> r where-  listDirectory :: FilePath -> m [FilePath]-  doesDirectoryExist :: FilePath -> m Bool--  readFileBS :: FilePath -> m Contents--  displayWarning :: String -> m ()--data Contents-  = Contents BS.ByteString-  | NoIO-  | IOError String------------------------------------------------------------------------------------ Pure------------------------------------------------------------------------------------ | Pure 'MonadCabalGild'.------ 'listDirectory' always return empty list.-newtype CabalGild a = CabalGild {unCabalGild :: ReaderT (Options, Map.Map FilePath BS.ByteString) (WriterT [String] (Either Error)) a}-  deriving newtype (Functor, Applicative, Monad, MonadError Error)--instance MonadReader Options CabalGild where-  ask = CabalGild $ asks fst--  local f (CabalGild m) = CabalGild $ local (first f) m--instance MonadCabalGild Options CabalGild where-  listDirectory dir = CabalGild $ do-    files <- asks snd-    return $ mapMaybe f (Map.keys files)-    where-      f :: FilePath -> Maybe FilePath-      f fp = do-        rest <- stripPrefix (dir ++ [pathSeparator]) fp-        return $ takeWhile (/= pathSeparator) rest--  doesDirectoryExist dir = CabalGild $ do-    files <- asks snd-    return (any (isPrefixOf (dir ++ [pathSeparator])) (Map.keys files))--  readFileBS p = CabalGild $ do-    files <- asks snd-    return (maybe (IOError "doesn't exist") Contents $ Map.lookup p files)--  displayWarning w = do-    werror <- asks optError-    if werror-      then throwError $ WarningError w-      else CabalGild $ tell [w]--runCabalGild ::-  Map.Map FilePath BS.ByteString ->-  Options ->-  CabalGild a ->-  Either Error (a, [String])-runCabalGild files opts m = runWriterT (runReaderT (unCabalGild m) (opts, files))------------------------------------------------------------------------------------ IO------------------------------------------------------------------------------------ | Options with root for directory traversals-data Options' = Options'-  { optRootDir :: Maybe FilePath,-    optOpt :: Options-  }--instance HasOptions Options' where-  options f (Options' mfp o) = Options' mfp <$> f o--newtype CabalGildIO a = CabalGildIO {unCabalGildIO :: ReaderT Options' IO a}-  deriving newtype (Functor, Applicative, Monad, MonadIO, MonadReader Options')--instance MonadError Error CabalGildIO where-  throwError = liftIO . throwIO-  catchError m h = CabalGildIO $ ReaderT $ \r ->-    catch (unCabalGildIO' r m) (unCabalGildIO' r . h)-    where-      unCabalGildIO' :: Options' -> CabalGildIO a -> IO a-      unCabalGildIO' r m' = runReaderT (unCabalGildIO m') r--instance MonadCabalGild Options' CabalGildIO where-  listDirectory p = do-    rd <- asks optRootDir-    case rd of-      Nothing -> return []-      Just d -> liftIO (D.listDirectory (d </> p))-  doesDirectoryExist p = do-    rd <- asks optRootDir-    case rd of-      Nothing -> return False-      Just d -> liftIO (D.doesDirectoryExist (d </> p))-  readFileBS p = do-    rd <- asks optRootDir-    case rd of-      Nothing -> return NoIO-      Just d -> liftIO $ catchIOError $ BS.readFile (d </> p)-  displayWarning w = do-    werror <- asks (optError . optOpt)-    liftIO $ do-      hPutStrLn stderr $ (if werror then "ERROR: " else "WARNING: ") ++ w-      when werror exitFailure--catchIOError :: IO BS.ByteString -> IO Contents-catchIOError m = catch (fmap Contents m) handler-  where-    handler :: IOException -> IO Contents-    handler exc = return (IOError (displayException exc))--runCabalGildIO :: Maybe FilePath -> Options -> CabalGildIO a -> IO (Either Error a)-runCabalGildIO mfp opts m = try $ runReaderT (unCabalGildIO m) (Options' mfp opts)------------------------------------------------------------------------------------ Files----------------------------------------------------------------------------------getFiles :: (MonadCabalGild r m) => FilePath -> m [FilePath]-getFiles = getDirectoryContentsRecursive' check-  where-    check "dist-newstyle" = False-    check ('.' : _) = False-    check _ = True---- | List all the files in a directory and all subdirectories.------ The order places files in sub-directories after all the files in their--- parent directories. The list is generated lazily so is not well defined if--- the source directory structure changes before the list is used.------ /Note:/ From @Cabal@'s "Distribution.Simple.Utils"-getDirectoryContentsRecursive' ::-  forall m r.-  (MonadCabalGild r m) =>-  -- | Check, whether to recurse-  (FilePath -> Bool) ->-  -- | top dir-  FilePath ->-  m [FilePath]-getDirectoryContentsRecursive' ignore' topdir = recurseDirectories [""]-  where-    recurseDirectories :: [FilePath] -> m [FilePath]-    recurseDirectories [] = return []-    recurseDirectories (dir : dirs) = do-      (files, dirs') <- collect [] [] =<< listDirectory (topdir </> dir)-      files' <- recurseDirectories (dirs' ++ dirs)-      return (files ++ files')-      where-        collect :: [FilePath] -> [FilePath] -> [[Char]] -> m ([FilePath], [FilePath])-        collect files dirs' [] =-          return-            ( reverse files,-              reverse dirs'-            )-        collect files dirs' (entry : entries)-          | ignore entry =-              collect files dirs' entries-        collect files dirs' (entry : entries) = do-          let dirEntry = dir </> entry-          isDirectory <- doesDirectoryExist (topdir </> dirEntry)-          if isDirectory-            then collect files (dirEntry : dirs') entries-            else collect (dirEntry : files) dirs' entries--        ignore ['.'] = True-        ignore ['.', '.'] = True-        ignore x = not (ignore' x)
− source/library/CabalGild/Options.hs
@@ -1,66 +0,0 @@--- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Options-  ( Mode (..),-    Options (..),-    defaultOptions,-    OptionsMorphism,-    mkOptionsMorphism,-    runOptionsMorphism,-    HasOptions (..),-  )-where--import qualified Distribution.CabalSpecVersion as C-import Distribution.Compat.Lens (LensLike')--data Mode-  = ModeStdout-  | ModeInplace-  | ModeCheck-  deriving (Eq, Show)--data Options = Options-  { optError :: !Bool,-    optIndent :: !Int,-    optTabular :: !Bool,-    optCabalFile :: !Bool,-    optSpecVersion :: !C.CabalSpecVersion,-    optMode :: !Mode,-    optStdinInputFile :: !(Maybe FilePath)-  }-  deriving (Show)--defaultOptions :: Options-defaultOptions =-  Options-    { optError = False,-      optIndent = 2,-      optTabular = True,-      optCabalFile = True,-      optSpecVersion = C.cabalSpecLatest,-      optMode = ModeStdout,-      optStdinInputFile = Nothing-    }--newtype OptionsMorphism = OM (Options -> Options)--runOptionsMorphism :: OptionsMorphism -> Options -> Options-runOptionsMorphism (OM f) = f--mkOptionsMorphism :: (Options -> Options) -> OptionsMorphism-mkOptionsMorphism = OM--instance Semigroup OptionsMorphism where-  OM f <> OM g = OM (g . f)--instance Monoid OptionsMorphism where-  mempty = OM id-  mappend = (<>)--class HasOptions e where-  options :: (Functor f) => LensLike' f e Options--instance HasOptions Options where-  options = id
− source/library/CabalGild/Parser.hs
@@ -1,28 +0,0 @@--- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Parser where--import CabalGild.Error-import CabalGild.Monad-import qualified Control.Monad.Except as Except-import qualified Data.ByteString as BS-import qualified Distribution.Fields as C-import qualified Distribution.PackageDescription.Parsec as C-import qualified Distribution.Parsec as C-import qualified Distribution.Types.GenericPackageDescription as C--runParseResult :: (MonadCabalGild r m) => FilePath -> BS.ByteString -> C.ParseResult a -> m a-runParseResult filepath contents pr = case result of-  Right gpd -> return gpd-  Left (mspecVersion, errors) -> Except.throwError $ CabalParseError filepath contents errors mspecVersion warnings-  where-    (warnings, result) = C.runParseResult pr--parseGpd :: (MonadCabalGild r m) => FilePath -> BS.ByteString -> m C.GenericPackageDescription-parseGpd filepath contents = runParseResult filepath contents $ C.parseGenericPackageDescription contents--parseFields :: (MonadCabalGild r m) => BS.ByteString -> m [C.Field C.Position]-parseFields contents = case C.readFields contents of-  Left err -> Except.throwError $ PanicCannotParseInput err-  Right x -> return x
− source/library/CabalGild/Pragma.hs
@@ -1,100 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module CabalGild.Pragma where--import CabalGild.Comments-import CabalGild.Glob-import qualified Data.Bifunctor as Bifunctor-import qualified Data.ByteString as BS-import qualified Data.Either as Either-import qualified Data.Maybe as Maybe-import qualified Distribution.Compat.CharParsing as C-import qualified Distribution.ModuleName as C-import qualified Distribution.Parsec as C-import qualified Distribution.Parsec.FieldLineStream as C------------------------------------------------------------------------------------ Types----------------------------------------------------------------------------------data Pragma-  = FieldPragma FieldPragma-  | GlobalPragma GlobalPragma-  deriving (Show)---- | Pragmas applied per field-data FieldPragma-  = PragmaExpandModules FilePath [C.ModuleName]-  | PragmaGlobFiles Glob-  | PragmaFragment FilePath-  deriving (Show)---- | Pragmas affecting global output-data GlobalPragma-  = PragmaOptIndent Int-  | PragmaOptTabular Bool-  deriving (Show)------------------------------------------------------------------------------------ Parser------------------------------------------------------------------------------------ | Parse pragma from 'ByteString'.------ An error ('Left') is reported only if input 'ByteString' starts with @-- cabal-gild:@.-parsePragma :: BS.ByteString -> Either String (Maybe Pragma)-parsePragma bs = case dropPrefix bs of-  Nothing -> Right Nothing-  Just bs' -> Bifunctor.bimap show Just $ C.runParsecParser parser "<input>" $ C.fieldLineStreamFromBS bs'-  where-    dropPrefix bs0 = do-      bs1 <- BS.stripPrefix "--" bs0-      bs2 <- BS.stripPrefix "cabal-gild:" (stripWhitespace bs1)-      return (stripWhitespace bs2)--    parser :: C.ParsecParser Pragma-    parser = do-      t <- C.parsecToken-      case t of-        "expand" -> expandModules-        "indent" -> indent-        "glob-files" -> globFiles-        "tabular" -> return $ GlobalPragma $ PragmaOptTabular True-        "no-tabular" -> return $ GlobalPragma $ PragmaOptTabular False-        "fragment" -> fragment-        _ -> fail $ "Unknown pragma " ++ t--    expandModules :: C.ParsecParser Pragma-    expandModules = do-      C.spaces-      dir <- C.parsecToken-      mns <- C.many (C.space *> C.spaces *> C.char '-' *> C.parsec)-      return $ FieldPragma $ PragmaExpandModules dir mns--    indent :: C.ParsecParser Pragma-    indent = do-      C.spaces-      GlobalPragma . PragmaOptIndent <$> C.integral--    fragment :: C.ParsecParser Pragma-    fragment = do-      C.spaces-      FieldPragma . PragmaFragment <$> C.parsecToken--    globFiles :: C.ParsecParser Pragma-    globFiles = do-      C.spaces-      t <- C.parsecToken-      case parseGlob t of-        Right g -> return $ FieldPragma $ PragmaGlobFiles g-        Left e -> C.unexpected e--stripWhitespace :: BS.ByteString -> BS.ByteString-stripWhitespace bs = case BS.uncons bs of-  Nothing -> bs-  Just (w, bs')-    | w == 32 -> stripWhitespace bs'-    | otherwise -> bs--parsePragmas :: Comments -> ([String], [Pragma])-parsePragmas = fmap Maybe.catMaybes . Either.partitionEithers . map parsePragma . unComments
− source/library/CabalGild/Refactoring.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Refactoring-  ( CommentsPragmas,-    refactor,-  )-where--import CabalGild.Fields.SourceFiles-import CabalGild.Monad-import CabalGild.Refactoring.ExpandExposedModules-import CabalGild.Refactoring.Fragments-import CabalGild.Refactoring.GlobFiles-import CabalGild.Refactoring.Type-import qualified Distribution.Fields as C------------------------------------------------------------------------------------ Refactorings----------------------------------------------------------------------------------refactor :: forall m r. (MonadCabalGild r m) => [C.Field CommentsPragmas] -> m [C.Field CommentsPragmas]-refactor = rewriteFields rewrite-  where-    rewrite :: C.Field CommentsPragmas -> m (Maybe (C.Field CommentsPragmas))-    rewrite f@(C.Field (C.Name _ n) _)-      | n == "exposed-modules" || n == "other-modules" =-          combine-            [ refactoringFragments,-              refactoringExpandExposedModules-            ]-            f-      | n `elem` fileFields =-          combine-            [ refactoringFragments,-              refactoringGlobFiles-            ]-            f-      | otherwise =-          combine-            [ refactoringFragments-            ]-            f-    rewrite f@C.Section {} =-      combine-        [ refactoringFragments-        ]-        f---- | Try refactorings in turn,--- considering it done if one applies.-combine ::-  (Monad m) =>-  [C.Field CommentsPragmas -> m (Maybe (C.Field CommentsPragmas))] ->-  C.Field CommentsPragmas ->-  m (Maybe (C.Field CommentsPragmas))-combine [] _ = return Nothing-combine (r : rs) f = do-  m <- r f-  case m of-    Nothing -> combine rs f-    Just f' -> return (Just f')
− source/library/CabalGild/Refactoring/ExpandExposedModules.hs
@@ -1,53 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes #-}-{-# OPTIONS_GHC -Wno-deprecations #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Refactoring.ExpandExposedModules-  ( refactoringExpandExposedModules,-  )-where--import CabalGild.Monad-import CabalGild.Pragma-import CabalGild.Refactoring.Type-import qualified Data.List as List-import qualified Data.Maybe as Maybe-import qualified Distribution.Compat.Lens as Lens-import qualified Distribution.Fields as C-import qualified Distribution.ModuleName as C-import Distribution.Utils.Generic (toUTF8BS)-import qualified System.FilePath as FilePath--refactoringExpandExposedModules :: FieldRefactoring-refactoringExpandExposedModules C.Section {} = pure Nothing-refactoringExpandExposedModules (C.Field name@(C.Name (_, _, pragmas) _n) fls) = do-  dirs <- parse pragmas-  files <- (traverse . Lens._1) getFiles dirs--  let newModules :: [C.FieldLine CommentsPragmas]-      newModules =-        Maybe.catMaybes-          [ return $ C.FieldLine emptyCommentsPragmas $ toUTF8BS $ List.intercalate "." parts-            | (files', mns) <- files,-              file <- files',-              let parts = FilePath.splitDirectories $ FilePath.dropExtension file,-              all C.validModuleComponent parts,-              let mn = C.fromComponents parts, -- TODO: don't use fromComponents-              mn `notElem` mns-          ]--  pure $ case newModules of-    [] -> Nothing-    _ -> Just (C.Field name (newModules ++ fls))-  where-    parse :: (MonadCabalGild r m) => [FieldPragma] -> m [(FilePath, [C.ModuleName])]-    parse = fmap mconcat . traverse go-      where-        go :: (MonadCabalGild r m) => FieldPragma -> m [(FilePath, [C.ModuleName])]-        go (PragmaExpandModules fp mns) = return [(fp, mns)]-        go p = do-          displayWarning $ "Skipped pragma " ++ show p-          return []
− source/library/CabalGild/Refactoring/Fragments.hs
@@ -1,90 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Refactoring.Fragments-  ( refactoringFragments,-  )-where--import CabalGild.Comments-import CabalGild.Monad-import CabalGild.Parser-import CabalGild.Pragma-import CabalGild.Refactoring.Type-import qualified Control.Monad as Monad-import qualified Data.Foldable as Foldable-import qualified Distribution.Fields as C-import qualified Distribution.Fields.Field as C-import qualified Distribution.Fields.Pretty as C-import qualified Distribution.Parsec as C-import Distribution.Utils.Generic (fromUTF8BS)-import Text.PrettyPrint (hsep, render)---- | Expand fragments.------ Applies to all fields and sections-refactoringFragments :: FieldRefactoring-refactoringFragments field = do-  mp <- parse (getPragmas field)-  case mp of-    Nothing -> pure Nothing-    Just p ->-      readFileBS p >>= \mcontents -> case mcontents of-        NoIO -> pure Nothing-        IOError err -> do-          displayWarning $ "Fragment " ++ p ++ " failed to read: " ++ show err-          pure Nothing-        Contents c -> do-          fields <- parseFields c-          case (field, fields) of-            (_, []) -> do-              displayWarning $ "Fragment " ++ p ++ " is empty."-              pure Nothing-            (C.Field (C.Name _ n) _, C.Section name@(C.Name _ _) arg _ : _) -> do-              displayWarning $ "Fragment " ++ p ++ " contains a section " ++ showSection name arg ++ ", expecting field " ++ show n ++ "."-              pure Nothing-            (C.Section name@(C.Name _ _) arg _, C.Field (C.Name _ n') _ : _) -> do-              displayWarning $ "Fragment " ++ p ++ " contains a field " ++ show n' ++ ", expecting section " ++ showSection name arg ++ "."-              pure Nothing-            (C.Field name@(C.Name _ n) _, C.Field (C.Name _ n') fls' : rest) -> do-              Monad.unless (null rest) $-                displayWarning $-                  "Fragment " ++ p ++ " contains multiple fields or sections, using only the first."-              if n == n'-                then do-                  -- everything is fine, replace-                  pure (Just (C.Field name (noCommentsPragmas fls')))-                else do-                  displayWarning $ "Fragment " ++ p ++ " contains field " ++ show n' ++ ", expecting field " ++ show n ++ "."-                  pure Nothing-            (C.Section name@(C.Name _ _) arg _, C.Section name'@(C.Name _ _) arg' fs' : rest) -> do-              Monad.unless (null rest) $-                displayWarning $-                  "Fragment " ++ p ++ " contains multiple fields or sections, using only the first."--              if Monad.void name == Monad.void name' && map Monad.void arg == map Monad.void arg'-                then do-                  pure (Just (C.Section name arg (noCommentsPragmas fs')))-                else do-                  displayWarning $ "Fragment " ++ p ++ " contains a section " ++ showSection name arg ++ ", expecting section " ++ showSection name' arg' ++ "."-                  pure Nothing-  where-    noCommentsPragmas :: (Functor f) => [f ann] -> [f CommentsPragmas]-    noCommentsPragmas = map ((C.zeroPos, Comments [], []) <$)--    getPragmas :: C.Field CommentsPragmas -> [FieldPragma]-    getPragmas = (\(_, _, z) -> z) . C.fieldAnn--    showSection :: C.Name ann -> [C.SectionArg ann] -> String-    showSection (C.Name _ n) [] = show n-    showSection (C.Name _ n) args = show (fromUTF8BS n ++ " " ++ render (hsep (C.prettySectionArgs n args)))--    parse :: (MonadCabalGild r m) => [FieldPragma] -> m (Maybe FilePath)-    parse = fmap Foldable.asum . traverse go-      where-        go :: (Monad m) => FieldPragma -> m (Maybe FilePath)-        go (PragmaFragment f) = return (Just f)-        go _ = return Nothing
− source/library/CabalGild/Refactoring/GlobFiles.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Refactoring.GlobFiles-  ( refactoringGlobFiles,-  )-where--import CabalGild.Glob-import CabalGild.Monad-import CabalGild.Pragma-import CabalGild.Refactoring.Type-import qualified Data.Maybe as Maybe-import qualified Distribution.Fields as C-import Distribution.Utils.Generic (toUTF8BS)-import qualified System.FilePath as Native-import qualified System.FilePath.Posix as Posix--refactoringGlobFiles :: FieldRefactoring-refactoringGlobFiles C.Section {} = pure Nothing-refactoringGlobFiles (C.Field name@(C.Name (_, _, pragmas) _n) fls) = do-  globs <- parse pragmas-  files <- fmap concat (traverse match' globs)--  let newFiles :: [C.FieldLine CommentsPragmas]-      newFiles =-        Maybe.catMaybes-          [ return $ C.FieldLine emptyCommentsPragmas $ toUTF8BS file-            | file <- files-          ]--  pure $ case files of-    [] -> Nothing-    _ -> Just (C.Field name (newFiles ++ fls))-  where-    parse :: (MonadCabalGild r m) => [FieldPragma] -> m [Glob]-    parse = fmap mconcat . traverse go-      where-        go :: (MonadCabalGild r m) => FieldPragma -> m [Glob]-        go (PragmaGlobFiles g) = return [g]-        go p = do-          displayWarning $ "Skipped pragma " ++ show p-          return []--    match' :: (MonadCabalGild r m) => Glob -> m [FilePath]-    match' g@(Glob dir _) = do-      files <- map (dir Native.</>) <$> getFiles dir-      return $ map toPosix $ filter (match g) files--    toPosix :: FilePath -> FilePath-    toPosix = Posix.joinPath . Native.splitDirectories
− source/library/CabalGild/Refactoring/Type.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE RankNTypes #-}---- |--- License: GPL-3.0-or-later--- Copyright: Oleg Grenrus-module CabalGild.Refactoring.Type-  ( FieldRefactoring,-    CommentsPragmas,-    emptyCommentsPragmas,-    rewriteFields,-  )-where--import CabalGild.Comments-import CabalGild.Monad-import CabalGild.Pragma-import qualified Distribution.Fields as C-import qualified Distribution.Parsec as C------------------------------------------------------------------------------------ Refactoring type----------------------------------------------------------------------------------type CommentsPragmas = (C.Position, Comments, [FieldPragma])--emptyCommentsPragmas :: CommentsPragmas-emptyCommentsPragmas = (C.zeroPos, mempty, mempty)--type FieldRefactoring =-  forall r m.-  (MonadCabalGild r m) =>-  (C.Field CommentsPragmas -> m (Maybe (C.Field CommentsPragmas)))------------------------------------------------------------------------------------ Traversing refactoring------------------------------------------------------------------------------------ | A top-to-bottom rewrite of sections and fields-rewriteFields ::-  (MonadCabalGild r m) =>-  (C.Field CommentsPragmas -> m (Maybe (C.Field CommentsPragmas))) ->-  [C.Field CommentsPragmas] ->-  m [C.Field CommentsPragmas]-rewriteFields f = goMany-  where-    goMany = traverse go--    go x = do-      m <- f x-      case m of-        Just y -> return y-        Nothing -> case x of-          C.Field {} -> return x-          C.Section name args fs -> C.Section name args <$> goMany fs
+ source/library/CabalGild/Type/Block.hs view
@@ -0,0 +1,57 @@+module CabalGild.Type.Block where++import qualified CabalGild.Type.Line as Line+import qualified Data.ByteString as ByteString+import qualified Distribution.Compat.Lens as Lens+import Prelude hiding (lines)++data Block = Block+  { lineBefore :: Bool,+    lines :: [Line.Line],+    lineAfter :: Bool+  }+  deriving (Eq, Show)++instance Semigroup Block where+  x <> y =+    let s = [Line.empty | lineAfter x || lineBefore y]+        z =+          Block+            { lineBefore = lineBefore x,+              lines = lines x <> s <> lines y,+              lineAfter = lineAfter y+            }+     in if isEmpty x then y else if isEmpty y then x else z++instance Monoid Block where+  mempty =+    Block+      { lineBefore = False,+        lines = [],+        lineAfter = False+      }++fromLine :: Line.Line -> Block+fromLine l = mempty {lines = [l]}++isEmpty :: Block -> Bool+isEmpty = null . lines++lineAfterLens :: Lens.Lens' Block Bool+lineAfterLens f s = fmap (\a -> s {lineAfter = a}) . f $ lineAfter s++lineBeforeLens :: Lens.Lens' Block Bool+lineBeforeLens f s = fmap (\a -> s {lineBefore = a}) . f $ lineBefore s++toByteString :: Block -> ByteString.ByteString+toByteString b =+  if isEmpty b+    then ByteString.empty+    else+      ByteString.intercalate (ByteString.singleton 0x0a)+        . fmap Line.toByteString+        $ concat+          [ [Line.empty | lineBefore b],+            lines b,+            [Line.empty | lineAfter b]+          ]
+ source/library/CabalGild/Type/Chunk.hs view
@@ -0,0 +1,48 @@+module CabalGild.Type.Chunk where++import qualified Data.ByteString as ByteString+import qualified Distribution.Compat.Lens as Lens++data Chunk = Chunk+  { spaceBefore :: Bool,+    value :: ByteString.ByteString,+    spaceAfter :: Bool+  }+  deriving (Eq, Show)++instance Semigroup Chunk where+  x <> y =+    let s =+          if spaceAfter x && spaceBefore y+            then ByteString.singleton 0x20+            else ByteString.empty+        z =+          Chunk+            { spaceBefore = spaceBefore x,+              value = value x <> s <> value y,+              spaceAfter = spaceAfter y+            }+     in if isEmpty x then y else if isEmpty y then x else z++instance Monoid Chunk where+  mempty =+    Chunk+      { spaceBefore = False,+        value = ByteString.empty,+        spaceAfter = False+      }++colon :: Chunk+colon = Lens.set spaceAfterLens True . fromByteString $ ByteString.singleton 0x3a++fromByteString :: ByteString.ByteString -> Chunk+fromByteString bs = mempty {value = bs}++isEmpty :: Chunk -> Bool+isEmpty = ByteString.null . value++spaceAfterLens :: Lens.Lens' Chunk Bool+spaceAfterLens f s = fmap (\a -> s {spaceAfter = a}) . f $ spaceAfter s++spaceBeforeLens :: Lens.Lens' Chunk Bool+spaceBeforeLens f s = fmap (\a -> s {spaceBefore = a}) . f $ spaceBefore s
+ source/library/CabalGild/Type/Comment.hs view
@@ -0,0 +1,13 @@+module CabalGild.Type.Comment where++import qualified CabalGild.Extra.String as String+import qualified Data.ByteString as ByteString++data Comment a = Comment+  { annotation :: a,+    value :: ByteString.ByteString+  }+  deriving (Eq, Show)++delimiter :: ByteString.ByteString+delimiter = String.toUtf8 "--"
+ source/library/CabalGild/Type/Config.hs view
@@ -0,0 +1,45 @@+module CabalGild.Type.Config where++import qualified CabalGild.Type.Flag as Flag+import qualified CabalGild.Type.Mode as Mode+import qualified Control.Monad as Monad+import qualified Control.Monad.Catch as Exception++data Config = Config+  { help :: Bool,+    input :: Maybe FilePath,+    mode :: Mode.Mode,+    output :: Maybe FilePath,+    stdin :: FilePath,+    version :: Bool+  }+  deriving (Eq, Show)++initial :: Config+initial =+  Config+    { help = False,+      input = Nothing,+      mode = Mode.Format,+      output = Nothing,+      stdin = ".",+      version = False+    }++applyFlag :: (Exception.MonadThrow m) => Config -> Flag.Flag -> m Config+applyFlag config flag = case flag of+  Flag.Help b -> pure config {help = b}+  Flag.Input s -> case s of+    "-" -> pure config {input = Nothing}+    _ -> pure config {input = Just s}+  Flag.Mode s -> do+    m <- Mode.fromString s+    pure config {mode = m}+  Flag.Output s -> case s of+    "-" -> pure config {output = Nothing}+    _ -> pure config {output = Just s}+  Flag.Stdin s -> pure config {stdin = s}+  Flag.Version b -> pure config {version = b}++fromFlags :: (Exception.MonadThrow m) => [Flag.Flag] -> m Config+fromFlags = Monad.foldM applyFlag initial
+ source/library/CabalGild/Type/Flag.hs view
@@ -0,0 +1,68 @@+module CabalGild.Type.Flag where++import qualified CabalGild.Exception.InvalidOption as InvalidOption+import qualified CabalGild.Exception.UnexpectedArgument as UnexpectedArgument+import qualified CabalGild.Exception.UnknownOption as UnknownOption+import qualified Control.Monad.Catch as Exception+import qualified System.Console.GetOpt as GetOpt++data Flag+  = Help Bool+  | Input String+  | Mode String+  | Output String+  | Stdin String+  | Version Bool+  deriving (Eq, Show)++options :: [GetOpt.OptDescr Flag]+options =+  [ GetOpt.Option+      ['h', '?']+      ["help"]+      (GetOpt.NoArg $ Help True)+      "Shows this help message.",+    GetOpt.Option+      []+      ["no-help"]+      (GetOpt.NoArg $ Help False)+      "",+    GetOpt.Option+      ['v']+      ["version"]+      (GetOpt.NoArg $ Version True)+      "Shows the version number.",+    GetOpt.Option+      []+      ["no-version"]+      (GetOpt.NoArg $ Version False)+      "",+    GetOpt.Option+      ['i']+      ["input"]+      (GetOpt.ReqArg Input "FILE")+      "Sets the input file. Use '-' for standard input (STDIN).\nDefault: '-'",+    GetOpt.Option+      ['m']+      ["mode"]+      (GetOpt.ReqArg Mode "MODE")+      "Sets the mode. Must be either 'check' or 'format'.\nDefault: 'format'",+    GetOpt.Option+      ['o']+      ["output"]+      (GetOpt.ReqArg Output "FILE")+      "Sets the output file. Use '-' for standard output (STDOUT).\nDefault: '-'",+    GetOpt.Option+      ['s']+      ["stdin"]+      (GetOpt.ReqArg Stdin "FILE")+      "Sets the path to the input file when using STDIN.\nDefault: '.'"+  ]++fromArguments :: (Exception.MonadThrow m) => [String] -> m [Flag]+fromArguments arguments = do+  let (flgs, args, opts, errs) = GetOpt.getOpt' GetOpt.Permute options arguments+  mapM_ (Exception.throwM . UnexpectedArgument.fromString) args+  mapM_ (Exception.throwM . InvalidOption.fromString) errs+  mapM_ (Exception.throwM . UnknownOption.fromString) opts+  pure flgs
+ source/library/CabalGild/Type/Line.hs view
@@ -0,0 +1,33 @@+module CabalGild.Type.Line where++import qualified CabalGild.Type.Chunk as Chunk+import qualified Data.ByteString as ByteString+import qualified Distribution.Compat.Lens as Lens++data Line = Line+  { indent :: Int,+    chunk :: Chunk.Chunk+  }+  deriving (Eq, Show)++chunkLens :: Lens.Lens' Line Chunk.Chunk+chunkLens f s = fmap (\a -> s {chunk = a}) . f $ chunk s++empty :: Line+empty =+  Line+    { indent = 0,+      chunk = mempty+    }++isEmpty :: Line -> Bool+isEmpty = Chunk.isEmpty . chunk++toByteString :: Line -> ByteString.ByteString+toByteString l =+  if isEmpty l+    then ByteString.empty+    else+      mappend (ByteString.replicate (2 * indent l) 0x20)+        . Chunk.value+        $ chunk l
+ source/library/CabalGild/Type/List.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module CabalGild.Type.List where++import qualified CabalGild.Extra.List as List+import qualified Data.Proxy as Proxy+import qualified Distribution.CabalSpecVersion as CabalSpecVersion+import qualified Distribution.Compat.Newtype as Newtype+import qualified Distribution.FieldGrammar.Newtypes as Newtypes+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Pretty as Pretty+import qualified Text.PrettyPrint as PrettyPrint++newtype List s b a = List+  { unwrap :: Newtypes.List s b a+  }++instance Newtype.Newtype [a] (List s b a) where+  pack = List . Newtype.pack+  unpack = Newtype.unpack . unwrap++instance+  ( Newtype.Newtype a b,+    Parsec.Parsec b,+    Newtypes.Sep s+  ) =>+  Parsec.Parsec (List s b a)+  where+  parsec = List <$> Parsec.parsec++instance+  ( Newtype.Newtype a b,+    Pretty.Pretty b,+    Newtypes.Sep s+  ) =>+  Pretty.Pretty (List s b a)+  where+  pretty = Pretty.prettyVersioned CabalSpecVersion.CabalSpecV1_0+  prettyVersioned v =+    Newtypes.prettySep (Proxy.Proxy @s)+      . fmap (Pretty.prettyVersioned @b v . Newtype.pack)+      . Newtype.unpack++instance+  {-# OVERLAPPING #-}+  ( Newtype.Newtype a b,+    Pretty.Pretty b+  ) =>+  Pretty.Pretty (List Newtypes.CommaFSep b a)+  where+  pretty = Pretty.prettyVersioned CabalSpecVersion.CabalSpecV1_0+  prettyVersioned v =+    ( \xs ->+        if List.compareLength xs 1 == GT && v >= CabalSpecVersion.CabalSpecV2_2+          then PrettyPrint.fsep $ fmap (<> PrettyPrint.comma) xs+          else Newtypes.prettySep (Proxy.Proxy @Newtypes.CommaFSep) xs+    )+      . fmap (Pretty.prettyVersioned @b v . Newtype.pack)+      . Newtype.unpack
+ source/library/CabalGild/Type/Mode.hs view
@@ -0,0 +1,15 @@+module CabalGild.Type.Mode where++import qualified CabalGild.Exception.InvalidMode as InvalidMode+import qualified Control.Monad.Catch as Exception++data Mode+  = Check+  | Format+  deriving (Eq, Show)++fromString :: (Exception.MonadThrow m) => String -> m Mode+fromString s = case s of+  "check" -> pure Check+  "format" -> pure Format+  _ -> Exception.throwM $ InvalidMode.fromString s
+ source/library/CabalGild/Type/Pragma.hs view
@@ -0,0 +1,19 @@+module CabalGild.Type.Pragma where++import qualified Control.Monad as Monad+import qualified Distribution.Compat.CharParsing as CharParsing+import qualified Distribution.FieldGrammar.Newtypes as Newtypes+import qualified Distribution.Parsec as Parsec++newtype Pragma+  = Discover FilePath+  deriving (Eq, Show)++instance Parsec.Parsec Pragma where+  parsec = do+    CharParsing.spaces+    Monad.void $ CharParsing.string "cabal-gild:"+    CharParsing.spaces+    Monad.void $ CharParsing.string "discover"+    CharParsing.skipSpaces1+    Discover . Newtypes.getFilePathNT <$> Parsec.parsec
+ source/library/CabalGild/Type/Set.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module CabalGild.Type.Set where++import qualified CabalGild.Extra.List as List+import qualified Data.Proxy as Proxy+import qualified Data.Set as Set+import qualified Distribution.CabalSpecVersion as CabalSpecVersion+import qualified Distribution.Compat.Newtype as Newtype+import qualified Distribution.FieldGrammar.Newtypes as Newtypes+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Pretty as Pretty+import qualified Text.PrettyPrint as PrettyPrint++newtype Set s b a = Set+  { unwrap :: Newtypes.Set' s b a+  }++instance Newtype.Newtype (Set.Set a) (Set s b a) where+  pack = Set . Newtype.pack+  unpack = Newtype.unpack . unwrap++instance+  ( Newtype.Newtype a b,+    Ord a,+    Parsec.Parsec b,+    Newtypes.Sep s+  ) =>+  Parsec.Parsec (Set s b a)+  where+  parsec = Set <$> Parsec.parsec++instance+  ( Newtype.Newtype a b,+    Pretty.Pretty b,+    Newtypes.Sep s+  ) =>+  Pretty.Pretty (Set s b a)+  where+  pretty = Pretty.prettyVersioned CabalSpecVersion.CabalSpecV1_0+  prettyVersioned v =+    Newtypes.prettySep (Proxy.Proxy @s)+      . fmap (Pretty.prettyVersioned @b v . Newtype.pack)+      . Set.toAscList+      . Newtype.unpack++instance+  {-# OVERLAPPING #-}+  ( Newtype.Newtype a b,+    Pretty.Pretty b+  ) =>+  Pretty.Pretty (Set Newtypes.CommaFSep b a)+  where+  pretty = Pretty.prettyVersioned CabalSpecVersion.CabalSpecV1_0+  prettyVersioned v =+    ( \xs ->+        if List.compareLength xs 1 == GT && v >= CabalSpecVersion.CabalSpecV2_2+          then PrettyPrint.fsep $ fmap (<> PrettyPrint.comma) xs+          else Newtypes.prettySep (Proxy.Proxy @Newtypes.CommaFSep) xs+    )+      . fmap (Pretty.prettyVersioned @b v . Newtype.pack)+      . Set.toAscList+      . Newtype.unpack++instance+  {-# OVERLAPPING #-}+  ( Newtype.Newtype a b,+    Pretty.Pretty b+  ) =>+  Pretty.Pretty (Set Newtypes.CommaVCat b a)+  where+  pretty = Pretty.prettyVersioned CabalSpecVersion.CabalSpecV1_0+  prettyVersioned v =+    ( \xs ->+        if List.compareLength xs 1 == GT && v >= CabalSpecVersion.CabalSpecV2_2+          then PrettyPrint.vcat $ fmap (<> PrettyPrint.comma) xs+          else Newtypes.prettySep (Proxy.Proxy @Newtypes.CommaVCat) xs+    )+      . fmap (Pretty.prettyVersioned @b v . Newtype.pack)+      . Set.toAscList+      . Newtype.unpack
+ source/library/CabalGild/Type/SomeParsecParser.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MonoLocalBinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module CabalGild.Type.SomeParsecParser where++import qualified CabalGild.Type.List as List+import qualified CabalGild.Type.Set as Set+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Pretty as Pretty++data SomeParsecParser+  = forall c s b a.+    (Parsec.Parsec (c s b a), Pretty.Pretty (c s b a)) =>+    SomeParsecParser (Parsec.ParsecParser (c s b a))++list ::+  forall s b a.+  (Parsec.Parsec (List.List s b a), Pretty.Pretty (List.List s b a)) =>+  SomeParsecParser+list = SomeParsecParser $ Parsec.parsec @(List.List s b a)++set ::+  forall s b a.+  (Parsec.Parsec (Set.Set s b a), Pretty.Pretty (Set.Set s b a)) =>+  SomeParsecParser+set = SomeParsecParser $ Parsec.parsec @(Set.Set s b a)
− source/library/VersionInterval.hs
@@ -1,448 +0,0 @@-{-# LANGUAGE BangPatterns #-}---- |------ Author:          Oleg Grenrus <oleg.grenrus@iki.fi>--- SPDX-License-Id: GPL-2.0-or-later------ This module implements a view of a 'VersionRange' as a finite--- list of separated version intervals.------ In conversion from and to 'VersionRange' it makes some effort to--- preserve the caret operator @^>=x.y@.  This constraint a priori--- specifies the same interval as @==x.y.*@, but indicates that newer--- versions could be acceptable (@allow-newer: ^@).-module VersionInterval-  ( -- * Version intervals-    VersionIntervals,--    -- * Conversions-    toVersionIntervals,-    fromVersionIntervals,-    ConversionProblem (..),--    -- ** Normalisation-    normaliseVersionRange,--    -- * Version intervals view-    VersionInterval (..),-    LB (..),-    MB (..),-    UB (..),-    Bound (..),--    -- * For testing-    validVersionInterval,-    validVersionIntervals,-    intersectInterval,-    stage1,-    stage2,-    stage3,-  )-where--import Control.Monad (join)-import Data.List (sortOn)-import Data.List.NonEmpty (NonEmpty (..), cons)-import Data.Maybe (catMaybes)-import Distribution.Types.Version-  ( Version,-    mkVersion,-    validVersion,-    version0,-    versionNumbers,-  )-import Distribution.Types.VersionRange.Internal-  ( VersionRange,-    VersionRangeF (..),-    cataVersionRange,-    earlierVersion,-    intersectVersionRanges,-    majorBoundVersion,-    majorUpperBound,-    noVersion,-    orLaterVersion,-    thisVersion,-    unionVersionRanges,-  )--singleton :: a -> NonEmpty a-singleton x = x :| []------------------------------------------------------------------------------------ Data------------------------------------------------------------------------------------ | A complementary representation of a 'VersionRange'. Instead of a boolean--- version predicate it uses an increasing sequence of non-overlapping,--- non-empty intervals.------ This version is different than in @Cabal-3.8@ and previous,--- as it tries to preserve @^>=@ version ranges under default and @transformCaretUpper@ semantics.--- Slighly simplifying, 'normalizeVersionRange' shouldn't destroy @^>=@ in version range expressions.-newtype VersionIntervals = VersionIntervals [VersionInterval]-  deriving (Eq, Show)---- | Version interval.------ Invariants:------ * Interval is non-empty--- * 'MB' is between 'LB' and 'UB'.-data VersionInterval = VI !LB !MB !UB-  deriving (Eq, Show)---- | Lower bound. For intervals it always exist: 'zeroLB' i.e. @>= 0@.------ All lower bound intervals are inclusive, i.e. @>=v@. @>x.y.z@ is converted into @>=x.y.z.0@.-newtype LB = LB Version-  deriving (Eq, Ord, Show)---- | Upper bound.------ All upper bounds are exclusive, i.e. @<v@. @<=x.y.z@ is converted to @<x.y.z.0@.-data UB-  = -- | upper bound-    UB !Version-  | -- | no upper bound (i.e. infinite)-    NoUB-  deriving (Eq, Ord, Show)---- | Bound variant.-data Bound-  = -- | inclusive: @>=@ or @<=@-    Incl-  | -- | exclusive: @>@ or @<@-    Excl-  deriving (Eq, Ord, Show)---- | Middle bound.-data MB-  = -- | major bound.-    MB !Version-  | -- | no major bound (i.e. infinite)-    NoMB-  deriving (Eq, Ord, Show)---- | @>=0@-zeroLB :: LB-zeroLB = LB version0---- | Whether the version is @0@.-isVersion0 :: Version -> Bool-isVersion0 = (==) version0---- | Versions are not separated type.-succVersion :: Version -> Version-succVersion v = mkVersion (versionNumbers v ++ [0])------------------------------------------------------------------------------------ Stage1----------------------------------------------------------------------------------stage1 :: ([VersionInterval] -> [VersionInterval]) -> VersionRange -> [VersionInterval]-stage1 opt = cataVersionRange alg-  where-    -- version range leafs transform into singleton intervals-    alg (ThisVersionF v) = [VI (LB v) (MB (succVersion v)) (UB (succVersion v))]-    alg (LaterVersionF v) = [VI (LB (succVersion v)) NoMB NoUB]-    alg (OrLaterVersionF v) = [VI (LB v) NoMB NoUB]-    alg (EarlierVersionF v)-      | isVersion0 v = []-      | otherwise = [VI zeroLB (MB v) (UB v)]-    alg (OrEarlierVersionF v) = [VI zeroLB (MB (succVersion v)) (UB (succVersion v))]-    -- \^>= version-range's upper bound should be MajorBound-    alg (MajorBoundVersionF v) = [VI (LB v) (MB (majorUpperBound v)) NoUB]-    -- union: just merge the version intervals-    alg (UnionVersionRangesF v1 v2) = v1 ++ v2-    -- intersection: pairwise intersect. Strip empty intervals. Sort to restore the invariant.-    alg (IntersectVersionRangesF v1 v2) = catMaybes $ intersectInterval <$> opt v1 <*> opt v2------------------------------------------------------------------------------------ Stage2----------------------------------------------------------------------------------stage2 :: [VersionInterval] -> [VersionInterval]-stage2 = sortOn (\(VI l _ _) -> l)------------------------------------------------------------------------------------ Postprocess----------------------------------------------------------------------------------stage2and3 :: [VersionInterval] -> [VersionInterval]-stage2and3 = stage3 . stage2--stage3 :: [VersionInterval] -> [VersionInterval]-stage3 [] = []-stage3 (VI l m u : rest) = stage3go l m u rest--stage3go :: LB -> MB -> UB -> [VersionInterval] -> [VersionInterval]-stage3go l m u [] = [VI l m u]-stage3go l m u (VI l' m' u' : is)-  | l == l' = stage3go l' (unionMB m m') (unionUB u u') is-  | otherwise = case overlap m u l' of-      NoOverlap -> VI l m u : stage3go l' m' u' is-      OverlapU -> viCons (VI l m (trimLB u l')) (stage3go l' m' (unionUB u u') is)-      OverlapM -> stage3go l (unionMB m m') (unionUB u u') is-  where-    viCons :: VersionInterval -> [VersionInterval] -> [VersionInterval]-    viCons i | nonEmptyVI i = (i :)-    viCons _ = id--trimLB :: UB -> LB -> UB-trimLB _ (LB l) = UB l------------------------------------------------------------------------------------ Intersections----------------------------------------------------------------------------------intersectInterval :: VersionInterval -> VersionInterval -> Maybe VersionInterval-intersectInterval (VI xl xm xu) (VI yl ym yu)-  | nonEmptyVI xy = Just xy-  | otherwise = Nothing-  where-    l = intersectLB xl yl-    m = intersectMB xm ym-    u = intersectUB xu yu--    -- make middle bound be between l and u-    m' = rtrimMB (ltrimMB l m) u--    xy = VI l m' u--ltrimMB :: LB -> MB -> MB-ltrimMB _ NoMB = NoMB-ltrimMB (LB l) (MB m) = case compare l m of-  LT -> MB m-  EQ -> MB m-  GT -> MB l--rtrimMB :: MB -> UB -> MB-rtrimMB m NoUB = m-rtrimMB NoMB (UB u) = MB u-rtrimMB (MB m) (UB u) = MB (min m u)--intersectLB :: LB -> LB -> LB-intersectLB (LB v) (LB u) = LB (max v u)--intersectMB :: MB -> MB -> MB-intersectMB NoMB b = b-intersectMB b NoMB = b-intersectMB (MB v) (MB u) = MB (min v u)--intersectUB :: UB -> UB -> UB-intersectUB NoUB b = b-intersectUB b NoUB = b-intersectUB (UB v) (UB u) = UB (min v u)--intersectMBandUB :: MB -> UB -> UB-intersectMBandUB NoMB b = b-intersectMBandUB (MB v) NoUB = UB v-intersectMBandUB (MB v) (UB u) = UB (min v u)------------------------------------------------------------------------------------ Unions----------------------------------------------------------------------------------unionMB :: MB -> MB -> MB-unionMB NoMB _ = NoMB-unionMB _ NoMB = NoMB-unionMB (MB v) (MB u) = MB (max v u)--unionUB :: UB -> UB -> UB-unionUB NoUB _ = NoUB-unionUB _ NoUB = NoUB-unionUB (UB v) (UB u) = UB (max v u)------------------------------------------------------------------------------------ Helpers------------------------------------------------------------------------------------ | Overlaps.-data Overlap-  = -- | no overlap, next interval's @l@ is greater than @u@-    NoOverlap-  | -- | overlaps, next interval's @l@ is less than @m@-    OverlapM-  | -- | overlaps, next interval's @l@ is less than @u@ (but greater than @m@)-    OverlapU-  deriving (Eq, Show)--overlap :: MB -> UB -> LB -> Overlap-overlap _ (UB u) (LB l) | u < l = NoOverlap-overlap (MB m) _ (LB l) | m < l = OverlapU-overlap _ _ _ = OverlapM------------------------------------------------------------------------------------ Invariants------------------------------------------------------------------------------------ | 'VersionIntervals' invariant:------ * all intervals are valid (lower bound is less then upper bound, middle bound is in between)--- * intervals doesn't touch each other (distinct)-validVersionIntervals :: VersionIntervals -> Bool-validVersionIntervals (VersionIntervals intervals) =-  all validVersionInterval intervals-    && all doesNotTouch' (pairs intervals)-  where-    doesNotTouch' :: (VersionInterval, VersionInterval) -> Bool-    doesNotTouch' (VI l m u, VI l' _ _) =-      l < l' && case overlap m u l' of-        NoOverlap -> True-        OverlapM -> False-        OverlapU -> case u of-          NoUB -> True-          UB uv -> case l' of LB lv -> uv == lv--pairs :: [a] -> [(a, a)]-pairs xs = zip xs (drop 1 xs)--validLB :: LB -> Bool-validLB (LB v) = validVersion v--validUB :: UB -> Bool-validUB NoUB = True-validUB (UB v) = validVersion v--validMB :: MB -> Bool-validMB NoMB = True-validMB (MB v) = validVersion v--validVersionInterval :: VersionInterval -> Bool-validVersionInterval i@(VI l m u) = validLB l && validMB m && validUB u && nonEmptyVI i && lbLessThanMB l m && mbLessThanUB m u--mbLessThanUB :: MB -> UB -> Bool-mbLessThanUB (MB m) (UB u) = m <= u-mbLessThanUB NoMB (UB _) = False-mbLessThanUB _ NoUB = True--lbLessThanMB :: LB -> MB -> Bool-lbLessThanMB _ NoMB = True-lbLessThanMB (LB l) (MB m) = l <= m---- Check an interval is non-empty----nonEmptyVI :: VersionInterval -> Bool-nonEmptyVI (VI (LB _) _ NoUB) = True-nonEmptyVI (VI (LB l) _ (UB u)) = l < u------------------------------------------------------------------------------------ Conversions------------------------------------------------------------------------------------ | Convert a 'VersionRange' to a sequence of version intervals.-toVersionIntervals :: VersionRange -> VersionIntervals-toVersionIntervals = VersionIntervals . stage2and3 . stage1 stage2and3--data ConversionProblem-  = IntervalsEmpty-  | OtherConversionProblem-  deriving (Eq, Show)---- | Convert a 'VersionIntervals' value back into a 'VersionRange' expression--- representing the version intervals.-fromVersionIntervals :: VersionIntervals -> Either ConversionProblem VersionRange-fromVersionIntervals (VersionIntervals []) = Right noVersion-fromVersionIntervals (VersionIntervals (x : xs)) =-  case join <$> traverse intervalToVersionRange (preprocess x xs) of-    Just vrs -> Right (foldr1 unionVersionRanges vrs)-    Nothing ->-      Left $-        if all seemsEmpty (x : xs)-          then IntervalsEmpty-          else OtherConversionProblem-  where-    -- we can remove upper bounds, if they touch next interval, and the next interval doesn't have upper bound-    preprocess :: VersionInterval -> [VersionInterval] -> NonEmpty VersionInterval-    preprocess i [] = i :| []-    preprocess i@(VI l m u) (j : js) = case u' of-      NoUB | touchesUB u l' -> cons (VI l m NoUB) js'-      _ -> cons i js'-      where-        js'@(VI l' _ u' :| _) = preprocess j js--    seemsEmpty :: VersionInterval -> Bool-    seemsEmpty (VI l m u) = not (nonEmptyVI (VI l NoMB (intersectMBandUB m u)))--touchesUB :: UB -> LB -> Bool-touchesUB NoUB _ = True-touchesUB (UB u) (LB l) = u >= l--lbToVR :: LB -> VersionRange-lbToVR (LB l) = orLaterVersion l--ubToVR :: UB -> VersionRange -> VersionRange-ubToVR NoUB vr = vr-ubToVR (UB u) vr = intersectVersionRanges vr (earlierVersion u)--mbEqUB :: MB -> UB -> Bool-mbEqUB NoMB NoUB = True-mbEqUB NoMB (UB _) = False-mbEqUB (MB m) (UB u) = m == u-mbEqUB (MB _) NoUB = False---- return the unions of version ranges.-intervalToVersionRange :: VersionInterval -> Maybe (NonEmpty VersionRange)-intervalToVersionRange (VI l m u) | mbEqUB m u = Just (singleton (intervalToVersionRange1 l u))-intervalToVersionRange (VI l m u) = fmap (fmap (ubToVR u)) (intervalToVersionRange2 l m)--intervalToVersionRange1 :: LB -> UB -> VersionRange-intervalToVersionRange1 (LB v) upper' = case upper' of-  NoUB ->-    lowerBound-  UB u-    | succVersion v == u ->-        thisVersion v-  UB u -> withLowerBound (makeUpperBound u)-  where-    lowerBound :: VersionRange-    lowerBound = lbToVR (LB v)--    withLowerBound :: VersionRange -> VersionRange-    withLowerBound vr-      | isVersion0 v = vr-      | otherwise = intersectVersionRanges lowerBound vr--    makeUpperBound :: Version -> VersionRange-    makeUpperBound = earlierVersion--intervalToVersionRange2 :: LB -> MB -> Maybe (NonEmpty VersionRange)-intervalToVersionRange2 (LB l) NoMB = Just (singleton lowerBound)-  where-    lowerBound :: VersionRange-    lowerBound = lbToVR (LB l)-intervalToVersionRange2 (LB l) (MB m)-  | supermajor l == supermajor m =-      go (l :|) (majorUpperBound l)-  | [a, b] <- versionNumbers m,-    let m' = mkVersion [a, b - 1],-    b >= 1,-    m' > l =-      Just $-        ubToVR (UB m') (lbToVR (LB l))-          :| [majorBoundVersion (mkVersion [a, b - 1])]-  | otherwise =-      Nothing-  where-    go :: ([Version] -> NonEmpty Version) -> Version -> Maybe (NonEmpty VersionRange)-    go !acc v = case compare v m of-      LT -> go (snoc acc v) (majorUpperBound v)-      EQ -> Just (fmap majorBoundVersion (acc []))-      GT -> Nothing--    snoc :: ([a] -> c) -> a -> [a] -> c-    snoc xs x = xs . (x :)--    supermajor :: Version -> Int-    supermajor v = case versionNumbers v of-      [] -> -1-      s : _ -> s------------------------------------------------------------------------------------ Normalisation------------------------------------------------------------------------------------ | Convert 'VersionRange' to 'VersionIntervals' and back.-normaliseVersionRange :: VersionRange -> Either ConversionProblem VersionRange-normaliseVersionRange = fromVersionIntervals . toVersionIntervals
− source/test-suite/CabalGild/Test/Golden.hs
@@ -1,87 +0,0 @@-module CabalGild.Test.Golden (tests) where--import CabalGild (cabalGild)-import CabalGild.Monad (runCabalGild)-import CabalGild.Options (defaultOptions)-import qualified Control.Exception as Exception-import qualified Data.ByteString as BS-import qualified Data.ByteString.Char8 as BS8-import qualified Data.Map as Map-import Distribution.Utils.Generic (toUTF8BS)-import System.FilePath ((-<.>), (</>))-import Test.Tasty (TestTree, testGroup)-import qualified Test.Tasty.HUnit as HUnit--tests :: TestTree-tests =-  testGroup-    "tests"-    [ goldenTest' "cabal-fmt",-      goldenTest' "Cabal",-      goldenTest' "Cabal-notab",-      goldenTest' "simple-example",-      goldenTest' "tree-diff",-      goldenTest' "fragment-missing",-      goldenTest' "fragment-empty",-      goldenTest' "fragment-wrong-field",-      goldenTest' "fragment-wrong-type",-      goldenTest' "fragment-multiple",-      goldenTest' "fragment-section",-      goldenTest' "issue69",-      goldenTest' "issue29"-    ]--goldenTest' :: String -> TestTree-goldenTest' n =-  testGroup-    n-    [ HUnit.testCase "successfully formats" $ do-        input <- BS.readFile inputPath-        (output, warnings) <--          either Exception.throwIO pure-            . runCabalGild files defaultOptions-            $ cabalGild inputPath input-        expected <- readFile goldenPath-        let actual = unlines (fmap ("-- " <>) warnings) <> output-        actual HUnit.@?= expected,-      HUnit.testCase "round trips" $ do-        input <- BS.readFile inputPath-        (expected, _) <--          either Exception.throwIO pure-            . runCabalGild files defaultOptions-            $ cabalGild inputPath input-        (actual, _) <--          either Exception.throwIO pure-            . runCabalGild files defaultOptions-            . cabalGild inputPath-            $ toUTF8BS expected-        actual HUnit.@?= expected-    ]-  where-    goldenPath = "fixtures" </> n -<.> "format"-    inputPath = "fixtures" </> n -<.> "cabal"--files :: Map.Map FilePath BS.ByteString-files =-  Map.fromList-    [ p "empty.fragment" "",-      p-        "build-depends.fragment"-        "build-depends: base, doctest >=0.15 && <0.17, QuickCheck >=2.12 && <2.13, simple-example, template-haskell",-      p-        "tested-with.fragment"-        "tested-with: GHC ==8.0.2",-      p-        "common.fragment"-        "common deps\n  build-depends: base, bytestring, containers\n  ghc-options: -Wall",-      p-        "multiple.fragment"-        "build-depends: base\nghc-options: -Wall",-      p ("cbits" </> "header.h") "...",-      p ("cbits" </> "source1.c") "...",-      p ("cbits" </> "source2.c") "...",-      p ("cbits" </> "sub" </> "source3.c") "..."-    ]-  where-    p :: a -> String -> (a, BS.ByteString)-    p x y = (x, BS8.pack y)
− source/test-suite/CabalGild/Test/Interval.hs
@@ -1,387 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module CabalGild.Test.Interval where--import Control.Monad (replicateM)-import Distribution.Parsec (eitherParsec)-import Distribution.Types.Version-  ( Version,-    mkVersion,-    validVersion,-    versionNumbers,-  )-import Distribution.Types.VersionRange-  ( VersionRange,-    VersionRangeF (..),-    anyVersion,-    earlierVersion,-    intersectVersionRanges,-    laterVersion,-    majorBoundVersion,-    notThisVersion,-    orEarlierVersion,-    orLaterVersion,-    projectVersionRange,-    thisVersion,-    unionVersionRanges,-    withinRange,-    withinVersion,-  )-import Distribution.Version (transformCaretUpper)-import Test.QuickCheck (Arbitrary (..), (===))-import qualified Test.QuickCheck as QC-import Test.Tasty (TestTree, testGroup)-import Test.Tasty.HUnit (testCase, (@?=))-import Test.Tasty.QuickCheck (testProperty)-import VersionInterval--tests :: TestTree-tests =-  testGroup-    "version-interval"-    [ testGroup-        "Validity"-        [ testProperty "validVersion" validVersion,-          testProperty "validVersionInterval" validVersionInterval,-          testProperty "validVersionIntervals" $ \vr ->-            let intervals = toVersionIntervals vr-             in QC.counterexample (show intervals) $ validVersionIntervals intervals-        ],-      testGroup-        "VersionInterval"-        [ testProperty "intersect valid" $ \a b ->-            let ab = intersectInterval a b-             in maybe (QC.property True) (\ab' -> QC.counterexample ("intersection: " ++ show ab') $ validVersionInterval ab') ab,-          testProperty "intersect complete" intersectComplete,-          testProperty "intersect complete lax" intersectCompleteLax-        ],-      testGroup-        "stage1"-        [ testProperty "valid" stage1_valid,-          testProperty "complete" stage1_complete,-          testProperty "complete lax" stage1_complete_lax,-          testProperty "valid ex1" $-            stage1_valid-              (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (thisVersion (mkVersion [1]))),-          testProperty "valid ex2" $-            stage1_valid-              (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1]))),-          testProperty "complete ex1" $-            stage1_complete-              (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (thisVersion (mkVersion [6])))-              (mkVersion [6]),-          testProperty "complete ex2" $-            stage1_complete-              (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1]))),-          testProperty "complete lax ex2" $-            stage1_complete_lax-              (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))-        ],-      testGroup-        "stage2"-        [ testProperty "valid" stage2_valid,-          testProperty "involutive" stage2_involutive,-          testProperty "complete" stage2_complete,-          testProperty "complete_lax" stage2_complete_lax-        ],-      testGroup-        "stage3"-        [ testProperty "valid" stage3_valid,-          testProperty "involutive" stage3_involutive,-          testProperty "complete" stage3_complete,-          testProperty "complete_lax" stage3_complete_lax,-          testProperty "complete ex1" $-            stage3_complete-              [VI (LB (mkVersion [0])) (MB (mkVersion [0])) NoUB, VI (LB (mkVersion [0, 0])) NoMB NoUB]-              (mkVersion [0]),-          testProperty "complete lax ex1" $-            stage3_complete_lax-              [VI (LB (mkVersion [0, 0])) (MB (mkVersion [0])) (UB (mkVersion [1])), VI (LB (mkVersion [0, 0, 0])) (MB (mkVersion [1])) (UB (mkVersion [1]))]-              (mkVersion [1]),-          testProperty "valid ex2" $-            stage3_valid-              (stage1 id (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))),-          testProperty "complete ex2" $-            stage3_complete-              (stage1 id (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))),-          testProperty "complete lax ex2" $-            stage3_complete_lax-              (stage1 id (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))),-          testProperty "valid ex3" $-            stage3_valid-              [VI (LB (mkVersion [0, 0])) (MB (mkVersion [0])) NoUB, VI (LB (mkVersion [0, 0])) NoMB NoUB]-        ],-      testGroup-        "normalise"-        [ normaliseExample ">=1 && <2" ">=1 && <2",-          normaliseExample "^>=1" "^>=1",-          normaliseExample "^>=1 || ^>=2" "^>=1 || ^>=2",-          normaliseExample "^>=1.2 || ^>=1.3 || ^>=1.4" "^>=1.2 || ^>=1.3 || ^>=1.4",-          normaliseExample "^>=1.2 || ^>=2.0" "^>=1.2 || ^>=2.0",-          normaliseExample ">=1.2 && <1.4 || ^>=1.4 || ^>=1.5" "^>=1.2 || ^>=1.3 || ^>=1.4 || ^>=1.5",-          normaliseExample ">=1.2 && <2.4 || ^>=2.4 || ^>=2.5" ">=1.2 && <2.5 || ^>=2.5",-          normaliseExample "^>=1.2.0.0 || ^>=1.3.0.0 || ^>=1.4.0.0" "^>=1.2.0.0 || ^>=1.3.0.0 || ^>=1.4.0.0",-          normaliseExample "==3.1.4" "==3.1.4",-          normaliseExample "<3.1.4 || >3.1.4" "<3.1.4 || >=3.1.4.0",-          normaliseExample "^>=1.2 && <2.0 || ^>=2.0" "^>=1.2 || ^>=2.0",-          normaliseExample "^>=1.2 && <3.0 || ^>=2.0" "^>=1.2 || ^>=2.0",-          normaliseExample "^>=1.2 || ^>=2.0 && <3" "^>=1.2 || ^>=2.0",-          normaliseExample "(^>=1.2 || ^>=2.0) && <3" "^>=1.2 && <2.0 || ^>=2.0 && <3",-          normaliseExample "(>=1.2 || >=2.0) && <3" ">=1.2 && <3",-          normaliseExample "<1 || >=1.0" "<1 || >=1.0",-          normaliseExample "<=1 || >=1.0" ">=0",-          normaliseExample ">0 && <0.0" "<0",-          normaliseExample-            "^>=1.5.0.1 || ^>=1.6.0.1 || >=1.9 && <1.13"-            "^>=1.5.0.1 || ^>=1.6.0.1 || ^>=1.9 || ^>=1.10 || ^>=1.11 ||^>=1.12",-          cannotNormaliseExample "^>=0 && >=0.1" IntervalsEmpty,-          testProperty "involutive" normaliseInvolutive,-          testProperty "complete" normaliseComplete,-          testProperty "complete_lax" normaliseCompleteLax,-          testProperty "involutive ex1" $-            normaliseInvolutive $-              intersectVersionRanges (majorBoundVersion (mkVersion [3])) (laterVersion (mkVersion [3]))-        ]-    ]--normaliseExample :: String -> String -> TestTree-normaliseExample input expected = testCase input $ do-  input' <- either fail return $ eitherParsec input-  expected' <- either fail return $ eitherParsec expected--  VersionInterval.normaliseVersionRange input' @?= Right expected'--cannotNormaliseExample :: String -> ConversionProblem -> TestTree-cannotNormaliseExample input problem = testCase ("cannot " ++ input) $ do-  input' <- either fail return $ eitherParsec input--  VersionInterval.normaliseVersionRange input' @?= Left problem------------------------------------------------------------------------------------ Intersect----------------------------------------------------------------------------------intersectComplete :: VersionInterval -> VersionInterval -> Version -> QC.Property-intersectComplete a b v =-  QC.counterexample ("intersection: " ++ show (ab, inA, inB)) $ (inA && inB) === inAB-  where-    ab = intersectInterval a b-    inA = withinInterval v a-    inB = withinInterval v b-    inAB = maybe False (withinInterval v) ab--intersectCompleteLax :: VersionInterval -> VersionInterval -> Version -> QC.Property-intersectCompleteLax a b v =-  QC.counterexample ("intersection: " ++ show (ab, inA, inB)) $ (inA && inB) === inAB-  where-    ab = intersectInterval a b-    inA = withinIntervalLax v a-    inB = withinIntervalLax v b-    inAB = maybe False (withinIntervalLax v) ab------------------------------------------------------------------------------------ Stage 1----------------------------------------------------------------------------------stage1_valid :: VersionRange -> QC.Property-stage1_valid vr = QC.counterexample ("stage1: " ++ show is) $ QC.property $ all validVersionInterval is-  where-    is = stage1 id vr--stage1_complete :: VersionRange -> Version -> QC.Property-stage1_complete vr v = QC.counterexample ("stage1: " ++ show is) $ withinRange v vr === any (withinInterval v) is-  where-    is = stage1 id vr--stage1_complete_lax :: VersionRange -> Version -> QC.Property-stage1_complete_lax vr v = QC.counterexample ("stage1: " ++ show is) $ withinRangeLax v vr === any (withinIntervalLax v) is-  where-    is = stage1 id vr------------------------------------------------------------------------------------ Stage 2----------------------------------------------------------------------------------stage2_valid :: [VersionInterval] -> QC.Property-stage2_valid is' = QC.counterexample ("stage2: " ++ show is) $ QC.property $ all validVersionInterval is-  where-    is = stage2 is'--stage2_involutive :: [VersionInterval] -> QC.Property-stage2_involutive is' = is1 === is2-  where-    is1 = stage2 is'-    is2 = stage2 is1--stage2_complete :: [VersionInterval] -> Version -> QC.Property-stage2_complete is' v = QC.counterexample ("stage2: " ++ show is) $ any (withinInterval v) is' === any (withinInterval v) is-  where-    is = stage2 is'--stage2_complete_lax :: [VersionInterval] -> Version -> QC.Property-stage2_complete_lax is' v = QC.counterexample ("stage2: " ++ show is) $ any (withinIntervalLax v) is' === any (withinIntervalLax v) is-  where-    is = stage2 is'------------------------------------------------------------------------------------ Stage 3----------------------------------------------------------------------------------stage3_valid :: [VersionInterval] -> QC.Property-stage3_valid is' = QC.counterexample ("stage3: " ++ show is) $ QC.property $ all validVersionInterval is-  where-    is = stage3 (stage2 is')--stage3_involutive :: [VersionInterval] -> QC.Property-stage3_involutive is' = is1 === is2-  where-    is1 = stage3 (stage2 is')-    is2 = stage3 is1--stage3_complete :: [VersionInterval] -> Version -> QC.Property-stage3_complete is' v = QC.counterexample ("stage3: " ++ show is) $ any (withinInterval v) is' === any (withinInterval v) is-  where-    is = stage3 (stage2 is')--stage3_complete_lax :: [VersionInterval] -> Version -> QC.Property-stage3_complete_lax is' v = QC.counterexample ("stage3: " ++ show is) $ any (withinIntervalLax v) is' === any (withinIntervalLax v) is-  where-    is = stage3 (stage2 is')------------------------------------------------------------------------------------ Normalise----------------------------------------------------------------------------------normaliseInvolutive :: VersionRange -> QC.Property-normaliseInvolutive vr = vr1 === vr2-  where-    vr1 = VersionInterval.normaliseVersionRange vr-    vr2 = VersionInterval.normaliseVersionRange =<< vr1--normaliseComplete :: VersionRange -> Version -> QC.Property-normaliseComplete vr v = case VersionInterval.normaliseVersionRange vr of-  Left _ -> QC.property True-  Right vr' -> QC.counterexample ("normalised: " ++ show vr') $ withinRange v vr === withinRange v vr'--normaliseCompleteLax :: VersionRange -> Version -> QC.Property-normaliseCompleteLax vr v = case VersionInterval.normaliseVersionRange vr of-  Left _ -> QC.property True-  Right vr' -> QC.counterexample ("normalised: " ++ show vr') $ withinRangeLax v vr === withinRangeLax v vr'------------------------------------------------------------------------------------ Predicates----------------------------------------------------------------------------------withinInterval :: Version -> VersionInterval -> Bool-withinInterval v (VI l m u) = viGreater l && viLessM m && viLess u-  where-    viGreater (LB v') = v >= v'--    viLessM NoMB = True-    viLessM (MB v') = v < v'--    viLess NoUB = True-    viLess (UB v') = v < v'--withinIntervalLax :: Version -> VersionInterval -> Bool-withinIntervalLax v (VI l _ u) = viGreater l && viLess u-  where-    viGreater (LB v') = v >= v'--    viLess NoUB = True-    viLess (UB v') = v < v'--withinRangeLax :: Version -> VersionRange -> Bool-withinRangeLax v vr = withinRange v (transformCaretUpper vr)------------------------------------------------------------------------------------ QC instances----------------------------------------------------------------------------------instance Arbitrary Version where-  arbitrary =-    QC.oneof-      [ mkVersion <$> replicateM d vDigit-        | d <- [1 .. 4]-      ]-    where-      vDigit :: QC.Gen Int-      vDigit = QC.elements [0 .. 9]--  shrink v =-    [ mkVersion v'-      | v' <- shrink (versionNumbers v),-        not (null v')-    ]--instance Arbitrary VersionRange where-  arbitrary =-    let intToDouble :: Int -> Double-        intToDouble = fromIntegral-     in QC.sized $ genVersionRange . round . logBase 2 . intToDouble . max 1--  shrink vr = case projectVersionRange vr of-    LaterVersionF v -> laterVersion <$> shrink v-    OrLaterVersionF v -> orLaterVersion <$> shrink v-    EarlierVersionF v -> earlierVersion <$> shrink v-    OrEarlierVersionF v -> orEarlierVersion <$> shrink v-    ThisVersionF v -> thisVersion <$> shrink v-    MajorBoundVersionF v -> majorBoundVersion <$> shrink v-    UnionVersionRangesF l r -> l : r : fmap (uncurry unionVersionRanges) (shrink (l, r))-    IntersectVersionRangesF l r -> l : r : fmap (uncurry intersectVersionRanges) (shrink (l, r))--genVersionRange :: Int -> QC.Gen VersionRange-genVersionRange n-  | n <= 1 =-      QC.oneof-        [ pure anyVersion,-          thisVersion <$> arbitrary,-          notThisVersion <$> arbitrary,-          laterVersion <$> arbitrary,-          earlierVersion <$> arbitrary,-          orLaterVersion <$> arbitrary,-          orEarlierVersion <$> arbitrary,-          withinVersion <$> arbitrary,-          majorBoundVersion <$> arbitrary-        ]-  | otherwise = do-      l <- QC.chooseInt (1, n - 1)-      let r = n - l-      QC.oneof-        [ unionVersionRanges <$> genVersionRange l <*> genVersionRange r,-          intersectVersionRanges <$> genVersionRange l <*> genVersionRange r-        ]--instance Arbitrary VersionInterval where-  arbitrary = QC.suchThat (VI <$> arbitrary <*> arbitrary <*> arbitrary) validVersionInterval--  shrink (VI l m u) =-    [ vi-      | (l', m', u') <- shrink (l, m, u),-        let vi = VI l' m' u',-        validVersionInterval vi-    ]--instance Arbitrary LB where-  arbitrary = LB <$> arbitrary-  shrink (LB v) = LB <$> shrink v--instance Arbitrary UB where-  arbitrary =-    QC.oneof-      [ pure NoUB,-        UB <$> arbitrary-      ]--  shrink NoUB = []-  shrink (UB v) = NoUB : map UB (shrink v)--instance Arbitrary MB where-  arbitrary =-    QC.oneof-      [ pure NoMB,-        MB <$> arbitrary-      ]--  shrink NoMB = []-  shrink (MB v) = NoMB : map MB (shrink v)
source/test-suite/Main.hs view
@@ -1,12 +1,844 @@-import qualified CabalGild.Test.Golden-import qualified CabalGild.Test.Interval-import qualified Test.Tasty+{-# LANGUAGE GeneralizedNewtypeDeriving #-} +import qualified CabalGild.Class.MonadLog as MonadLog+import qualified CabalGild.Class.MonadRead as MonadRead+import qualified CabalGild.Class.MonadWalk as MonadWalk+import qualified CabalGild.Class.MonadWrite as MonadWrite+import qualified CabalGild.Extra.String as String+import qualified CabalGild.Main as Gild+import qualified Control.Monad.Catch as Exception+import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.Except as ExceptT+import qualified Control.Monad.Trans.RWS as RWST+import qualified Data.ByteString as ByteString+import qualified Data.Either as Either+import qualified Data.Function as Function+import qualified Data.Functor.Identity as Identity+import qualified Data.Map as Map+import qualified GHC.Stack as Stack+import qualified System.FilePath as FilePath+import qualified Test.Hspec as Hspec+ main :: IO ()-main =-  Test.Tasty.defaultMain $-    Test.Tasty.testGroup-      "cabal-gild"-      [ CabalGild.Test.Golden.tests,-        CabalGild.Test.Interval.tests-      ]+main = Hspec.hspec . Hspec.parallel . Hspec.describe "cabal-gild" $ do+  Hspec.it "shows the help" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" ["--help"])+            (Map.empty, Map.empty)+            Map.empty+    a `Hspec.shouldSatisfy` Either.isLeft+    w `Hspec.shouldNotSatisfy` null+    s `Hspec.shouldBe` Map.empty++  Hspec.it "shows the version" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" ["--version"])+            (Map.empty, Map.empty)+            Map.empty+    a `Hspec.shouldSatisfy` Either.isLeft+    w `Hspec.shouldNotSatisfy` null+    s `Hspec.shouldBe` Map.empty++  Hspec.it "reads from an input file" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" ["--input", "input.cabal"])+            (Map.singleton (Just "input.cabal") (String.toUtf8 ""), Map.empty)+            Map.empty+    a `Hspec.shouldBe` Right ()+    w `Hspec.shouldBe` []+    s `Hspec.shouldSatisfy` Map.member Nothing++  Hspec.it "writes to an output file" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" ["--output", "output.cabal"])+            (Map.singleton Nothing (String.toUtf8 ""), Map.empty)+            Map.empty+    a `Hspec.shouldBe` Right ()+    w `Hspec.shouldBe` []+    s `Hspec.shouldSatisfy` Map.member (Just "output.cabal")++  Hspec.it "succeeds when checking formatted input" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" ["--mode", "check"])+            (Map.singleton Nothing (String.toUtf8 ""), Map.empty)+            Map.empty+    a `Hspec.shouldBe` Right ()+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "fails when checking unformatted input" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" ["--mode", "check"])+            (Map.singleton Nothing (String.toUtf8 "fail:yes"), Map.empty)+            Map.empty+    a `Hspec.shouldSatisfy` Either.isLeft+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "succeeds with empty input" $ do+    expectGilded+      ""+      ""++  Hspec.it "removes extra blank space" $ do+    expectGilded+      "\t\r\n \r\n"+      ""++  Hspec.it "formats a comment" $ do+    expectGilded+      "-- c"+      "-- c\n"++  Hspec.it "keeps a blank comment" $ do+    expectGilded+      "--"+      "--\n"++  Hspec.it "formats multiple comments" $ do+    expectGilded+      "-- c\n-- d"+      "-- c\n-- d\n"++  Hspec.it "removes blank lines between comments" $ do+    expectGilded+      "-- c\n\n-- d"+      "-- c\n-- d\n"++  Hspec.it "does not require a space after the comment start" $ do+    expectGilded+      "--c"+      "--c\n"++  Hspec.it "leaves leading blank space in comments" $ do+    expectGilded+      "--\t c"+      "--\t c\n"++  Hspec.it "trims trailing blank space from comments" $ do+    expectGilded+      "-- c\t \n"+      "-- c\n"++  Hspec.it "normalizes Windows line endings in comments" $ do+    expectGilded+      "-- c\r\n"+      "-- c\n"++  Hspec.it "formats a field without a value" $ do+    expectGilded+      "f:"+      "f:\n"++  Hspec.it "formats a field with a value" $ do+    expectGilded+      "f: 1"+      "f: 1\n"++  Hspec.it "does not require spaces before a field's value" $ do+    expectGilded+      "f:1"+      "f: 1\n"++  Hspec.it "allows spaces after a field's name" $ do+    expectGilded+      "f :1"+      "f: 1\n"++  Hspec.it "formats multiple fields" $ do+    expectGilded+      "f: 1\ng: 2"+      "f: 1\ng: 2\n"++  Hspec.it "formats a field with hung values" $ do+    expectGilded+      "f: 1\n 2"+      "f:\n  1\n  2\n"++  Hspec.it "formats a field with nested values" $ do+    expectGilded+      "f:\n 1\n 2"+      "f:\n  1\n  2\n"++  Hspec.it "puts a line after a field with multiple values" $ do+    expectGilded+      "f: 1\n 2\ng: 3"+      "f:\n  1\n  2\n\ng: 3\n"++  Hspec.it "does not pu a line before a field with multiple values" $ do+    expectGilded+      "f: 1\ng: 2\n 3"+      "f: 1\ng:\n  2\n  3\n"++  Hspec.it "converts field names to lowercase" $ do+    expectGilded+      "F: 1"+      "f: 1\n"++  Hspec.it "does not convert field values to lowercase" $ do+    expectGilded+      "f: A"+      "f: A\n"++  Hspec.it "normalizes spaces within field values" $ do+    expectGilded+      "f:\n a\n\n  b"+      "f:\n  a\n  b\n"++  Hspec.it "formats a section" $ do+    expectGilded+      "s"+      "s\n"++  Hspec.it "puts a line after a section" $ do+    expectGilded+      "s\nf: 1"+      "s\n\nf: 1\n"++  Hspec.it "puts a line before a section" $ do+    expectGilded+      "f: 1\ns"+      "f: 1\n\ns\n"++  Hspec.it "formats a section with an argument" $ do+    expectGilded+      "s a"+      "s a\n"++  Hspec.it "formats a section with multiple arguments" $ do+    expectGilded+      "s a b"+      "s a b\n"++  Hspec.it "formats a section with a quoted argument" $ do+    expectGilded+      "s \"a\""+      "s \"a\"\n"++  Hspec.it "formats a section with an operator argument" $ do+    expectGilded+      "s !"+      "s !\n"++  Hspec.it "converts section names to lowercase" $ do+    expectGilded+      "S"+      "s\n"++  Hspec.it "does not convert section arguments to lowercase" $ do+    expectGilded+      "s A"+      "s A\n"++  Hspec.it "formats nested sections" $ do+    -- Note that the nested section does not have an extra blank line before+    -- it.+    expectGilded+      "s\n t"+      "s\n  t\n"++  Hspec.it "formats a section with a field" $ do+    expectGilded+      "s\n f: 1"+      "s\n  f: 1\n"++  Hspec.it "formats a section with multiple fields" $ do+    expectGilded+      "s\n f: 1\n g: 2"+      "s\n  f: 1\n  g: 2\n"++  Hspec.it "correctly indents a section containing a field with multiple values" $ do+    expectGilded+      "s\n f:\n  1\n  2"+      "s\n  f:\n    1\n    2\n"++  Hspec.it "formats a comment before a field" $ do+    expectGilded+      "-- c\nf: 1"+      "-- c\nf: 1\n"++  Hspec.it "formats a comment after a field" $ do+    expectGilded+      "f: 1\n-- c"+      "f: 1\n-- c\n"++  Hspec.it "formats a comment before a field's value" $ do+    expectGilded+      "f:\n -- c\n 1"+      "f:\n  -- c\n  1\n"++  Hspec.it "formats a comment in a field's value" $ do+    expectGilded+      "f:\n 1\n -- c\n 2"+      "f:\n  1\n  -- c\n  2\n"++  Hspec.it "formats a comment after a field's value" $ do+    expectGilded+      "f:\n 1\n -- c"+      "f: 1\n-- c\n"++  Hspec.it "formats a comment after a field with multiple values" $ do+    expectGilded+      "f: 1\n 2\n-- c"+      "f:\n  1\n  2\n\n-- c\n"++  Hspec.it "formats a comment before a section" $ do+    expectGilded+      "-- c\ns"+      "-- c\ns\n"++  Hspec.it "formats a comment after a section" $ do+    expectGilded+      "s\n-- c"+      "s\n\n-- c\n"++  Hspec.it "correctly indents a comment in a section" $ do+    expectGilded+      "s\n -- c\n f: 1"+      "s\n  -- c\n  f: 1\n"++  Hspec.describe "description" $ do+    -- These tests apply to other "free text" fields as well. The description+    -- field is just a representative example.++    Hspec.describe "< 3.0" $ do+      -- These may look surprising, but they're the expected behavior.+      -- <https://github.com/haskell/cabal/issues/5938>++      Hspec.it "collapses extra blank lines" $ do+        expectGilded+          "description:\n 1\n\n 2"+          "description:\n  1\n  2\n"++      Hspec.it "trims leading blank space" $ do+        expectGilded+          "description:\n 1\n  2"+          "description:\n  1\n  2\n"++    Hspec.describe ">= 3.0" $ do+      Hspec.it "keeps one extra blank line" $ do+        expectGilded+          "cabal-version: 3.0\ndescription:\n 1\n\n 2"+          "cabal-version: 3.0\ndescription:\n  1\n\n  2\n"++      Hspec.it "keeps two extra blank lines" $ do+        -- Although Haddock will collapse these, Cabal itself keeps them.+        expectGilded+          "cabal-version: 3.0\ndescription:\n 1\n\n\n 2"+          "cabal-version: 3.0\ndescription:\n  1\n\n\n  2\n"++      Hspec.it "indents second line past first when nested" $ do+        expectGilded+          "cabal-version: 3.0\ndescription:\n 1\n  2"+          "cabal-version: 3.0\ndescription:\n  1\n   2\n"++      Hspec.it "indents first line past second when nested" $ do+        expectGilded+          "cabal-version: 3.0\ndescription:\n  1\n 2"+          "cabal-version: 3.0\ndescription:\n   1\n  2\n"++      Hspec.it "does not indent first line when hung" $ do+        expectGilded+          "cabal-version: 3.0\ndescription: 1\n 2"+          "cabal-version: 3.0\ndescription:\n  1\n  2\n"++      Hspec.it "indents second line past first when hung" $ do+        expectGilded+          "cabal-version: 3.0\ndescription: 1\n              2"+          "cabal-version: 3.0\ndescription:\n  1\n   2\n"++      Hspec.it "indents third line (but not first) past second when hung" $ do+        -- If the first line of the value is on the same line as the name, then+        -- it should never be indented.+        expectGilded+          "cabal-version: 3.0\ndescription: 1\n 2\n  3"+          "cabal-version: 3.0\ndescription:\n  1\n  2\n   3\n"++      Hspec.it "treats tabs the same as spaces" $ do+        -- Yes, each tab only counts as one space.+        expectGilded+          "cabal-version: 3.0\ndescription:\n 1\n\t2"+          "cabal-version: 3.0\ndescription:\n  1\n  2\n"++      Hspec.it "does not insert extra blank lines before comments" $ do+        expectGilded+          "cabal-version: 3.0\ndescription:\n -- c\n 1\n -- d\n 2"+          "cabal-version: 3.0\ndescription:\n  -- c\n  1\n  -- d\n  2\n"++      Hspec.it "does not consider comments for indentation" $ do+        expectGilded+          "cabal-version: 3.0\ndescription:\n  1\n -- c\n    2"+          "cabal-version: 3.0\ndescription:\n  1\n  -- c\n    2\n"++  Hspec.it "properly formats conditionals" $ do+    expectGilded+      "if ! impl ( ghc >= 9.8 )"+      "if !impl(ghc >= 9.8)\n"++  Hspec.describe "license-files" $ do+    -- These tests apply to other "list" fields as well. The license-files+    -- field is just a representative example.++    Hspec.it "removes duplicates" $ do+      expectGilded+        "license-files: f f"+        "license-files: f\n"++    Hspec.it "sorts unquoted" $ do+      expectGilded+        "license-files: g f"+        "license-files:\n  f\n  g\n"++    Hspec.it "sorts mixed" $ do+      expectGilded+        "license-files: \"g\" f"+        "license-files:\n  f\n  g\n"++    Hspec.it "sorts quoted" $ do+      expectGilded+        "license-files: \"g\" \"f\""+        "license-files:\n  f\n  g\n"++    Hspec.it "sorts comma-separated" $ do+      expectGilded+        "license-files: g, f"+        "license-files:\n  f\n  g\n"++    Hspec.it "collects comments at the top" $ do+      -- This isn't ideal, but keeping comments "close" to their original+      -- identifier is very difficult.+      expectGilded+        "license-files:\n -- c\n g\n -- d\n f"+        "license-files:\n  -- c\n  -- d\n  f\n  g\n"++    Hspec.it "leaves invalid fields alone" $ do+      -- This field value is valid in general. Cabal will reject it because the+      -- license-files field has special rules. Perhaps the user is trying to+      -- format something other than a package description. Or maybe they just+      -- made a typo. Either way, we can leave it alone.+      expectGilded+        "license-files: , f ,"+        "license-files: , f ,\n"++  Hspec.it "sorts tested-with" $ do+    expectGilded+      "tested-with: GHC == 9.8.1 , GHC == 9.6.4"+      "tested-with:\n  ghc ==9.6.4\n  ghc ==9.8.1\n"++  Hspec.it "sorts data-files" $ do+    expectGilded+      "data-files: g f"+      "data-files:\n  f\n  g\n"++  Hspec.it "sorts extra-source-files" $ do+    expectGilded+      "extra-source-files: g f"+      "extra-source-files:\n  f\n  g\n"++  Hspec.it "sorts extra-tmp-files" $ do+    expectGilded+      "extra-tmp-files: g f"+      "extra-tmp-files:\n  f\n  g\n"++  Hspec.it "sorts extra-doc-files" $ do+    expectGilded+      "extra-doc-files: g f"+      "extra-doc-files:\n  f\n  g\n"++  Hspec.it "sorts exposed-modules" $ do+    expectGilded+      "library\n exposed-modules: N M"+      "library\n  exposed-modules:\n    M\n    N\n"++  Hspec.it "sorts reexported-modules" $ do+    expectGilded+      "library\n reexported-modules: p:M4 as M5, M2 as M3, q:M6, M1"+      "library\n  reexported-modules:\n    M1,\n    M2 as M3,\n    p:M4 as M5,\n    q:M6\n"++  Hspec.it "sorts signatures" $ do+    expectGilded+      "library\n signatures: N M"+      "library\n  signatures:\n    M\n    N\n"++  Hspec.it "sorts build-tools" $ do+    expectGilded+      "library\n build-tools: q , p == 1"+      "library\n  build-tools:\n    p ==1,\n    q >=0\n"++  Hspec.it "adds a trailing comma to build-tools when possible" $ do+    expectGilded+      "cabal-version: 2.2\nlibrary\n build-tools: p == 1, q == 2"+      "cabal-version: 2.2\n\nlibrary\n  build-tools:\n    p ==1,\n    q ==2,\n"++  Hspec.it "does not add a trailing comma to build-tools with one element" $ do+    expectGilded+      "cabal-version: 2.2\nlibrary\n build-tools: p"+      "cabal-version: 2.2\n\nlibrary\n  build-tools: p >=0\n"++  Hspec.it "sorts build-tool-depends" $ do+    expectGilded+      "library\n build-tool-depends: q:d , p:c == 1"+      "library\n  build-tool-depends:\n    p:c ==1,\n    q:d\n"++  Hspec.it "sorts pkgconfig-depends" $ do+    -- This unusual version range format appears to be a quirk of Cabal's+    -- parser specifically for pkg-config.+    expectGilded+      "library\n pkgconfig-depends: q , p == 1"+      "library\n  pkgconfig-depends:\n    p >=1 && <=1,\n    q\n"++  Hspec.it "sorts frameworks" $ do+    expectGilded+      "library\n frameworks: b a"+      "library\n  frameworks:\n    a\n    b\n"++  Hspec.it "sorts extra-framework-dirs" $ do+    expectGilded+      "library\n extra-framework-dirs: e d"+      "library\n  extra-framework-dirs:\n    d\n    e\n"++  Hspec.it "sorts asm-sources" $ do+    expectGilded+      "library\n asm-sources: g f"+      "library\n  asm-sources:\n    f\n    g\n"++  Hspec.it "sorts cmm-sources" $ do+    expectGilded+      "library\n cmm-sources: g f"+      "library\n  cmm-sources:\n    f\n    g\n"++  Hspec.it "sorts c-sources" $ do+    expectGilded+      "library\n c-sources: g f"+      "library\n  c-sources:\n    f\n    g\n"++  Hspec.it "sorts cxx-sources" $ do+    expectGilded+      "library\n cxx-sources: g f"+      "library\n  cxx-sources:\n    f\n    g\n"++  Hspec.it "sorts js-sources" $ do+    expectGilded+      "library\n js-sources: g f"+      "library\n  js-sources:\n    f\n    g\n"++  Hspec.it "sorts other-modules" $ do+    expectGilded+      "library\n other-modules: N M"+      "library\n  other-modules:\n    M\n    N\n"++  Hspec.it "sorts virtual-modules" $ do+    expectGilded+      "library\n virtual-modules: N M"+      "library\n  virtual-modules:\n    M\n    N\n"++  Hspec.it "sorts autogen-modules" $ do+    expectGilded+      "library\n autogen-modules: N M"+      "library\n  autogen-modules:\n    M\n    N\n"++  Hspec.it "sorts other-languages" $ do+    expectGilded+      "library\n other-languages: b a"+      "library\n  other-languages:\n    a\n    b\n"++  Hspec.it "sorts default-extensions" $ do+    expectGilded+      "library\n default-extensions: b a"+      "library\n  default-extensions:\n    a\n    b\n"++  Hspec.it "sorts other-extensions" $ do+    expectGilded+      "library\n other-extensions: b a"+      "library\n  other-extensions:\n    a\n    b\n"++  Hspec.it "sorts extensions" $ do+    expectGilded+      "library\n extensions: b a"+      "library\n  extensions:\n    a\n    b\n"++  Hspec.it "sorts build-depends" $ do+    expectGilded+      "library\n build-depends: q , p == 1"+      "library\n  build-depends:\n    p ==1,\n    q\n"++  Hspec.it "adds a trailing comma to build-depends when possible" $ do+    expectGilded+      "cabal-version: 2.2\nlibrary\n build-depends: p == 1, q == 2"+      "cabal-version: 2.2\n\nlibrary\n  build-depends:\n    p ==1,\n    q ==2,\n"++  Hspec.it "does not add a trailing comma to build-depends with one element" $ do+    expectGilded+      "cabal-version: 2.2\nlibrary\n build-depends: p"+      "cabal-version: 2.2\n\nlibrary\n  build-depends: p\n"++  Hspec.it "removes duplicate options" $ do+    -- This is kind of silly because there's only one possible foreign library+    -- option.+    expectGilded+      "foreign-library x\n options: standalone standalone"+      "foreign-library x\n  options: standalone\n"++  Hspec.it "does not sort hs-source-dirs" $ do+    expectGilded+      "library\n hs-source-dirs: b a"+      "library\n  hs-source-dirs:\n    b\n    a\n"++  Hspec.it "does not sort code-generators" $ do+    expectGilded+      "test-suite x\n code-generators: b, a"+      "test-suite x\n  code-generators:\n    b,\n    a\n"++  Hspec.it "adds a trailing comma to code-generators when possible" $ do+    expectGilded+      "cabal-version: 2.2\ntest-suite x\n code-generators: a, b"+      "cabal-version: 2.2\n\ntest-suite x\n  code-generators:\n    a,\n    b,\n"++  Hspec.it "does not add a trailing comma to code-generators with one element" $ do+    expectGilded+      "cabal-version: 2.2\ntest-suite x\n code-generators: a"+      "cabal-version: 2.2\n\ntest-suite x\n  code-generators: a\n"++  Hspec.it "does not sort cpp-options" $ do+    expectGilded+      "library\n cpp-options: b a"+      "library\n  cpp-options:\n    b\n    a\n"++  Hspec.it "does not sort asm-options" $ do+    expectGilded+      "library\n asm-options: b a"+      "library\n  asm-options:\n    b\n    a\n"++  Hspec.it "does not sort cmm-options" $ do+    expectGilded+      "library\n cmm-options: b a"+      "library\n  cmm-options:\n    b\n    a\n"++  Hspec.it "does not sort cc-options" $ do+    expectGilded+      "library\n cc-options: b a"+      "library\n  cc-options:\n    b\n    a\n"++  Hspec.it "does not sort cxx-options" $ do+    expectGilded+      "library\n cxx-options: b a"+      "library\n  cxx-options:\n    b\n    a\n"++  Hspec.it "does not sort ld-options" $ do+    expectGilded+      "library\n ld-options: b a"+      "library\n  ld-options:\n    b\n    a\n"++  Hspec.it "does not sort hsc2hs-options" $ do+    expectGilded+      "library\n hsc2hs-options: b a"+      "library\n  hsc2hs-options:\n    b\n    a\n"++  Hspec.it "sorts extra-libraries" $ do+    expectGilded+      "library\n extra-libraries: b a"+      "library\n  extra-libraries:\n    a\n    b\n"++  Hspec.it "sorts extra-libraries-static" $ do+    expectGilded+      "library\n extra-libraries-static: b a"+      "library\n  extra-libraries-static:\n    a\n    b\n"++  Hspec.it "sorts extra-ghci-libraries" $ do+    expectGilded+      "library\n extra-ghci-libraries: b a"+      "library\n  extra-ghci-libraries:\n    a\n    b\n"++  Hspec.it "sorts extra-bundled-libraries" $ do+    expectGilded+      "library\n extra-bundled-libraries: b a"+      "library\n  extra-bundled-libraries:\n    a\n    b\n"++  Hspec.it "sorts extra-library-flavours" $ do+    expectGilded+      "library\n extra-library-flavours: b a"+      "library\n  extra-library-flavours:\n    a\n    b\n"++  Hspec.it "sorts extra-dynamic-library-flavours" $ do+    expectGilded+      "library\n extra-dynamic-library-flavours: b a"+      "library\n  extra-dynamic-library-flavours:\n    a\n    b\n"++  Hspec.it "sorts extra-lib-dirs" $ do+    expectGilded+      "library\n extra-lib-dirs: g f"+      "library\n  extra-lib-dirs:\n    f\n    g\n"++  Hspec.it "sorts extra-lib-dirs-static" $ do+    expectGilded+      "library\n extra-lib-dirs-static: g f"+      "library\n  extra-lib-dirs-static:\n    f\n    g\n"++  Hspec.it "sorts include-dirs" $ do+    expectGilded+      "library\n include-dirs: g f"+      "library\n  include-dirs:\n    f\n    g\n"++  Hspec.it "sorts includes" $ do+    expectGilded+      "library\n includes: g f"+      "library\n  includes:\n    f\n    g\n"++  Hspec.it "sorts autogen-includes" $ do+    expectGilded+      "library\n autogen-includes: g f"+      "library\n  autogen-includes:\n    f\n    g\n"++  Hspec.it "sorts install-includes" $ do+    expectGilded+      "library\n install-includes: g f"+      "library\n  install-includes:\n    f\n    g\n"++  Hspec.it "sorts mixins" $ do+    expectGilded+      "library\n mixins: q (M, N as O), p"+      "library\n  mixins:\n    p,\n    q (M, N as O)\n"++  Hspec.it "does not sort ghc-options" $ do+    expectGilded+      "library\n ghc-options: b a"+      "library\n  ghc-options:\n    b\n    a\n"++  Hspec.it "does not sort ghcjs-options" $ do+    expectGilded+      "library\n ghcjs-options: b a"+      "library\n  ghcjs-options:\n    b\n    a\n"++  Hspec.it "does not sort ghc-prof-options" $ do+    expectGilded+      "library\n ghc-prof-options: b a"+      "library\n  ghc-prof-options:\n    b\n    a\n"++  Hspec.it "does not sort ghcjs-prof-options" $ do+    expectGilded+      "library\n ghcjs-prof-options: b a"+      "library\n  ghcjs-prof-options:\n    b\n    a\n"++  Hspec.it "does not sort ghc-shared-options" $ do+    expectGilded+      "library\n ghc-shared-options: b a"+      "library\n  ghc-shared-options:\n    b\n    a\n"++  Hspec.it "does not sort ghcjs-shared-options" $ do+    expectGilded+      "library\n ghcjs-shared-options: b a"+      "library\n  ghcjs-shared-options:\n    b\n    a\n"++  Hspec.it "sorts setup-depends" $ do+    expectGilded+      "custom-setup\n setup-depends: b, a"+      "custom-setup\n  setup-depends:\n    a,\n    b\n"++  Hspec.it "discovers an exposed module" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" [])+            ( Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules:"),+              Map.singleton (FilePath.combine "." ".") ["M.hs"]+            )+            Map.empty+    a `Hspec.shouldBe` Right ()+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.singleton Nothing (String.toUtf8 "library\n  -- cabal-gild: discover .\n  exposed-modules: M\n")++  Hspec.it "discovers an other module" $ do+    let (a, s, w) =+          runTest+            (Gild.mainWith "" [])+            ( Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n other-modules:"),+              Map.singleton (FilePath.combine "." ".") ["M.hs"]+            )+            Map.empty+    a `Hspec.shouldBe` Right ()+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.singleton Nothing (String.toUtf8 "library\n  -- cabal-gild: discover .\n  other-modules: M\n")++expectGilded :: (Stack.HasCallStack) => String -> String -> Hspec.Expectation+expectGilded input expected = do+  let (a, s, w) =+        runTest+          (Gild.mainWith "" [])+          (Map.singleton Nothing (String.toUtf8 input), Map.empty)+          Map.empty+  a `Hspec.shouldBe` Right ()+  w `Hspec.shouldBe` []+  actual <- case Map.toList s of+    [(Nothing, x)] -> pure x+    _ -> fail $ "impossible: " <> show s+  actual `Hspec.shouldBe` String.toUtf8 expected+  -- After formatting, the output should not change if we format it again.+  expectStable actual++expectStable :: (Stack.HasCallStack) => ByteString.ByteString -> Hspec.Expectation+expectStable input = do+  let (a, s, w) =+        runTest+          (Gild.mainWith "" [])+          (Map.singleton Nothing input, Map.empty)+          Map.empty+  a `Hspec.shouldBe` Right ()+  w `Hspec.shouldBe` []+  output <- case Map.toList s of+    [(Nothing, x)] -> pure x+    _ -> fail $ "impossible: " <> show s+  output `Hspec.shouldBe` input++newtype Problem = Problem+  { unProblem :: Exception.SomeException+  }+  deriving (Show)++instance Eq Problem where+  (==) = Function.on (==) show++type Test = TestT Identity.Identity++runTest :: Test a -> R -> S -> (Either E a, S, W)+runTest t r = Identity.runIdentity . RWST.runRWST (ExceptT.runExceptT $ runTestT t) r++type E = Problem++type R = (S, Map.Map FilePath [FilePath])++type S = Map.Map (Maybe FilePath) ByteString.ByteString++type W = [String]++newtype TestT m a = TestT+  { runTestT :: ExceptT.ExceptT E (RWST.RWST R W S m) a+  }+  deriving (Applicative, Functor, Monad)++instance (Monad m) => MonadLog.MonadLog (TestT m) where+  log = TestT . Trans.lift . RWST.tell . pure++instance (Monad m) => MonadRead.MonadRead (TestT m) where+  read k = do+    m <- TestT . Trans.lift . RWST.asks $ Map.lookup k . fst+    case m of+      Nothing -> Exception.throwM . userError $ "read " <> show k+      Just x -> pure x++instance (Monad m) => Exception.MonadThrow (TestT m) where+  throwM = TestT . ExceptT.throwE . Problem . Exception.toException++instance (Monad m) => MonadWalk.MonadWalk (TestT m) where+  walk p = do+    m <- TestT . Trans.lift . RWST.asks $ Map.lookup p . snd+    case m of+      Nothing -> Exception.throwM . userError $ "walk " <> show p+      Just x -> pure x++instance (Monad m) => MonadWrite.MonadWrite (TestT m) where+  write k = TestT . Trans.lift . RWST.modify . Map.insert k