ben-0.6.6ubuntu1/0000755000000000000000000000000012235730034010500 5ustar ben-0.6.6ubuntu1/bin/0000755000000000000000000000000012233757266011266 5ustar ben-0.6.6ubuntu1/bin/ben.mlp0000644000000000000000000000300612233757266012543 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_frontend let static_frontends = [ @STATIC_FRONTENDS@ ] let () = List.iter register_frontend static_frontends let () = Printexc.catch main () ben-0.6.6ubuntu1/COPYING0000644000000000000000000010357112233757266011560 0ustar This program is released under the AGPL version 3 (see the text below) with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are 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. 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. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. 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 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 work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero 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 Affero 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 Affero 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 Affero 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. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. 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 AGPL, see . ben-0.6.6ubuntu1/_tags0000644000000000000000000000021712233757266011536 0ustar <**/*>: debug, thread <**/*.ml*>: annot : for-pack(Benlib) : use_libbenl <**/*.{byte,native}>: use_libbenl ben-0.6.6ubuntu1/templates/0000755000000000000000000000000012235731006012476 5ustar ben-0.6.6ubuntu1/templates/ubuntu.ml0000644000000000000000000000260012235731006014350 0ustar open Printf open Xhtml.M let a_link url text = a ~a:[a_href (uri_of_string url)] [pcdata text] let page ~title ~subtitle ~headers ~body ~footer = let headers = (meta ~content:"text/html;charset=utf-8" ~a:[a_http_equiv "Content-Type"] ()) :: (link ~a:[a_rel [`Stylesheet]; a_href "media/revamp.css"] ()) :: (link ~a:[a_rel [`Stylesheet]; a_href "media/styles.css"] ()) :: headers in html ~a:[a_xmlns `W3_org_1999_xhtml] (head (Xhtml.M.title (pcdata title)) headers ) (Xhtml.M.body ~a:[a_class ["debian"]] [ h1 ~a:[a_id "title"] [pcdata "Ubuntu Release Management"]; h2 ~a:[a_id "subtitle"] subtitle; div ~a:[a_id "body"] body; div ~a:[a_id "footer"] footer ]) open Template let () = Benl_templates.register_template { name = "Ubuntu"; page; intro = []; pts = (fun ~src -> sprintf "https://launchpad.net/ubuntu/+source/%s" src); changelog = (fun ~letter ~src ~ver -> sprintf "http://changelogs.ubuntu.com/changelogs/%s/%s_%s/changelog" letter src ver); buildd = (fun ~src ~ver -> sprintf "https://launchpad.net/ubuntu/+source/%s/%s" src ver); buildds = (fun ~srcs -> None); bugs = (fun ~src -> sprintf "https://bugs.launchpad.net/ubuntu/+source/%s" src); critical_bugs = (fun ~srcs -> None); msg_id = (fun ~mid -> sprintf "http://mid.gmane.org/%s" mid); } ben-0.6.6ubuntu1/templates/debian.ml0000644000000000000000000000324512233760077014266 0ustar open Printf open Xhtml.M let href uri = a_href (uri_of_string uri) let a_link url text = a ~a:[a_href (uri_of_string url)] [pcdata text] let page ~title ~subtitle ~headers ~body ~footer = let headers = (meta ~content:"text/html;charset=utf-8" ~a:[a_http_equiv "Content-Type"] ()) :: (link ~a:[a_rel [`Stylesheet]; a_href "media/revamp.css"] ()) :: (link ~a:[a_rel [`Stylesheet]; a_href "media/styles.css"] ()) :: headers in html ~a:[a_xmlns `W3_org_1999_xhtml] (head (Xhtml.M.title (pcdata title)) headers ) (Xhtml.M.body ~a:[a_class ["debian"]] [ h1 ~a:[a_id "title"] [pcdata "Transition tracker"]; h2 ~a:[a_id "subtitle"] subtitle; div ~a:[a_id "body"] body; div ~a:[a_id "footer"] footer ]) open Template let () = Benl_templates.register_template { name = "Simple"; page; intro = []; pts = (fun ~src -> sprintf "http://packages.qa.debian.org/%s" src); changelog = (fun ~letter ~src ~ver -> sprintf "http://packages.debian.org/changelog:%s" src); buildd = (fun ~src ~ver -> sprintf "https://buildd.debian.org/status/package.php?p=%s" src); buildds = (fun ~srcs -> let srcs = String.concat "," srcs in Some (sprintf "https://buildd.debian.org/status/package.php?p=%s&compact=compact" srcs)); bugs = (fun ~src -> sprintf "http://bugs.debian.org/%s" src); critical_bugs = (fun ~srcs -> let srcs = String.concat ";src=" srcs in Some (sprintf "http://bugs.debian.org/cgi-bin/pkgreport.cgi?sev-inc=serious;sev-inc=grave;sev-inc=critical;src=%s" srcs)); msg_id = (fun ~mid -> sprintf "http://lists.debian.org/%s" mid); } ben-0.6.6ubuntu1/templates/debianrt.ml0000644000000000000000000000407712233760077014640 0ustar open Printf open Xhtml.M let href uri = a_href (uri_of_string uri) let a_link url text = a ~a:[a_href (uri_of_string url)] [pcdata text] let page ~title ~subtitle ~headers ~body ~footer = let headers = (meta ~content:"text/html;charset=utf-8" ~a:[a_http_equiv "Content-Type"] ()) :: (link ~a:[a_rel [`Stylesheet]; a_href "media/revamp.css"] ()) :: (link ~a:[a_rel [`Stylesheet]; a_href "media/styles.css"] ()) :: headers in html ~a:[a_xmlns `W3_org_1999_xhtml] (head (Xhtml.M.title (pcdata title)) headers ) (Xhtml.M.body ~a:[a_class ["debian"]] [ h1 ~a:[a_id "title"] [a_link "http://release.debian.org/" "Debian Release Management"]; h2 ~a:[a_id "subtitle"] subtitle; div ~a:[a_id "body"] body; div ~a:[a_id "footer"] footer ]) open Template let () = Benl_templates.register_template { name = "Debian"; page; intro = [ b [ a_link "http://wiki.debian.org/Teams/ReleaseTeam/Transitions" "Transition documentation" ]; br (); b [ a_link "http://bugs.debian.org/cgi-bin/pkgreport.cgi?users=release.debian.org@packages.debian.org;tag=transition" "Bugs tagged \"transition\"" ]; br (); br (); ]; pts = (fun ~src -> sprintf "http://packages.qa.debian.org/%s" src); changelog = (fun ~letter ~src ~ver -> sprintf "http://packages.debian.org/changelog:%s" src); buildd = (fun ~src ~ver -> sprintf "https://buildd.debian.org/status/package.php?p=%s" src); buildds = (fun ~srcs -> let srcs = String.concat "," srcs in Some (sprintf "https://buildd.debian.org/status/package.php?p=%s&compact=compact" srcs)); bugs = (fun ~src -> sprintf "http://bugs.debian.org/%s" src); critical_bugs = (fun ~srcs -> let srcs = String.concat ";src=" srcs in Some (sprintf "http://bugs.debian.org/cgi-bin/pkgreport.cgi?sev-inc=serious;sev-inc=grave;sev-inc=critical;src=%s" srcs)); msg_id = (fun ~mid -> sprintf "http://lists.debian.org/%s" mid); } ben-0.6.6ubuntu1/META0000644000000000000000000000025512233760077011163 0ustar name = "ben" version = "0.6" requires="unix,pcre,ocamlgraph,tyxml" description = "Libraries for Debian maintainers" archive(byte) = "benl.cma" archive(native) = "benl.cmxa" ben-0.6.6ubuntu1/debian/0000755000000000000000000000000012256133667011736 5ustar ben-0.6.6ubuntu1/debian/libben-ocaml.install.in0000644000000000000000000000011312233757266016254 0ustar @OCamlStdlibDir@/ben/META @OCamlStdlibDir@/ben/benl.cma @OCamlDllDir@/*.so ben-0.6.6ubuntu1/debian/copyright0000644000000000000000000000474112233760077013673 0ustar Packaged-By: Stéphane Glondu Packaged-Date: Tue, 20 Sep 2011 20:24:13 +0200 Files: * Copyright: © 2009-2013 Stéphane Glondu © 2010-2013 Mehdi Dogguy © 2013 Johannes Schauer License: AGPL-3+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version, with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. . 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 Affero General Public License for more details. . You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Files: lib/benl_dpkg.c Copyright: © 1995 Ian Jackson License: GPL-2+ This is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This 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. . The complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-2'. Files: media/debian.png Copyright: © 1999 Software in the Public Interest License: Debian Open Use Logo License This logo or a modified version may be used by anyone to refer to the Debian project, but does not indicate endorsement by the project. . Note: we would appreciate that you make the image a link to http://www.debian.org/ if you use it on a web page. Files: media/revamp.css Copyright © 2007-2011 Stefano Zacchiroli © 2007 Dan Callahan © 2007 Enrico Tassi License: GPL-3+ The complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-3'. . Original file can be found at . ben-0.6.6ubuntu1/debian/ben.doc-base0000644000000000000000000000055712233757266014112 0ustar Document: ben Title: Reference Manual of Ben Author: Mehdi Dogguy and Stéphane Glondu Abstract: This manual describes what ben is and how it can be used to generate transition monitors and trackers. Section: Programming/OCaml Format: HTML Index: /usr/share/doc/ben/refman.html Files: /usr/share/doc/ben/*.html Format: Text Files: /usr/share/doc/ben/refman.txt.gz ben-0.6.6ubuntu1/debian/changelog0000644000000000000000000001113112256133667013605 0ustar ben (0.6.6ubuntu2) trusty; urgency=medium * Rebuild for ocaml-4.01. -- Matthias Klose Mon, 23 Dec 2013 22:22:47 +0000 ben (0.6.6ubuntu1) trusty; urgency=low * Resynchronise with Debian. Remaining changes: - Show Ubuntu logo. - Allow configs to request the Packages/Sources files are not redownloaded (so that we can download once and for all at the start). * Add an Ubuntu template. * Tolerate templates with buildds or critical_bugs entries that return None. -- Colin Watson Mon, 04 Nov 2013 14:41:20 +0000 ben (0.6.6) unstable; urgency=low * Simplify computation of dependency levels by using ocamlgraph's SCC module * Use uninstallable:yes instead of debcheck:uninstallable * Add back edos-debcheck pseudo-field for compatibility with the setup at release.debian.org * Update copyright information -- Stéphane Glondu Sun, 18 Aug 2013 14:55:29 +0200 ben (0.6.5) unstable; urgency=low [ Stéphane Glondu ] * Upload to unstable * Migrate to dose-debcheck (Closes: #707599) - the pseudo-header "edos-debcheck" has been renamed into "debcheck"; existing .ben files using it might need update * Add visual indication for sources that build "MA: same" binaries (Closes: #711908) * New computation of dependency levels, which should give better results when there are cycles or several connected components * Drop dependency to ocamlgraph (no longer used) * Update Vcs-* * Bump Standards-Version to 3.9.4 (no changes) [ Mehdi Dogguy ] * Fix changelog urls * Only warn instead of exiting when a .ben file is incorrect * Better error reporting wrt. configuration files * Separator between comparison operators and versions can be empty * Handle architecture restrictions in packages' relationships * Command-line flags --use-cache and --cache-file are now available for all frontends. [ Johannes Schauer ] * Allow creation of a cache in download (Closes: #714703) -- Stéphane Glondu Thu, 15 Aug 2013 23:57:07 +0200 ben (0.6.4) experimental; urgency=low * Pass -thread to ocamldoc when generating API documentation. * Pass needed flags to dh_ocaml so that Ben doesn't define modules Benl_error and Benl_templates. * Provide minimal documentation about HTML templates for Ben, and how to build them. -- Mehdi Dogguy Sun, 06 Jan 2013 16:28:59 +0100 ben (0.6.3) experimental; urgency=low * Fix a typo in Makefile which made the build system try a native build on architectures where dynlink.cmxa is not available. -- Mehdi Dogguy Mon, 08 Oct 2012 21:47:47 +0200 ben (0.6.2) experimental; urgency=low * Add missing dependency on curl. Thanks to Luca Falavigna for spotting it! * Make libjs-jquery a strong dependency and put a symlink in media (Closes: #680273) * Add docbook-xsl to Build-Depends (needed on Ubuntu to build the documentation). Thanks to Iain Lane! * Add a basic template mechanism - HTML templates are put under /usr/lib/ben/templates - Add --template command line option to "ben monitor" and "ben tracker" - Add "template" and "base-url" as configuration keys for "ben tracker" * The "media" directory is taken care by Ben directly now when "monitor" and "tracker" are used (See commit a5c222db6990da84ec30e4878d53bbda6). * Fix dependencies of the library in the META file. -- Mehdi Dogguy Sat, 06 Oct 2012 22:46:05 +0200 ben (0.6.1ubuntu4) saucy; urgency=low * Rebuild for new OCaml ABIs. -- Colin Watson Fri, 10 May 2013 08:02:58 +0100 ben (0.6.1ubuntu3) saucy; urgency=low * Rebuild for new OCaml ABIs. -- Colin Watson Thu, 09 May 2013 23:12:10 +0100 ben (0.6.1ubuntu2) quantal; urgency=low * Update Vcs-* for Ubuntu * Add Build-Depends on docbook-xsl as otherwise xsltproc tries to download DTD from the internet. -- Iain Lane Wed, 04 Jul 2012 20:50:37 +0100 ben (0.6.1ubuntu1) quantal; urgency=low * Apply Ubuntu customisations - Link to Launchpad instead of Debian resources - Show Ubuntu logo - Allow configs to request the Packages/Sources files are not redownloaded (so that we can download once and for all at the start) * Recommend edos-debcheck -- Iain Lane Wed, 04 Jul 2012 17:48:11 +0100 ben (0.6.1) experimental; urgency=low [ Stéphane Glondu ] * Initial packaging [ Mehdi Dogguy ] * Initial Release (Closes: #679547) -- Stéphane Glondu Sun, 01 Jul 2012 22:10:36 +0200 ben-0.6.6ubuntu1/debian/ben.docs0000644000000000000000000000003712233757266013356 0ustar doc/refman.html doc/refman.txt ben-0.6.6ubuntu1/debian/ben.manpages0000644000000000000000000000001212233757266014212 0ustar doc/ben.1 ben-0.6.6ubuntu1/debian/compat0000644000000000000000000000000212233757266013136 0ustar 8 ben-0.6.6ubuntu1/debian/ben.examples0000644000000000000000000000001312233757266014236 0ustar examples/* ben-0.6.6ubuntu1/debian/control0000644000000000000000000000521512233765774013351 0ustar Source: ben Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Debian OCaml Maintainers Uploaders: Stéphane Glondu , Mehdi Dogguy Build-Depends: debhelper (>= 8), dh-ocaml (>= 0.9.6~), graphviz, ocaml-findlib, menhir, libpcre-ocaml-dev, libocamlgraph-ocaml-dev, libfileutils-ocaml-dev, libtyxml-ocaml-dev (>= 2.1-1~), libpostgresql-ocaml-dev, ocaml-nox (>= 3.11.1-3~), asciidoc, docbook-xml, docbook-xsl, libxml2-utils, xsltproc, source-highlight Standards-Version: 3.9.4 Section: ocaml Homepage: http://ben.debian.net XS-Debian-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/ben.git XS-Debian-Vcs-Git: git://anonscm.debian.org/collab-maint/ben.git Vcs-Browser: https://code.launchpad.net/~ubuntu-transition-trackers/ubuntu-transition-tracker/ben Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-transition-trackers/ubuntu-transition-tracker/ben Package: libben-ocaml-dev Architecture: any Depends: ${ocaml:Depends}, ${shlibs:Depends}, ${misc:Depends} Provides: ${ocaml:Provides} Recommends: ocaml-findlib Description: OCaml libraries for Debian maintainers (development package) This package contains miscellaneous OCaml libraries to make the life of an OCaml-aware Debian package maintainer easier. . This package contains development files of the library. Package: libben-ocaml Architecture: any Depends: ${ocaml:Depends}, ${shlibs:Depends}, ${misc:Depends} Provides: ${ocaml:Provides} Description: OCaml libraries for Debian maintainers (runtime package) This package contains miscellaneous OCaml libraries to make the life of an OCaml-aware Debian package maintainer easier. . This package contains the shared runtime stub libraries. Package: ben Architecture: any Depends: ${ocaml:Depends}, ${shlibs:Depends}, bzip2, curl, libjs-jquery, ${misc:Depends} Provides: ${ocaml:Provides} Enhances: devscripts Recommends: dose-debcheck Description: toolbox for Debian maintainers This is a collection of useful tools that Debian maintainers can use to make their packaging work easier. They all work with regular Debian package list files, and should be useful for Debian derivatives as well. This package ships a single executable, "ben", with the following subcommands: * download: download a set of package list files from a mirror * monitor: monitor the status of a set of packages across several architectures (useful for transitions) * query: query packages using their metadata (similar to grep-dctrl, but uses a dedicated query language) * tracker: frontend to multiple monitors ben-0.6.6ubuntu1/debian/ben.install0000644000000000000000000000006312233760077014065 0ustar usr/bin usr/lib/ben/templates media usr/share/ben ben-0.6.6ubuntu1/debian/libben-ocaml-dev.install.in0000644000000000000000000000013212233757266017031 0ustar @OCamlStdlibDir@/ben/*.cm{o,i,x}* @OCamlStdlibDir@/ben/*.{o,a} @OCamlStdlibDir@/ben/*.ml* ben-0.6.6ubuntu1/debian/ben.links0000644000000000000000000000011512233760077013535 0ustar /usr/share/javascript/jquery/jquery.min.js usr/share/ben/media/jquery.min.js ben-0.6.6ubuntu1/debian/rules0000755000000000000000000000127712233760077013021 0ustar #!/usr/bin/make -f # -*- makefile -*- include /usr/share/ocaml/ocamlvars.mk export DESTDIR := $(CURDIR)/debian/tmp export OCAMLFIND_DESTDIR := $(DESTDIR)$(OCAML_STDLIB_DIR) # FIXME: xhtmlpretty.cmxa is only available on natdynlink architectures ifeq ($(OCAML_NATDYNLINK),yes) export OCAMLBEST := native else export OCAMLBEST := byte endif %: dh $@ --with ocaml .PHONY: override_dh_auto_install override_dh_auto_install: mkdir -p $(OCAMLFIND_DESTDIR) $(DESTDIR)$(OCAML_DLL_DIR) $(MAKE) install PREFIX=/usr .PHONY: override_dh_install override_dh_install: dh_install --fail-missing -X.so.owner .PHONY: override_dh_ocaml override_dh_ocaml: dh_ocaml --nodefined-map ben:Benl_error,Benl_templates ben-0.6.6ubuntu1/debian/source/0000755000000000000000000000000012233757266013240 5ustar ben-0.6.6ubuntu1/debian/source/format0000644000000000000000000000001512233757266014447 0ustar 3.0 (native) ben-0.6.6ubuntu1/debian/libben-ocaml-dev.ocamldoc0000644000000000000000000000024312233760077016534 0ustar # OCamldoc generated documentation -thread -package unix -package pcre -package ocamlgraph -package tyxml -package fileutils -package threads -package postgresql ben-0.6.6ubuntu1/doc/0000755000000000000000000000000012235730676011261 5ustar ben-0.6.6ubuntu1/doc/refman.txt0000644000000000000000000002726312233760077013300 0ustar Ben's reference manual ====================== :Author: Mehdi Dogguy and Stéphane Glondu :Date: May 30, 2012 :Revision: 0.6 This manual is free software; you may redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This 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. A copy of the GNU General Public License is available as /usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution or on the World Wide Web at the GNU web site. You can also obtain it by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. WARNING: This document is still work in progress! :numbered!: [abstract] Introduction ------------ _Ben_ is the name of a set of utilities written in http://caml.inria.fr[OCaml] and available through the `ben` command. The major feature of _Ben_ is to provide a full featured transition tracker to follow the evolution of a set of packages in the Debian archive. The aim of this document is to describe the features of _Ben_ and its configuration. :numbered: Getting the source code ----------------------- _Ben_ is maintained in a Git repository available online at http://anonscm.debian.org/gitweb/?p=collab-maint/ben.git. Getting the sources is as simple as: [source,shell] ---- git clone git://anonscm.debian.org/collab-maint/ben.git ---- The source tree has a `debian/` directory. It is a native Debian package, so you can use the standard building tools in order to build it. Query language -------------- The main feature of _Ben_ is a transition tracker. The transition tracker selects a set of affected packages and computes a state for each of them. There exist already various ways to do that. One solution would be to use the http://packages.debian.org/sid/dctrl-tools[dctrl-tools]. We chose to make our own language. This allows us to perform more fine-grained queries, optimize queries and extend the query language easily. A ben query is decribed by the following http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form[BNF] formulae: ::= "true" | "false" | "!" /* Boolean negation */ | "|" /* Boolean OR operator */ | "&" /* Boolean AND operator */ | "(" ")" /*set 2*/ | "~" "/" "/" | "~" '"' '"' | "source" | '"' '"' ::= '.' ::= '<<' | '<' | '>' | '>>' | '=' | '<=' | '>=' The first rules are the usual boolean constants and operators. The sixth rule is useful to group queries and override boolean operators' priotity. The second set are the various type of queries implemented to match against different criteria. It matches against a package field (in lowercase). We believe the syntax of queries is easy to grasp. Nonetheless, here are some exemples: - `.build-depends ~ /lib.*ocaml-dev/` + This query matches all packages that build-depend on a package whose name matches the http://perldoc.perl.org/perlre.html[Perl regular expression] `lib.*ocaml-dev`. - `.depends ~ "libapt-pkg4.12"` + This one is simpler than the first one in the sense that `libapt-pkg4.12` is considered as a plain string and not a regular experssion. IMPORTANT: Note the symbols around the selectors: /.../ for regular expressions and "..." for plain strings. WARNING: Packages fields may contain a list of values comma-separated. _Ben_ splits the list before looking with "..." for a match. - `>= "3.0"` + The query `>= "3.0"` matches all packages with a version number equal to or higher than "3.0". - `source` + This matches all source packages. Now that the concept of query is explained, we will focus on other parts of _Ben_. We will see how we can use the queries for each frontend. Frontends --------- _Ben_ is a set of utilities available through the `ben` command. Each utility is called a _frontend_ and there are four: * `download` * `query` * `monitor` * `tracker` All frontends share a set of options and each one defines its own specific set. The shared set of command-line options is: [options="header"] |==================================================================== | Option | Action | --dry-run | Dry run | --quiet\|-q | Quiet mode | --verbose | Verbose mode | --mirror uri | Package mirror to use | --mirror-binaries uri | Package mirror to use for binaries | --mirror-sources uri | Package mirror to use for sources | --areas a,... | Areas to consider (comma separated) | --archs a,... | Architectures to consider (comma separated) | --suite a | Suite | --cache-dir d | Path to cache dir | --cache-file\|-C f | Specify the name of the cache file | --use-cache | Use cache whenever possible | --config\|-c c | Config file |===================================================================== The rest of this section describes each frontend. download ~~~~~~~~ This frontend is the simplest one as it has no command-line options, except the shared ones. It downloads all Sources.bz2 files and all Packages.bz2 files for selected architectures and areas. You may invoke it by running: $ ben download [options] The requested files will be downloaded in $BEN_CACHE_DIR, if set, or in the current directory. NOTE: `ben download` doesn't read `ben.cache` files yet. query ~~~~~ This utility is pretty much like http://man.cx/grep-dctrl(1)[`grep-dctrl(1)`]. Given a list of Packages or Sources files, it performs a query and outputs the result. Using it is as simple as shown below: $ ben query ".package ~ /gentoo/" Packages Other valid uses: $ zcat Packages.gz | ben query ".package ~ /gentoo/" - [...] $ ben query ".package ~ /gentoo/" Packages_foo.gz Packages_bar.bz2 [...] $ ben query ".package ~ /gentoo/" monitor.cache [...] Just like `grep-dctrl(1)`, `ben query` has a simple mechanism to filter its output. Using the command-line option `-s`, one can specify a comma-separated list of fields that will be shown for matching paragraphs. $ ben query ".package ~ /gentoo/" -s Package,Version ... monitor ~~~~~~~ The `monitor` fontend builds a monitoring page for a transition. A transition is decribed by three queries: * `is_affected`: matches source packages that are part of this transition; this query is evaluated against all source and binary packages and, for binary packages, their source package is picked; * `is_good`: matches binary packages that are considered to be ready (fixed) for this transition; * `is_bad`: matches binary packages that are considered to be broken (not fixed) for this transition. Note that some packages can be neither good nor bad. For example, there are many packages that build-depend on some library but do not link against it. Thus, they do not need any dependency on the library at runtime. An example of a complete description of a transition is: is_affected = .build-depends ~ /libicu-dev/; is_good = .depends ~ /libicu44/; is_bad = .depends ~ /libicu42/; There are other optional fields: * `title` + This puts a nice title in the HTML page. * `notes` + This can be used to put remarks about the transition or notes about the status of some packages or the whole transition. + + _Ben_ recognizes some special texts and turns them into links. The following formats are recognized: [options="header"] |========================================================================= | Original text | Result | pts:ocaml | http://packages.qa.debian.org/ocaml[pts:ocaml] | buildd:ocaml | http://buildd.debian.org/ocaml[buildd:ocaml] | #123456 | http://bugs.debian.org/123456[#123456] | | http://lists.debian.org/msg-id | $$http://example.com$$ | http://example.com |========================================================================= `monitor` understands the following list of command-line options: [options="header"] |========================================================================= | Option | Action | --run-debcheck | Run dose-debcheck and add virtual `.uninstallable` field | --use-projectb | Get package lists from Projectb database | --color | Color if text output | --text | Select text output format | --html | Select HTML output format | --output file | Select output file | -o file | (Same as above) | --template template | Select an HTML template |========================================================================= tracker ~~~~~~~ This frontend uses `monitor` to generate a summary page about all known transitions. An example of such summary can be found at http://release.debian.org/transitions/. `tracker` has a notion of `profiles` that gives a hint on the actual state of the transition. The default profiles are: * `planned` for known planned transitions or requested but not processed or acknowledged yet; * `permanent` is a special profile made to keep an eye on some set of packages, not necessarily a transition; * `ongoing` for the actual list of (known) on-going transitions; * `finished` has a list of some transitions that are almost finished (e.g. new binary packages migrated but old binary packages left in testing to not decrease installability, or a finished transition with a number of still broken packages in testing). Technically, each `profile` is a sub-directory of the global config directoryfootnote:[http://release.debian.org/transitions/config/]. The latter can be specified by a command-line option. By default, `tracker` looks for a directory named `config` which should contain a file named `global.conf`, unless otherwise told. It reads data (`.ben` files) from the `config` directory and outputs the result in the `base` directory. `tracker` has the following command-line options: [options="header"] |==================================================================== | Option | Action | --base\|-b [dir] | Specifies the "base" directory | --config-dir\|-cd [dir] | Location of ben trackers | --transition\|-t [profile/transition] | Generate only that tracker page | --update\|-u | Updates cache files | --use-projectb | Get package lists from Projectb database | --template template | Select an HTML template |==================================================================== HTML Templates -------------- Ben has a simple templating mechanism to generate customized HTML pages. Templates are loaded dynamically when `monitor` or `tracker` frontends are used. When none specified, Ben chooses to load the Debian template. You can write your own HTML template for Ben. All you have to do is to install the package `libben-ocaml-dev` which provides the Ben library. We recommend users to start from an existing template to ease the task. You can compile a template (e.g. named `foo`) by running the following command: $ ocamlbuild -pkg ben foo.cmxs NOTE: .cmxs files are native dynamically loadable shared modules. If you're building on a bytecode-only architecture, you should build a `foo.cma` instead. If your template needs a CSS (Cascading Style Sheets) or some images, you should install them under `/usr/share/ben/media`. Reporting issues ---------------- _Ben_ doesn't have a bug tracker yet. If you experience a bug or if you're looking for some help, feel free to contact us directly. ben-0.6.6ubuntu1/doc/ben.10000644000000000000000000000650412204136721012077 0ustar '\" t .\" Title: ben .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 .\" Date: 08/18/2013 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" .TH "BEN" "1" "08/18/2013" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ben \- transition tracker manager .SH "SYNOPSIS" .sp \fBben\fR \fIFRONTEND\fR [\fIOPTIONS\fR] .sp \fBben\fR [\-h|\-help|\-\-help] .SH "DESCRIPTION" .sp The ben(1) command is a set of utilities written in OCaml\&. It provides a full featured transition tracker to follow the evolution of a set of packages in the Debian\(cqs archive\&. All frontends share a common list of options described below\&. .SH "OPTIONS" .PP \fB\-\-dry\-run\fR .RS 4 Dry run .RE .PP \fB\-\-quiet|\-q\fR .RS 4 Quiet mode .RE .PP \fB\-\-verbose\fR .RS 4 Verbose mode .RE .PP \fB\-\-mirror uri\fR .RS 4 Package mirror to use .RE .PP \fB\-\-mirror\-binaries uri\fR .RS 4 Package mirror to use for binaries .RE .PP \fB\-\-mirror\-sources uri\fR .RS 4 Package mirror to use for sources .RE .PP \fB\-\-areas a,\&...\fR .RS 4 Areas to consider (comma separated) .RE .PP \fB\-\-archs a,\&...\fR .RS 4 Architectures to consider (comma separated) .RE .PP \fB\-\-suite a\fR .RS 4 Suite .RE .PP \fB\-\-cache\-dir d\fR .RS 4 Path to cache dir .RE .PP \fB\-\-cache\-file|\-C f\fR .RS 4 Specify the name of the cache file .RE .PP *\-\-use\-cache .RS 4 Use cache whenever possible .RE .PP \fB\-\-config|\-c c\fR .RS 4 Config file .RE .SH "FRONTENDS" .PP \fBdownload\fR .RS 4 has no command\-line options, except the shared ones\&. It downloads all Sources\&.bz2 files and all Packages\&.bz2 files for selected architectures and areas\&. .RE .PP \fBquery\fR .RS 4 This utility is pretty much like grep\-dctrl(1)\&. Given a list of Packages or Sources files, it performs a query and outputs the result\&. .RE .PP \fBmonitor\fR .RS 4 The frontend monitor builds a monitor page for a transition that is described by few criteria (the list of affected packages, a description of good package and the description of a broken package)\&. .RE .PP \fBtracker\fR .RS 4 This frontend uses the monitor to generate a summary page about all known transitions\&. An example of such summary can be found at http://release\&.debian\&.org/transitions/\&. .RE .sp For more information about ben\(cqs frontends, please refer to the reference manual\&. .SH "AUTHOR" .sp Ben was originally written by Stéphane Glondu\&. .SH "RESOURCES" .sp Main web site: http://ben\&.debian\&.net/ ben-0.6.6ubuntu1/doc/refman.html0000644000000000000000000011433612204136722013413 0ustar Ben’s reference manual

This manual is free software; you may redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This 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.

A copy of the GNU General Public License is available as /usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution or on the World Wide Web at the GNU web site. You can also obtain it by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Warning This document is still work in progress!

Introduction

Ben is the name of a set of utilities written in OCaml and available through the ben command. The major feature of Ben is to provide a full featured transition tracker to follow the evolution of a set of packages in the Debian archive.

The aim of this document is to describe the features of Ben and its configuration.

1. Getting the source code

Ben is maintained in a Git repository available online at http://anonscm.debian.org/gitweb/?p=collab-maint/ben.git. Getting the sources is as simple as:

git clone git://anonscm.debian.org/collab-maint/ben.git

The source tree has a debian/ directory. It is a native Debian package, so you can use the standard building tools in order to build it.

2. Query language

The main feature of Ben is a transition tracker. The transition tracker selects a set of affected packages and computes a state for each of them. There exist already various ways to do that. One solution would be to use the dctrl-tools. We chose to make our own language. This allows us to perform more fine-grained queries, optimize queries and extend the query language easily.

A ben query is decribed by the following BNF formulae:

<query> ::= "true"
          | "false"
          | "!" <query>            /* Boolean negation     */
          | <query> "|" <query>    /* Boolean OR operator  */
          | <query> "&" <query>    /* Boolean AND operator */
          | "(" <query> ")"
/*set 2*/ | <field> "~" "/" <regex> "/"
          | <field> "~" '"' <string> '"'
          | "source"
          | <comparison> '"' <string> '"'
<field> ::= '.' <string>
<comparison> ::= '<<' | '<' | '>' | '>>' | '=' | '<=' | '>='

The first rules are the usual boolean constants and operators. The sixth rule is useful to group queries and override boolean operators' priotity.

The second set are the various type of queries implemented to match against different criteria. It matches against a package field (in lowercase).

We believe the syntax of queries is easy to grasp. Nonetheless, here are some exemples:

  • .build-depends ~ /lib.*ocaml-dev/
    This query matches all packages that build-depend on a package whose name matches the Perl regular expression lib.*ocaml-dev.

  • .depends ~ "libapt-pkg4.12"
    This one is simpler than the first one in the sense that libapt-pkg4.12 is considered as a plain string and not a regular experssion.

Important Note the symbols around the selectors: /…/ for regular expressions and "…" for plain strings.
Warning Packages fields may contain a list of values comma-separated. Ben splits the list before looking with "…" for a match.
  • >= "3.0"
    The query >= "3.0" matches all packages with a version number equal to or higher than "3.0".

  • source
    This matches all source packages.

Now that the concept of query is explained, we will focus on other parts of Ben. We will see how we can use the queries for each frontend.

3. Frontends

Ben is a set of utilities available through the ben command. Each utility is called a frontend and there are four:

  • download

  • query

  • monitor

  • tracker

All frontends share a set of options and each one defines its own specific set. The shared set of command-line options is:

Option Action

--dry-run

Dry run

--quiet|-q

Quiet mode

--verbose

Verbose mode

--mirror uri

Package mirror to use

--mirror-binaries uri

Package mirror to use for binaries

--mirror-sources uri

Package mirror to use for sources

--areas a,…

Areas to consider (comma separated)

--archs a,…

Architectures to consider (comma separated)

--suite a

Suite

--cache-dir d

Path to cache dir

--cache-file|-C f

Specify the name of the cache file

--use-cache

Use cache whenever possible

--config|-c c

Config file

The rest of this section describes each frontend.

3.1. download

This frontend is the simplest one as it has no command-line options, except the shared ones. It downloads all Sources.bz2 files and all Packages.bz2 files for selected architectures and areas. You may invoke it by running:

$ ben download [options]

The requested files will be downloaded in $BEN_CACHE_DIR, if set, or in the current directory.

Note ben download doesn’t read ben.cache files yet.

3.2. query

This utility is pretty much like grep-dctrl(1). Given a list of Packages or Sources files, it performs a query and outputs the result.

Using it is as simple as shown below:

$ ben query ".package ~ /gentoo/" Packages

Other valid uses:

$ zcat Packages.gz | ben query ".package ~ /gentoo/" -
[...]
$ ben query ".package ~ /gentoo/" Packages_foo.gz Packages_bar.bz2
[...]
$ ben query ".package ~ /gentoo/" monitor.cache
[...]

Just like grep-dctrl(1), ben query has a simple mechanism to filter its output. Using the command-line option -s, one can specify a comma-separated list of fields that will be shown for matching paragraphs.

$ ben query ".package ~ /gentoo/" -s Package,Version ...

3.3. monitor

The monitor fontend builds a monitoring page for a transition. A transition is decribed by three queries:

  • is_affected: matches source packages that are part of this transition; this query is evaluated against all source and binary packages and, for binary packages, their source package is picked;

  • is_good: matches binary packages that are considered to be ready (fixed) for this transition;

  • is_bad: matches binary packages that are considered to be broken (not fixed) for this transition.

Note that some packages can be neither good nor bad. For example, there are many packages that build-depend on some library but do not link against it. Thus, they do not need any dependency on the library at runtime.

An example of a complete description of a transition is:

is_affected = .build-depends ~ /libicu-dev/;
is_good = .depends ~ /libicu44/;
is_bad = .depends ~ /libicu42/;

There are other optional fields:

  • title
    This puts a nice title in the HTML page.

  • notes
    This can be used to put remarks about the transition or notes about the status of some packages or the whole transition.

    Ben recognizes some special texts and turns them into links. The following formats are recognized:

Original text Result

pts:ocaml

pts:ocaml

buildd:ocaml

buildd:ocaml

#123456

#123456

<msg-id>

http://lists.debian.org/msg-id

http://example.com

http://example.com

monitor understands the following list of command-line options:

Option Action

--run-debcheck

Run dose-debcheck and add virtual .uninstallable field

--use-projectb

Get package lists from Projectb database

--color

Color if text output

--text

Select text output format

--html

Select HTML output format

--output file

Select output file

-o file

(Same as above)

--template template

Select an HTML template

3.4. tracker

This frontend uses monitor to generate a summary page about all known transitions. An example of such summary can be found at http://release.debian.org/transitions/.

tracker has a notion of profiles that gives a hint on the actual state of the transition. The default profiles are:

  • planned for known planned transitions or requested but not processed or acknowledged yet;

  • permanent is a special profile made to keep an eye on some set of packages, not necessarily a transition;

  • ongoing for the actual list of (known) on-going transitions;

  • finished has a list of some transitions that are almost finished (e.g. new binary packages migrated but old binary packages left in testing to not decrease installability, or a finished transition with a number of still broken packages in testing).

Technically, each profile is a sub-directory of the global config directory
[http://release.debian.org/transitions/config/]
. The latter can be specified by a command-line option.

By default, tracker looks for a directory named config which should contain a file named global.conf, unless otherwise told. It reads data (.ben files) from the config directory and outputs the result in the base directory.

tracker has the following command-line options:

Option Action

--base|-b [dir]

Specifies the "base" directory

--config-dir|-cd [dir]

Location of ben trackers

--transition|-t [profile/transition]

Generate only that tracker page

--update|-u

Updates cache files

--use-projectb

Get package lists from Projectb database

--template template

Select an HTML template

4. HTML Templates

Ben has a simple templating mechanism to generate customized HTML pages. Templates are loaded dynamically when monitor or tracker frontends are used. When none specified, Ben chooses to load the Debian template.

You can write your own HTML template for Ben. All you have to do is to install the package libben-ocaml-dev which provides the Ben library. We recommend users to start from an existing template to ease the task. You can compile a template (e.g. named foo) by running the following command:

$ ocamlbuild -pkg ben foo.cmxs
Note .cmxs files are native dynamically loadable shared modules. If you’re building on a bytecode-only architecture, you should build a foo.cma instead.

If your template needs a CSS (Cascading Style Sheets) or some images, you should install them under /usr/share/ben/media.

5. Reporting issues

Ben doesn’t have a bug tracker yet. If you experience a bug or if you’re looking for some help, feel free to contact us directly.


ben-0.6.6ubuntu1/doc/Makefile0000644000000000000000000000031412233760077012713 0ustar all: ben.1 refman.html ben.1: a2x --doctype manpage --format manpage $@.txt refman.html: asciidoc -b html -a icons -a toc2 $(@:.html=.txt) .PHONY: ben.1 refman.html clean: -rm -f refman.html ben.1 ben-0.6.6ubuntu1/doc/ben.1.txt0000644000000000000000000000375212233760077012730 0ustar BEN(1) ====== :doctype: manpage NAME ---- ben - transition tracker manager SYNOPSIS -------- *ben* 'FRONTEND' ['OPTIONS'] *ben* [-h|-help|--help] DESCRIPTION ----------- The ben(1) command is a set of utilities written in OCaml. It provides a full featured transition tracker to follow the evolution of a set of packages in the Debian’s archive. All frontends share a common list of options described below. OPTIONS ------- *--dry-run*:: Dry run *--quiet|-q*:: Quiet mode *--verbose*:: Verbose mode *--mirror uri*:: Package mirror to use *--mirror-binaries uri*:: Package mirror to use for binaries *--mirror-sources uri*:: Package mirror to use for sources *--areas a,…*:: Areas to consider (comma separated) *--archs a,…*:: Architectures to consider (comma separated) *--suite a*:: Suite *--cache-dir d*:: Path to cache dir *--cache-file|-C f*:: Specify the name of the cache file *--use-cache:: Use cache whenever possible *--config|-c c*:: Config file FRONTENDS --------- *download*:: has no command-line options, except the shared ones. It downloads all Sources.bz2 files and all Packages.bz2 files for selected architectures and areas. *query*:: This utility is pretty much like grep-dctrl(1). Given a list of Packages or Sources files, it performs a query and outputs the result. *monitor*:: The frontend monitor builds a monitor page for a transition that is described by few criteria (the list of affected packages, a description of good package and the description of a broken package). *tracker*:: This frontend uses the monitor to generate a summary page about all known transitions. An example of such summary can be found at . For more information about ben's frontends, please refer to the reference manual. AUTHOR ------ Ben was originally written by Stéphane Glondu. RESOURCES --------- Main web site: ben-0.6.6ubuntu1/.typerex0000644000000000000000000000003512233757266012215 0ustar CMT _build bin frontends lib ben-0.6.6ubuntu1/examples/0000755000000000000000000000000012233757266012334 5ustar ben-0.6.6ubuntu1/examples/monitor/0000755000000000000000000000000012233760077014015 5ustar ben-0.6.6ubuntu1/examples/monitor/haskell.ben0000644000000000000000000000042112233760077016123 0ustar title = "Haskell"; architectures = [ "amd64" ]; is_affected = .source ~ /ghc/ | .build-depends ~ /ghc/ | .build-depends ~ /haskell-devscripts/ | .depends ~ /libghc-/; is_good = !.uninstallable ~ /yes/; is_bad = .uninstallable ~ /yes/; ben-0.6.6ubuntu1/examples/monitor/ocaml.ben0000644000000000000000000000177712233760077015612 0ustar # Sample configuration file for monitor frontend title = "OCaml"; # Run with "ben monitor -c ocaml.ben". With default settings, this # should be run after a download run. Additionally, the # "--run-debcheck" must be passed to be able to use the # "uninstallable" pseudo-field. # Sample of architectures representative of issues that arise with # OCaml packages: native, native without natdynlink, bytecode architectures = [ "amd64"; "armel"; "mips" ]; is_affected = .maintainer ~ /debian-ocaml-maint/ | .build-depends ~ /ocaml/ | .build-depends-indep ~ /ocaml/; is_good = !.uninstallable ~ /yes/; is_bad = .uninstallable ~ /yes/; # Comment appearing in HTML output, with various linkifications notes = "This is a permanent tracker for the OCaml stack. For an example OCaml release bug, see #718767. Further details about the language can be found at http://caml.inria.fr and the source package is pts:ocaml (buildd:ocaml). More on http://wiki.debian.org/Teams/OCamlTaskForce/OCamlTransitions"; ben-0.6.6ubuntu1/examples/download/0000755000000000000000000000000012233757266014143 5ustar ben-0.6.6ubuntu1/examples/download/unstable.ben0000644000000000000000000000054212233757266016447 0ustar # Sample configuration file for download frontend # Run with "ben download -c unstable.ben", and it will download Sources and # Packages for listed architectures into current directory. mirror = "http://ftp.fr.debian.org/debian"; suite = "unstable"; areas = [ "main"; "contrib"; "non-free" ]; architectures = [ "amd64"; "i386"; "armel"; "mips" ]; ben-0.6.6ubuntu1/examples/tracker/0000755000000000000000000000000012233763276013765 5ustar ben-0.6.6ubuntu1/examples/tracker/global.conf0000644000000000000000000000437612233760077016102 0ustar # This type of configuration file is used on release.debian.org/transitions # to run Release Team's transition tracker. # Suite to analyse suite = "unstable"; # Areas to take into account areas = ["main"; "contrib"; "non-free"]; # List of architectures architectures = [ "amd64"; "armel"; "armhf"; "hurd-i386"; "i386"; "ia64"; "kfreebsd-amd64"; "kfreebsd-i386"; "mips"; "mipsel"; "powerpc"; "s390"; "s390x"; "sparc" ]; # Architectures present in the list "ignored" are not taken into account # when computing pourcentages for each transition. ignored = [ "hurd-i386"; "armhf"; "s390x" ]; # Configuration paths # - base is where html files are produced into a subdir "html" # (it also expects a copy of media/ dir there) # - config-dir is where transition trackers (.ben files) are stored # and organized in dirs. Each subdir of config-dir is a profile and # they are: planned, ongoing, permanent, finished, old and unknown. # - use-cache is a boolean value that tells ben whether he should consider # using the cache file "ben.cache" stored in directory "cache-dir". # - run-debcheck activates installability checking for all packages on all # architectures. This is necessary if you want to use ".uninstallable" # predicates in .ben trackers. # - use-projectb makes ben using projectb database to retrieve Packages # informations instead of downloding separate Packages_* files. base = "/srv/release.debian.org/www/transitions"; config-dir = "/srv/release.debian.org/www/transitions/config"; use-cache = true; cache-dir = "/srv/release.debian.org/tmp/ben-cache"; run-debcheck = true; base-url = "http://release.debian.org/transitions"; template = "debianrt"; use-projectb = true; # - output-type sets output format to the format being specified. Valid # values here are: text, levels, and xhtml. Any invalid value will be # considered as xhtml. output-type = "xhtml"; # There are other configuration variables like: # - mirror-binaries mirror to be used to retreive Packages_* files # - mirror-sources mirror to be used to retreive Sources_* files # - mirror sets both mirror-binaries and mirror-sources to the same mirror # These options are (obviously) not taken into account if use-projectb is # set to true. mirror = "http://cdn.debian.net/debian"; ben-0.6.6ubuntu1/media/0000755000000000000000000000000012235730040011554 5ustar ben-0.6.6ubuntu1/media/ubuntu.png0000644000000000000000000001170512233757266013631 0ustar PNG  IHDRRR,bKGDԂ pHYsHHFk> vpAgRR+#IDATx՝{t\U?;4I$MI)]("\@^E]Pe镫u^b"(X<奼 ->6ii$3{L'3$VJ2{3(H"4`*PL?pDb~ h=A8`*yF8|`:0XTygu ͑]@;hh)Q|eǁ"@]~<l P3s"4GMo/G!3@Ӛc +.;2-:^D"ԓ)"DZɎyѝDsi A]"򰈜#"jaFzEzk:#~I"s,[D+ GD2ͮlcM"MZ/"F sXVTV3G5}| x79eK)cd66:Ӊ O9C͢&8 R@8c 덧x7FBAP ;c>KY8Ss1~NіZsvgD}4J;cP<|e^8 =&ͦ΁5Iq/kWadNʠPBQo)<}q@QR }0+_1L$#/HlC5"a3y>Ja n 9ֽGW(Hx1n9٦ \,raX-?lVHr(3ۀ k*؍v eG +'Kq~&JTÛsBHV`: |83SC*zjmFl eHPo=OE;\`6&'ŶFZr}125~ L =]toy e0N[?؂kbKnۊEXa\4TiVAFT^Tpݝt>z=kzf{H hNso_Sj@m;#|gpW2'W(\>@{rc61"1Kq_!"- Lp8]zX=GnaF{wU\mt:A)^^@U>_''lwG)xgGy|'.0$m@FkH%Tc+IpIZ̄-x?"c:@=(b뉼ob/_#9xf,EH=f ܊gja&I }#hU%57pWl_gf0Qô;(3TǸR ^}Ipk n'T U7D  z%wB/_kRv:cA.FLv+cm϶qNpWTc;|QxCnh k3tu&l\Eɭ+sLUGT zٓN<}?O܋qN)(]V5 B8K&uf,6a*a/ʗſt#_-ˋvy?%NBL ĶqOS5{Phɉ*)Pk0'=]CO} HRt<[GǭxK)֝^t˞h./仫pU& &:;НDNzb>B+ޛto|>1DqR|ɚq1uŷ܁,)/ӳt,$rx$lZlGGQob mGP E<:̃l_}{f br>r~&:23 zHng:&SRͭ{۫X ZsdZ̮#3R.7yW~ĊI vqJ3 l^*9"c27d5%%wY9^B`Ǜ=C$RPiݍ ʉg}j=y^}'9FnًH< eH]$Xi>v(b\4'g;Ch/LWi9yWH'7c6q51 mոϘ1UΤgKh]Ob6]VjQq֢nnد`wG*amc6I(܌3,=}!]^ЧG}k!7+I3cݛ^$Y-tm|oBg-@y/<8J. p%6U$սw0fc"f-EQl}v( Û$Ye/#xOAb>QWRzI*SPVk^Eҋe`D2?!?PtzRCH:c\4߼1$BG^a &k3*J(ui@}*IJȿ榁mz0ȿx.68]~=n>HƤp@kqr8q;8a$5 Jn]I+Qllwm\-Ķx> -"XhKBpW.7IimrL} JVMv}aww,zӦ= TPx*P{w?-5yj::DdmZo@l_׮'R ό:a?Q6Ӧpzń:޹3ۃwyD ^]e4dڏտ&^)wT}@Oֵ:hpf Gaen:@ǓC`jg!ś[5t 7txJrO{Il% +xjuo|8m㝱 ]@)'M%j{"[IOm=_B|5?Ml;BP,r/Y@#}goE ps-GϻodboV$ ͹(Ev̱$M8&&i/e]tPoұ_Lhߎ "_utَ"ey%ʯhgD2 ̦zz}SFe bsw8v?V"t[Γiq{;HM=3S7?M} tax|tM;أz8*_3y `YMښ)Y-WREFunC|L&ϔo]I] @r(8M:kmv_ɿιD1wi't/;hf8 Vj00~ݴ ]!ORuxA юsՌOpb[GPJ\2]7c s^ɤ ].Ӧ%o[oD[L"8v6A;Gk'kb[x׽Xa2@I[dohjk > Xa\tЏϚ h} cdTkk&5u _~<".*S5¥;p|,!uR LЁ$LDm sfsJN?o4;Wz׳e^NgSfdH-qĊp1wQE䂑^{*rƚB &vڨB4[Dn&2HޘSyLU",c!DDrD "IDcM+" "Ʈ K| !(B } 3k]EɍvԒx r -kFK/r_5p9*F0u= ^A۝q"1_`V[n7чMh-3m^fQ&/?D Copyright © 2009 Mehdi Dogguy 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. Dependencies: jquery. */ function update () { $(".src").removeClass("mark"); if ($("#good").is(":checked")) { $(".src").filter(".good").parent().show(); } else { $(".src").filter(".good").addClass("mark").parent().hide(); } if ($("#bad").is(":checked")) { $(".src").filter(".bad").parent().show(); } else { $(".src").filter(".bad").addClass("mark").parent().hide(); } if ($("#unknown").is(":checked")) { $(".src").filter(".unknown").parent().show(); } else { $(".src").filter(".unknown").addClass("mark").parent().hide(); } if ($("#notintesting").is(":checked")) { $(".src").filter(".notintesting").parent().hide(); } else { $(".src").filter(".notintesting").each(function() { if(!$(this).hasClass("mark")) { $(this).parent().show(); } }); } for (i = 0; i < nb_rounds; i++) { if ($(".round"+i).filter(":visible").length > 0) { $("#header"+i).show(); } else { $("#header"+i).hide(); } } $("#count").html(" ("+$(".srcname").filter(":visible").length+")"); }; function init () { $("#good").click(update); $("#bad").click(update); $("#unknown").click(update); $("#notintesting").click(update); update(); } $(document).ready(init); ben-0.6.6ubuntu1/media/debian.png0000644000000000000000000001511512233757266013530 0ustar PNG  IHDRR0MDIDATx}\G"DN8מ'X}Cyh盛'`[{>=x*;*`'EE"Hy <$\\3ݐ0;;f?;3ߙ 6c} c#F a|G_fJof '7*Iq,r tu*ZS5-{Ebr;6f{4N˲/=tx\stÍ jce۲e:- vkazKt5#J?;ݝ_F,hwj9+144pQX\^^>֋;vҥ^Kl F ГY*IΤ+<ܨ>=Aq.ljjjJKKn߾ Ȳeܒ:A\B thc xYŴ`H~eP?w073ypʕCT*XѡjGyi𶧧(X1Jv4F&@,e%f&[, ֭G /L<i72'YOeк/X)d8!7sZܶ{\$ִ,%0dxqUYsLdX/͛͛rܤ#G,\rAX YY_|م > O^/J;&LpttT*$u:]UU BxO?֭[CCCԯEQFS^^>c ARRRGkjjmk wtt2Ga<5UT*H}.&yE]yʒ*ͻʒcՂX'4&'*F322F8E\ wuuRԴiΜ9, b1lf:hB,9rd 7$2}tY:bf/Xڵk$w۷oOHH9sPAjzF'q%sf3,oV^A-`'v+xHYR7,RTUUYB"J3柦T2twwR~\\_NF4ʯjϝ;pY 'X0S4ggg4Z 6C+WU bǗ<'IHwɋ***rrr& 'L`^ӟJ#{(j㭷^3D̟9/!++ KJII lM8]eoT biQ{dMO;(:;;C}6̦Nb\/DCCCm!"666~){zz`qF ƞIe2Nš[)))O6\zz:B֘Ÿhu痩J؄jR*111 !!!7o޳ggϞkк>t$H$IGGGnn.pZӭ]VQ1S]Mo&;v쨯7JwqqOJWWw${ww޽{a.Vk33 l Gzh﫡9N46 V`uQIrnٲ]JJJrV3yd)xϟ'fJ@ .\0d# @Q@dƍY|9036@Q($WWÇ*nJ:y$IgL ~S .{{{H$j5JvW1Z[[a੧﨡xVu7n -@W,^$ڦ&6 /RܹsQWt޽kkkM| &hgooӧOꡡSNM2QpuuŞ|8544d|Dr| 'Oa ̈#Ds73(?-]V=qPzz:CNw)bo~X-`bRb}7į O|bbbrss=JxhHxyyO^{5rG3,[cf߽6Bm"a+oe215`\vtȪ**v|}}_t'!**ꭷޢuJDD$I~3 ~X#>inS [fiӗ,YB4@e… D{{{t>>>DCCI֭#ɰrJGGG 4aY{,17f)e`WҚKg B=~Qg`'!/Z̍CdPQQLuJa MTV{y*Ҷ69sjcBa҄e2 HQ#ĸo`Jc"$6{T,<@UZFJe_>{7ru[vvv$%o٨^3DRn&(2o0KWr3XH3V{\$[i'j8i$KEXyD@=Wvy~ aHf dсJjt"z FcSU9!d=:EOcVB$ r1+i)'2\Gf\0*<^d: /jiݨ[niښR/8,q )ZJU՘cWؔal&9W0w#yҪE@@ ݉$ܼy^ZZa߹s$7*̈n=i#/ A(Z}i{シaoP"D|3SVw|ǑeԄ%Od7a`8w֪IdP? _U)-nҔ7ք% i>HxI- *9D(k3m49a}ܑQMKK۲eKOψxn9 Y<7fF^|"К՚`=I< ,c˘6:C0׿,\0""|sӾ7*I,)zh=|b'a`Sb;Q/#nq"- `Cl6I{#qZBm6ࡠG+@p?~IN t@, #.hmrA;8@odDDD\rV|#""xlQ(2SٚU6ߌM &Z*);qQUVMsz%-6g/s|899эdq8<J60o)z3=.rk2C\?e6<Бn8kyyyww71}Æ ' CkS_LvlѽtSɉ6Bak ˁZ~Ux`[A]'<+b|ϕfP8| $6skZ*3JGGGܽ{JD[[[*Ñ AM`D#YzT* :===z=l3Qv\LSiX!:N0gR|`F/z/^4yn__0\JWWa+b a93c2hUeqU3$UWWx<Jf"//bJ͛gv\bb[[IW^mmm5/ZlN7[»/Yԡ$Er~jA*Osh40 :::4mx燑SZt)V(t:N7ꬨΝ;(d0c U-[  [zl\PF[)fFS4k֬G(cX\;wc209GR}|SΞ=K%P(N {ىVKHHʚ:uu N(^z vݹs'~KfZ ){r.-%2nH * © 2007 Dan Callahan * © 2007 Enrico Tassi * License: GNU General Public License (GPL), version 3 or above */ /* --- Whole-Page --- */ body { margin: 0; padding: 0; font-family: "DejaVu Sans", "Bitstream Vera Sans", sans-serif; /*Prefer Free Fonts*/ color: #000; font-size: 100%; } body.debian { background: #fff url('ubuntu.png') no-repeat 10px 7px; } a:link { color: #0755d7; text-decoration: underline; } a:visited { color: #0755d7; text-decoration: underline; } a:hover { color: #032a6b; text-decoration: underline; } a:active { color: #f00; text-decoration: underline; } a img { border: none; } .containertable { width: 100%; } /* --- Header --- */ body > form { /* "Jump to package" */ margin: 0.3em; font-size: 80%; padding: 0.5em; border: 1px solid #aaa; background-color: #dfdfdf; } #quickforms { /* "Jump to package" */ margin: 0.3em; font-size: 80%; padding: 0.5em; border: 1px solid #aaa; background-color: #dfdfdf; } h1#title { margin: 0 0 0 0; padding: 20px 0 0 280px; font-size: 150%; /* min-height: 60px; height: auto !important; /* "Min-Height Fast Hack" */ /* height: 60px; */ } h1#title a { color: black; text-decoration: none; } h2#subtitle { margin: -1em 0 1em 0; padding: 20px 0 0 280px; font-size: 80%; /* min-height: 60px; height: auto !important; height: 60px;*/ } /* --- Content Pane --- */ div#body { clear: both; border-top: 2px solid #d70751; /* background: #dfdfdf;*/ padding: 1em 1em; /* 0em 0em */ } table.containertable { padding: 0.5em 0.5em; } td.containercell { padding: 0.5em; } table.lefttable { border-collapse: collapse; border: 1px solid #999; background: #fff; width: 100%; } table.righttable { border-collapse: collapse; border: 1px solid #999; background: #fff; width: 100%; } td.titlecell { padding: 0.2em 0.2em 0.1em 0.2em; font-weight: bold; font-size: 100%; background: #d70751; color: #fff; border-top: 3px solid #999; border-bottom: 1px solid #999; } td.titlecell a:link { color: #ffffff; background: #d70751; text-decoration: underline; } td.titlecell a:visited { color: #ffffff; background: #d70751; text-decoration: underline; } td.titlecell a:hover { color: #fff200; background: #d70751; text-decoration: underline; } td.titlecell a:active { color: #295598; background: #d70751; text-decoration: underline; } th.titlecell { padding: 0.2em 0.2em 0.1em 0.2em; font-weight: bold; font-size: 100%; background: #d70751; color: #fff; border-top: 3px solid #999; border-bottom: 1px solid #999; } th.titlecell a:link { color: #ffffff; background: #d70751; text-decoration: underline; } th.titlecell a:visited { color: #ffffff; background: #d70751; text-decoration: underline; } th.titlecell a:hover { color: #fff200; background: #d70751; text-decoration: underline; } th.titlecell a:active { color: #295598; background: #d70751; text-decoration: underline; } td.labelcell { font-weight: bold; padding: 0.2em 0 0.2em 0.3em; border-bottom: 1px dotted #999; } td.labelcell:after { content: ":"; } td.contentcell { padding: 0.2em 0.3em 0.2em 0; border-bottom: 1px dotted #999; } /* - Edge Tables - */ tr#bugs_rc { font-size: 90%; } tr#bugs_in { font-size: 90%; } tr#bugs_mw { font-size: 90%; } tr#bugs_fp { font-size: 90%; } span.indented { padding-left: 1.5em; } td > form { margin: 0.4em 0 0.4em 0.4em; padding: 0; } /* PTS subscribe */ td#src_files ul { padding: 0; } td#src_files li { display: inline; font-family: "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; } #news-list { max-height: 30em; overflow: auto; } /* - Central Table - */ #problems { background: #0755d7; color: #ffffff; } #todo { background: #0755d7; color: #ffffff; } /* --- Footer --- */ div#body > hr { display: none; } div.footer { padding: 1em 0; background-color: #fff; text-align: center; border-top: 2px solid #d70751; margin: 0 0 0 0; border-bottom: 0; } tt { font-family: "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; } /* --- Misc --- */ form > p { margin: 0; padding: 0; } a.feedlink { /* Little orange RSS button */ background: #f60 !important; color: #fff !important; border: 1px solid !important; border-color: #fc9 #630 #330 #f96 !important; padding: 0 3px !important; font-weight: bold !important; font-size: 70% !important; text-decoration: none !important; vertical-align: 0.2em !important; /* Without !important, inherets from td.titlecell a:* */ } ul { list-style-type: none; padding: 0; } li { margin-top: 0.2em; } /*li { margin-top: 0.4em; } td > ul { padding-left: 1em; } a.none { color: #000 !important; text-decoration: none !important; }*/ ben-0.6.6ubuntu1/media/styles.css0000644000000000000000000000132012233757266013626 0ustar div.transition { display: inline-block; vertical-align:text-top; margin: 2em; } div.status { text-align: center; margin-top: 1em; } div.status table a { text-decoration: none; } div.status table { padding: 0px; border-spacing: 1px; } div.footer { margin-top: 2em; font-size: 60%; } .parameters { background: #eeeeee; padding: 0.3em; margin: 0.2em; } .parameters pre { font-size: 90%; } #footer { border-top: 2px solid #d70751; padding: 0.5em; } .level { text-align: left; } .src { background: #eeeeee; } .good { background: LightGreen; text-align: center; } .bad { background: Salmon; text-align: center; } .unknown { background: Cornsilk; text-align: center; } ben-0.6.6ubuntu1/lib/0000755000000000000000000000000012235727774011267 5ustar ben-0.6.6ubuntu1/lib/benl_data.ml0000644000000000000000000003443612233760077013533 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Benl_core open Benl_base open Benl_marshal module M = Package.Map module S = Package.Set let use_projectb = ref false let run_debcheck = ref false open Benl_modules module Marshal = Benl_marshal.Make(Marshallable) open Marshallable type origin = { get_binaries : ([ `binary ] as 'a) Package.t PAMap.t -> string -> 'a Package.t PAMap.t; get_sources : ([ `source ] as 'b, 'b Package.t) M.t -> ('b, 'b Package.t) M.t; } let relevant_binary_keys = [ "package"; "source"; "version"; "maintainer"; "architecture"; "provides"; "depends"; "pre-depends"; "replaces"; "multi-arch"; "conflicts"; "breaks"; "suggests"; "recommends"; "enhances" ] let relevant_source_keys = [ "package"; "source"; "version"; "maintainer"; "architecture"; "directory"; "binary"; "build-depends"; "build-depends-indep" ] let ( // ) = Filename.concat let ( !! ) = Lazy.force let ( !!! ) = Package.Name.to_string let file_origin = let get_binaries accu arch = Benl_utils.parse_control_file `binary (!Benl_clflags.cache_dir // ("Packages_"^arch)) (fun x -> List.mem x relevant_binary_keys) (fun name pkg accu -> try let old_pkg = PAMap.find (name, arch) accu in let old_ver = Package.get "version" old_pkg in let ver = Package.get "version" pkg in if Benl_base.Version.compare old_ver ver < 0 then PAMap.add (name, arch) pkg accu else accu with _ -> PAMap.add (name, arch) pkg accu ) accu in let get_sources accu = Benl_utils.parse_control_file `source (!Benl_clflags.cache_dir // "Sources") (fun x -> List.mem x relevant_source_keys) (fun name pkg accu -> try let old_pkg = M.find name accu in let old_ver = Package.get "version" old_pkg in let ver = Package.get "version" pkg in if Benl_base.Version.compare old_ver ver < 0 then M.add name pkg accu else accu with _ -> M.add name pkg accu ) accu in { get_binaries = get_binaries; get_sources = get_sources } module Projectb = struct module StringMap = Map.Make(String) module StringSet = Set.Make(String) module IntMap = Map.Make(struct type t = int let compare : t -> t -> int = compare end) let mk_origin () = (* psql service=projectb must work, e.g. on coccia.debian.org. To make it work elsewhere, copy coccia.debian.org:/etc/postgresql-common/pg_service.conf to your ~/.pg_service.conf and set up tunnels accordingly. *) let projectb = new Postgresql.connection ~conninfo:"service=projectb" () in let mk_wrapper_maps transform sql = let r = projectb#exec sql in assert (r#status = Postgresql.Tuples_ok); Array.fold_left (fun (a, b) row -> match row with | [| key_id; key |] -> let key = transform key and key_id = int_of_string key_id in ( IntMap.add key_id key a, StringMap.add key key_id b ) | _ -> assert false ) (IntMap.empty, StringMap.empty) r#get_all in let string_identity x = x in let mk_wrappers name (key_of_id_map, id_of_key_map) = ((fun x -> try IntMap.find x key_of_id_map with Not_found -> ksprintf invalid_arg "%s_of_id(%d)" name x), (fun x -> try StringMap.find x id_of_key_map with Not_found -> ksprintf invalid_arg "id_of_%s(%s)" name x)) in let key_of_id, id_of_key = mk_wrappers "key" (mk_wrapper_maps String.lowercase "select key_id, key from metadata_keys") in let suite_of_id, id_of_suite = mk_wrappers "suite" (mk_wrapper_maps string_identity "select id, suite_name from suite") in let arch_of_id, id_of_arch = mk_wrappers "arch" (mk_wrapper_maps string_identity "select id, arch_string from architecture") in let relevant_binary_key_ids = List.map id_of_key relevant_binary_keys in let get_binaries accu arch = Benl_clflags.progress "Querying projectb for %s binaries in unstable..." arch; let sql = sprintf "select b.bin_id, b.key_id, b.value from bin_associations as a join (select * from binaries_metadata where key_id in (%s)) as b on b.bin_id = a.bin join (select * from binaries) as c on c.id = a.bin where a.suite = %d and c.architecture in (%d,%d)" (String.concat "," (List.map string_of_int relevant_binary_key_ids)) (id_of_suite "unstable") (id_of_arch "all") (id_of_arch arch) in let r = projectb#exec sql in assert (r#status = Postgresql.Tuples_ok); let id_indexed_map = Array.fold_left (fun a row -> match row with | [| src_id; key_id; value |] -> let src_id = int_of_string src_id and key_id = int_of_string key_id in let old = try IntMap.find src_id a with Not_found -> [] in IntMap.add src_id ((key_of_id key_id, value)::old) a | _ -> assert false ) IntMap.empty r#get_all in let result = IntMap.fold (fun _ assoc accu -> let pkg = Package.of_assoc `binary assoc in let name = Package.Name.of_string (Package.get "package" pkg) in let ver = Package.get "version" pkg in try let old_pkg = PAMap.find (name, arch) accu in let old_ver = Package.get "version" old_pkg in if Benl_base.Version.compare old_ver ver < 0 then PAMap.add (name, arch) pkg accu else accu with Not_found -> PAMap.add (name, arch) pkg accu ) id_indexed_map accu in Benl_clflags.progress "\n"; result in let sources_in_testing = Benl_clflags.progress "Querying projectb for sources in testing..."; let sql = sprintf "select (select value from source_metadata as b where key_id = %d and b.src_id = a.source) from src_associations as a where a.suite = %d" (id_of_key "source") (id_of_suite "testing") in let r = projectb#exec sql in assert (r#status = Postgresql.Tuples_ok); let result = Array.fold_left (fun a row -> match row with | [| source |] -> StringSet.add source a | _ -> assert false ) StringSet.empty r#get_all in Benl_clflags.progress "\n"; result in let relevant_source_key_ids = (* beware! key "directory" does not exist in projectb and is handled specifically below *) List.map id_of_key (List.filter (fun x -> x <> "directory") relevant_source_keys) in let get_sources accu = Benl_clflags.progress "Querying projectb for sources in unstable..."; (* get general metadata *) let sql = sprintf "select b.src_id, b.key_id, b.value from src_associations as a join (select * from source_metadata where key_id in (%s)) as b on b.src_id = a.source where a.suite = %d" (String.concat "," (List.map string_of_int relevant_source_key_ids)) (id_of_suite "unstable") in let r = projectb#exec sql in assert (r#status = Postgresql.Tuples_ok); let id_indexed_map = Array.fold_left (fun a row -> match row with | [| src_id; key_id; value |] -> let src_id = int_of_string src_id and key_id = int_of_string key_id in let old = try IntMap.find src_id a with Not_found -> [] in let key = key_of_id key_id in (* translate "source" to "package" for consistency with Sources files *) let key = if key = "source" then "package" else key in IntMap.add src_id ((key, value)::old) a | _ -> assert false ) IntMap.empty r#get_all in (* get .dsc paths to compute directories *) let sql = sprintf "select a.source, c.filename from src_associations as a join (select * from dsc_files) as b on b.source = a.source, files as c where a.suite = %d and b.file = c.id and c.filename like '%%dsc'" (id_of_suite "unstable") in let r = projectb#exec sql in assert (r#status = Postgresql.Tuples_ok); let id_indexed_dscs = Array.fold_left (fun a row -> match row with | [| src_id; filename |] -> let src_id = int_of_string src_id in IntMap.add src_id filename a | _ -> assert false ) IntMap.empty r#get_all in (* fake directory entry by merging id_indexed_{map,dscs} *) let id_indexed_map = IntMap.mapi (fun src_id pkg -> let directory = Filename.concat "pool" (Filename.dirname (IntMap.find src_id id_indexed_dscs)) in ("directory", directory) :: pkg ) id_indexed_map in let result = IntMap.fold (fun _ assoc accu -> let pkg = Package.of_assoc `source assoc in let sname = Package.get "package" pkg in let is_in_testing = if StringSet.mem sname sources_in_testing then "yes" else "no" in let pkg = Package.add "is-in-testing" is_in_testing pkg in let name = Package.Name.of_string sname in let ver = Package.get "version" pkg in try let old_pkg = M.find name accu in let old_ver = Package.get "version" old_pkg in if Benl_base.Version.compare old_ver ver < 0 then M.add name pkg accu else accu with Not_found -> M.add name pkg accu ) id_indexed_map accu in Benl_clflags.progress "\n"; result in { get_binaries = get_binaries; get_sources = get_sources } end let filter_affected { src_map = srcs; bin_map = bins } is_affected = let src_map = M.fold begin fun name src accu -> if Query.eval_source src !!(is_affected ()) then M.add name src accu else accu end srcs M.empty in let src_map, bin_map = PAMap.fold begin fun (name, arch) pkg (saccu, baccu) -> let src_name = Package.get "source" pkg in let src_name = Package.Name.of_string src_name in try let src = M.find src_name srcs in if Query.eval_binary pkg !!(is_affected ()) || Query.eval_source src !!(is_affected ()) then begin M.add src_name src saccu , PAMap.add (name, arch) pkg baccu; end else (saccu, baccu) with Not_found -> eprintf "warning: Binary (%s,%s) without Source!\n%!" !!!name arch; (saccu, baccu) end bins (src_map, PAMap.empty) in { src_map = src_map; bin_map = bin_map } let inject_debcheck_data = let rex = Pcre.regexp "^ package: (.*)$" in fun (bins : [`binary] Package.t PAMap.t) architectures -> let a, b = if !Benl_clflags.quiet then ("\n", "") else ("", "\n") in let all_uninstallable_packages = List.map (fun arch_ref -> Benl_clflags.progress "Running dose-debcheck on %s..." arch_ref; let (ic, oc) as p = Unix.open_process "dose-debcheck --quiet --failures" in (* inefficiency: for each architecture, we iterate on all binary packages, not only on binary packages of said architectures *) PAMap.iter (fun (name, arch) pkg -> if arch = arch_ref then Package.print oc pkg ) bins; close_out oc; let rec loop accu = begin match (try Some (input_line ic) with End_of_file -> None) with | None -> if Package.Set.is_empty accu then Printf.eprintf "W: no uninstallable packages!\n%!"; accu | Some line -> try let r = Pcre.exec ~rex line in let package = Pcre.get_substring r 1 in loop (Package.Set.add (Package.Name.of_string package) accu) with Not_found -> loop accu end in let result = loop Package.Set.empty in begin match Unix.close_process p with | Unix.WEXITED (0|1) -> () | Unix.WEXITED i -> Printf.eprintf "%sW: subprocess dose-debcheck exited with code %d%s%!" a i b | Unix.WSIGNALED i -> Printf.eprintf "%sW: subprocess dose-debcheck died with signal %d%s%!" a i b | Unix.WSTOPPED i -> Printf.eprintf "%sW: subprocess dose-debcheck stopped with signal %d%s%!" a i b end; Benl_clflags.progress "\n"; (arch_ref, result) ) architectures in PAMap.mapi (fun (name, arch) pkg -> let uninstallable_packages = List.assoc arch all_uninstallable_packages in if Package.Set.mem name uninstallable_packages then (* the following line is for compatibility only and should be removed eventually *) let pkg = Package.add "edos-debcheck" "uninstallable" pkg in Package.add "uninstallable" "yes" pkg else pkg ) bins let get_data is_affected = let file = Benl_clflags.get_cache_file () in if !Benl_clflags.use_cache && Sys.file_exists file then filter_affected (Marshal.load file) is_affected else let origin = if !use_projectb then Projectb.mk_origin () else file_origin in let src_raw = origin.get_sources M.empty in let bin_raw = List.fold_left origin.get_binaries PAMap.empty !Benl_clflags.architectures in let bin_raw = if !run_debcheck then inject_debcheck_data bin_raw !Benl_clflags.architectures else bin_raw in let data = { src_map = src_raw; bin_map = bin_raw; } in Marshal.dump file data; filter_affected data is_affected ben-0.6.6ubuntu1/lib/package.ml0000644000000000000000000001075712233760077013215 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Benl_types type 'a t = (string * string) list module Name = struct type 'a t = string let of_string x = x let to_string x = x end let filter_print keep outc p = List.iter (fun (f, v) -> if keep = [] || List.mem (String.lowercase f) keep then fprintf outc "%s: %s\n" (String.capitalize f) v) p; fprintf outc "\n" let print = filter_print [] let get = List.assoc let add k v pkg = (k, v) :: pkg module Set = struct module S = Set.Make(String) type 'a t = S.t let is_empty = S.is_empty let empty = S.empty let add = S.add let mem = S.mem let exists = S.exists let iter = S.iter let cardinal = S.cardinal let elements = S.elements let fold = S.fold end let rex = Pcre.regexp "^(\\S+)(?: \\((\\S+)\\))?$" let of_assoc sort x = match sort with | `binary -> let source, version = try let name = get "source" x in let r = Pcre.exec ~rex name in let name = Pcre.get_substring r 1 in let version = try Pcre.get_substring r 2 with Not_found -> get "version" x in name, version with Not_found -> get "package" x, get "version" x in ("source", source) :: ("source-version", version) :: (List.remove_assoc "source" x) | `source -> x module Map = struct module M = Map.Make(String) type ('a, 'b) t = 'b M.t let empty = M.empty let add = M.add let iter = M.iter let find = M.find let mapi = M.mapi let fold = M.fold let bindings = M.bindings let update_default default f key t = let previous = try find key t with Not_found -> default in add key (f previous) t end let get_and_split = let rex = Pcre.regexp "(?:[, |]|\\([^)]+\\))+" in fun field x -> try let deps = get field x in Pcre.split ~rex deps with Not_found -> [] let build_depends x = get_and_split "build-depends-indep" x @ get_and_split "build-depends" x let binaries x = get_and_split "binary" x type dependency = { dep_name : string; dep_version : (comparison * string) option; } let split_name_and_version = let rex = Pcre.regexp "^\\s*(\\S+)\\s*(\\(([<>=]+)\\s*([^)]+)\\))?\\s*(\\[\\s*([^\\]]+)\\s*\\])?\\s*$" in fun x -> try let r = Pcre.exec ~rex x in let dep = try let cmp = match Pcre.get_substring r 3 with | "<=" -> Le | "<<" -> Lt | ">=" -> Ge | ">>" -> Gt | "=" -> Eq | "<" -> Lt | ">" -> Gt | x -> ksprintf failwith "invalid comparison operator: %s" x in Some (cmp, Pcre.get_substring r 4) with Not_found -> None in { dep_name = Pcre.get_substring r 1; dep_version = dep; } with Not_found -> ksprintf failwith "unable to parse: %s" x let dependencies = let rex = Pcre.regexp "(?:\\s*[,|]\\s*)+" in fun field x -> try let deps = get field x in let deps = Pcre.split ~rex deps in List.map split_name_and_version deps with Not_found -> [] ben-0.6.6ubuntu1/lib/benl_utils.ml0000644000000000000000000000573412233757266013767 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_core open Benl_error open Lexing module S = Package.Set let p = Benl_clflags.progress let parse_control_in_channel kind filename ic keep f accu = p "Parsing %s..." filename; let result = Benl_lexer.stanza_fold begin fun p accu -> let p = List.filter (fun (k, v) -> keep k) p in f (Package.Name.of_string (List.assoc "package" p)) (Package.of_assoc kind p) accu end (from_channel ic) accu in p "\n"; result let parse_control_file kind filename keep f accu = let base = Filename.basename filename in with_in_file filename begin fun ic -> parse_control_in_channel kind base ic keep f accu end let parse_config_file filename = with_in_file filename begin fun ic -> let lexbuf = from_channel ic in let pos = lexbuf.lex_curr_p in lexbuf.lex_curr_p <- { pos with pos_fname = filename }; try Benl_parser.config_file Benl_lexer.token lexbuf with Benl_parser.Error -> let pos = Lexing.lexeme_start_p lexbuf in raise (Parsing_error (pos.pos_fname, pos.pos_lnum, pos.pos_cnum-pos.pos_bol)) end let file_content file = let lines = ref "" in let inchan = open_in file in try while true; do lines := Printf.sprintf "%s%s\n" !lines (input_line inchan) done; "" with End_of_file -> close_in inchan; !lines let dump_to_file name string = let outchan = open_out name in let () = output_string outchan string in close_out outchan let dump_xhtml_to_file filename xhtml = let outchan = open_out filename in let () = Xhtml.P.print (output_string outchan) xhtml in close_out outchan ben-0.6.6ubuntu1/lib/benl_core.mli0000644000000000000000000000537712233760077013725 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) (** Utility functions. This module contains handy functions not specific to Ben. *) val with_in_channel : in_channel -> (in_channel -> 'a) -> 'a (** Run the function on the in_channel, taking care of exceptions. *) val with_in_file : string -> (in_channel -> 'a) -> 'a (** Run the function on the given file, taking care of exceptions. *) val with_out_file : string -> (out_channel -> 'a) -> 'a (** Run the function on the given file, taking care of exceptions .*) val escape_for_shell : string -> string (** Quote a string for use with shell. For example, ["a"] is quoted into ["'a'"]. *) val get_rfc2822_date : unit -> string (** Get the current date in RFC-2822 format. *) val list_iteri : (int -> 'a -> 'b) -> 'a list -> unit (** Same as [List.iter], but calls the function with the index of the current element. *) val list_rev_mapi : (int -> 'a -> 'b) -> 'a list -> 'b list (** Same as [List.rev_map], but calls the function with the index of the current element. *) val simple_split : char -> string -> string list (** [simple_split sep s] splits [s] using [sep] as delimiter. *) val starts_with : string -> string -> bool (** [starts_with s prefix] returns [true] iff [s] starts with [prefix]. *) val ends_with : string -> string -> bool (** [ends_with s suffix] returns [true] iff [s] ends with [suffix]. *) ben-0.6.6ubuntu1/lib/benl_lexer.mll0000644000000000000000000000772212233760077014113 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) { open Benl_error open Benl_base open Benl_parser let id_from_token s = match (String.lowercase s) with | "true" -> TRUE | "false" -> FALSE | _ -> IDENT s } let space = [' ' '\t'] let field_name = ['a'-'z' 'A'-'Z' '-' '_' '0'-'9']+ let field_value = ([^ '\n'] | '\n' space)* rule stanza empty accu = parse | (field_name as name) space* ":" space* (field_value as value) '\n'? { let name = String.lowercase name in stanza false ((name, value)::accu) lexbuf } | '\n'+ | eof { if empty then Pervasives.raise End_of_file else List.rev accu } and token = parse | '.' (field_name as name) { FIELD name } | "source" { SOURCE } | '=' { EQ } | "<=" { LE } | ("<" | "<<") { LT } | ">=" { GE } | (">" | ">>") { GT } | '~' { MATCH } | '|' { OR } | '&' { AND } | '!' { NOT } | '(' { LPAREN } | ')' { RPAREN } | '[' { LBRACKET } | ']' { RBRACKET } | ';' { SEMICOLON } | field_name as id { id_from_token id } | '#' { comment lexbuf } | ('"'|"'") as c { STRING (string c (Buffer.create 128) lexbuf) } | '@' (_ as c) | ('/' as c) { REGEXP (regexp c (Buffer.create 32) lexbuf) } | '\n' { Lexing.new_line lexbuf; token lexbuf } | space { token lexbuf } | _ as c { let pos = Lexing.lexeme_start_p lexbuf in raise (Unexpected_char (pos.Lexing.pos_fname, c, pos.Lexing.pos_lnum, pos.Lexing.pos_cnum-pos.Lexing.pos_bol)) } | eof { EOF } and regexp separator buf = parse | _ as c { if c = separator then let res = Buffer.contents buf in let reg = Pcre.regexp res in (res, reg) else begin Buffer.add_char buf c; if c = '\n' then Lexing.new_line lexbuf; regexp separator buf lexbuf end } and string separator buf = parse | _ as c { if c = separator then Buffer.contents buf else begin Buffer.add_char buf c; if c = '\n' then Lexing.new_line lexbuf; string separator buf lexbuf end } and comment = parse | '\n' { Lexing.new_line lexbuf; token lexbuf } | _ { comment lexbuf } { let stanza_fold f lexbuf accu = let rec loop accu = let stanza = try Some (stanza true [] lexbuf) with End_of_file -> None in match stanza with | None -> accu | Some x -> loop (f x accu) in loop accu } ben-0.6.6ubuntu1/lib/benl_parser.mly0000644000000000000000000000466012233757266014311 0ustar /**************************************************************************/ /* Copyright © 2009 Stéphane Glondu */ /* */ /* This program is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU Affero General Public License as */ /* published by the Free Software Foundation, either version 3 of the */ /* License, or (at your option) any later version, with the additional */ /* exemption that compiling, linking, and/or using OpenSSL is allowed. */ /* */ /* 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 */ /* Affero General Public License for more details. */ /* */ /* You should have received a copy of the GNU Affero General Public */ /* License along with this program. If not, see */ /* . */ /**************************************************************************/ %{ open Benl_types %} %token FIELD %token REGEXP %token MATCH OR AND NOT LPAREN RPAREN EOF SOURCE %token TRUE FALSE LBRACKET RBRACKET SEMICOLON %token STRING IDENT %token LE LT GT GE EQ %left OR %left AND %nonassoc NOT %start full_expr %start config_file %% full_expr: | e = expr EOF { e } expr: | e1 = expr OR e2 = expr { EOr (e1, e2) } | e1 = expr AND e2 = expr { EAnd (e1, e2) } | TRUE { Etrue } | FALSE { Efalse } | c = comparison x = STRING { EVersion (c, x) } | NOT e = expr { ENot e } | n = FIELD MATCH p = predicate { EMatch (n, p) } | LPAREN e = expr RPAREN { e } | SOURCE { ESource } | LBRACKET xs = separated_list(SEMICOLON, expr) RBRACKET { EList xs } | x = STRING { EString x } predicate: | x = REGEXP { ERegexp x } | x = STRING { EString x } | x = STRING c = comparison v = STRING { EDep (x, c, v) } comparison: | LE { Le } | LT { Lt } | EQ { Eq } | GE { Ge } | GT { Gt } config_item: | i = IDENT EQ e = expr SEMICOLON { (i, e) } config_file: | xs = list(config_item) EOF { xs } ben-0.6.6ubuntu1/lib/benl_error.ml0000644000000000000000000000700112233760077013737 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf type error = | Illegal_escape of char | Unknown_error of exn | Nothing_to_download | Curl_error of int | Unexpected_char of string * char * int * int | Bad_marshalled_data of string | Unknown_command of string | Unknown_output_format of string | Unexpected_expression of string | Error_in_configuration_file of string | Missing_configuration_item of string | Unknown_configuration_item of string | Parsing_error of string * int * int | Template_not_found of string | Dynlink_error of Dynlink.error exception Error of error let string_of_error = function | Illegal_escape c -> sprintf "illegal escape of %C" c | Unknown_error e -> sprintf "unexpected error: %s" (Printexc.to_string e) | Curl_error r -> sprintf "curl exited with return code %d" r | Nothing_to_download -> sprintf "nothing to download" | Unexpected_char (file, c, line, column) -> sprintf "unexpected char %C in file %S, line %d, position %d" c file line column | Bad_marshalled_data s -> sprintf "bad marshalled data in %s" s | Unknown_command s -> sprintf "unknown command: %s" s | Unknown_output_format s -> sprintf "unknown output format: %s" s | Unexpected_expression s -> sprintf "unexpected expression: %s" s | Error_in_configuration_file s -> sprintf "error in configuration file: %s" s | Missing_configuration_item s -> sprintf "missing configuration item: %s" s | Unknown_configuration_item s -> sprintf "unknown configuration item: %s" s | Parsing_error (file, line, column) -> sprintf "parse error in file %S, line %d, character %d" file line column | Template_not_found name -> sprintf "template %s not found" name | Dynlink_error e -> sprintf "Dynlink error: %s" (Dynlink.error_message e) let () = Printexc.register_printer (function | Error exn -> Some ("ben-specific error: " ^ (string_of_error exn)) | _ -> None ) let raise e = Pervasives.raise (Error e) let warn e = Printf.eprintf "W: %s\n%!" (string_of_error e) ben-0.6.6ubuntu1/lib/benl_modules.ml0000644000000000000000000000326512233757266014274 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) module PAIndex = struct type t = [`binary] Package.Name.t * string let compare = Pervasives.compare end module PAMap = Map.Make(PAIndex) module Marshallable = struct let magic_number = "BENA0901" type t = { src_map : ([`source], [`source] Package.t) Package.Map.t; bin_map : [`binary] Package.t PAMap.t } end ben-0.6.6ubuntu1/lib/libbenl.clib0000644000000000000000000000001412233757266013521 0ustar benl_dpkg.o ben-0.6.6ubuntu1/lib/package.mli0000644000000000000000000000554212233760077013362 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_types type 'a t module Name : sig type 'a t val of_string : string -> 'a t val to_string : 'a t -> string end val get : string -> 'a t -> string val add : string -> string -> 'a t -> 'a t val print : out_channel -> 'a t -> unit val filter_print : string list -> out_channel -> 'a t -> unit module Set : sig type 'a t val empty : 'a t val is_empty : 'a t -> bool val add : 'a Name.t -> 'a t -> 'a t val mem : 'a Name.t -> 'a t -> bool val exists : ('a Name.t -> bool) -> 'a t -> bool val iter : ('a Name.t -> unit) -> 'a t -> unit val cardinal : 'a t -> int val elements : 'a t -> 'a Name.t list val fold : ('a Name.t -> 'b -> 'b) -> 'a t -> 'b -> 'b end val of_assoc : ([< `binary | `source] as 'a) -> (string * string) list -> 'a t module Map : sig type ('a, 'b) t val empty : ('a, 'b) t val add : 'a Name.t -> 'b -> ('a, 'b) t -> ('a, 'b) t val find : 'a Name.t -> ('a, 'b) t -> 'b val iter : ('a Name.t -> 'b -> unit) -> ('a, 'b) t -> unit val mapi : ('a Name.t -> 'b -> 'c) -> ('a, 'b) t -> ('a, 'c) t val fold : ('a Name.t -> 'b -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c val bindings : ('a, 'b) t -> ('a Name.t * 'b) list val update_default : 'b -> ('b -> 'b) -> 'a Name.t -> ('a, 'b) t -> ('a, 'b) t end val build_depends : [`source] t -> [`binary] Name.t list val binaries : [`source] t -> [`binary] Name.t list type dependency = { dep_name : string; dep_version : (comparison * string) option; } val dependencies : string -> 'a t -> dependency list ben-0.6.6ubuntu1/lib/query.mli0000644000000000000000000000327612233757266013144 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) type t val of_expr : Benl_types.expr -> t val of_string : string -> t val to_string : ?escape:bool -> t -> string val fields : Benl_base.Fields.t -> t -> Benl_base.Fields.t val eval : ([> `source] as 'a) -> 'a Package.t -> t -> bool val eval_source : [`source] Package.t -> t -> bool val eval_binary : [`binary] Package.t -> t -> bool ben-0.6.6ubuntu1/lib/benl_templates.ml0000644000000000000000000000444512235722600014605 0ustar (**************************************************************************) (* Copyright © 2012 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_error open Template let template : Template.t option ref = ref None let path = "/usr/lib/ben/templates" let (//) = Filename.concat let register_template t = template := Some t let template_not_found name = Benl_error.raise (Benl_error.Template_not_found name) let load_template name = let file = let cma = Dynlink.adapt_filename (Printf.sprintf "%s.cma" name) in let filepath = path // cma in if Sys.file_exists filepath then filepath else if Sys.file_exists name then name else if Sys.file_exists cma then cma else template_not_found name in try Dynlink.loadfile file with Dynlink.Error e -> Benl_error.raise (Dynlink_error e) let get_registered_template () = match !template with | Some t -> t | None -> let name = "debian" in let () = load_template name in begin match !template with | Some t -> t | None -> template_not_found name end ben-0.6.6ubuntu1/lib/benl_clflags.ml0000644000000000000000000000540212233760077014224 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_error let get_env_default var default = try Sys.getenv var with Not_found -> default let dry_run = ref false let verbose = ref false let architectures = ref !Benl_base.debian_architectures let cache_dir = ref (get_env_default "BEN_CACHE_DIR" (Sys.getcwd ())) let cache_file = ref "ben.cache" let use_cache = ref false let media_dir = ref (get_env_default "BEN_MEDIA_DIR" "/usr/share/ben/media") let mirror_binaries = ref "http://ftp.fr.debian.org/debian" let mirror_sources = ref "http://ftp.fr.debian.org/debian" let mirror = mirror_binaries let suite = ref "unstable" let areas = ref ["main"; "contrib"; "non-free"] let quiet = ref false let reset () = let () = architectures := !Benl_base.debian_architectures in let () = suite := "unstable" in let () = areas := ["main"; "contrib"; "non-free"] in () let config : Benl_types.config ref = ref [] let get_config key = try List.assoc key !config with Not_found -> raise (Missing_configuration_item key) let get_cache_file ?(name = !cache_file) () = if Sys.file_exists name then name else let filecache = Filename.concat !cache_dir name in if Sys.file_exists filecache then filecache else name (* Let the system generate an error *) let progress fmt = if !quiet then Printf.ifprintf stderr fmt else Printf.fprintf stderr (fmt^^"%!") ben-0.6.6ubuntu1/lib/benl_lexer.mli0000644000000000000000000000335112233760077014102 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) (** Lexing rules *) val token : Lexing.lexbuf -> Benl_parser.token (** Tokenizer for [Benl_parser]. *) val stanza_fold : ((string * string) list -> 'a -> 'a) -> Lexing.lexbuf -> 'a -> 'a (** [stanza_fold f lexbuf accu] iterates [f] over all stanzas of [lexbuf], using [accu] as accumulator. *) ben-0.6.6ubuntu1/lib/benl_frontend.ml0000644000000000000000000001375612233760077014443 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_error open Benl_types type frontend = { name : string; main : string list -> unit; help : unit -> unit } let frontends = ref [] let register_frontend sc = frontends := (sc.name, sc) :: !frontends let get_frontend x = try List.assoc x !frontends with Not_found -> raise (Unknown_command x) let available_frontends () = List.map fst !frontends let to_cmd x = let n = String.length x in if n > 4 && String.sub x 0 4 = "ben-" then String.sub x 4 (n-4) else x let fail fmt = Printf.ksprintf (fun x -> raise (Error_in_configuration_file x)) fmt let check_string what = function | EString s -> s | _ -> fail "%s must be a string" what let check_string_list what = function | EList ys -> List.map begin function | EString s -> s | _ -> fail "%s must be a list of strings" what end ys | _ -> fail "%s must be a list of strings" what let read_config_file filename = let config = Benl_utils.parse_config_file filename in let rec process = function | ("mirror", x)::xs -> Benl_clflags.mirror_binaries := check_string "mirror" x; Benl_clflags.mirror_sources := check_string "mirror" x; process xs | ("mirror-binaries", x)::xs -> Benl_clflags.mirror_binaries := check_string "mirror-binaries" x; process xs | ("mirror-sources", x)::xs -> Benl_clflags.mirror_sources := check_string "mirror-sources" x; process xs | ("areas", x)::xs -> Benl_clflags.areas := check_string_list "areas" x; process xs | ("architectures", x)::xs -> Benl_clflags.architectures := check_string_list "architectures" x; process xs | ("suite", x)::xs -> Benl_clflags.suite := check_string "suite" x; process xs | x::xs -> x::(process xs) | [] -> [] in process config let rec parse_common_args = function | ("--dry-run" | "-n")::xs -> Benl_clflags.dry_run := true; parse_common_args xs | ("--quiet" | "-q")::xs -> Benl_clflags.quiet := true; parse_common_args xs | ("--verbose" | "-v")::xs -> Benl_clflags.verbose := true; parse_common_args xs | "--mirror"::x::xs -> Benl_clflags.mirror_binaries := x; Benl_clflags.mirror_sources := x; parse_common_args xs | "--mirror-binaries"::x::xs -> Benl_clflags.mirror_binaries := x; parse_common_args xs | "--mirror-sources"::x::xs -> Benl_clflags.mirror_sources := x; parse_common_args xs | "--areas"::x::xs -> Benl_clflags.areas := Benl_core.simple_split ',' x; parse_common_args xs | "--archs"::x::xs -> Benl_clflags.architectures := Benl_core.simple_split ',' x; parse_common_args xs | "--suite"::x::xs -> Benl_clflags.suite := x; parse_common_args xs | "--cache-dir"::x::xs -> Benl_clflags.cache_dir := x; parse_common_args xs | ("--config"|"-c")::x::xs -> Benl_clflags.config := read_config_file x; parse_common_args xs | ("--cache"|"-C")::x::xs -> Benl_clflags.cache_file := x; parse_common_args xs | "--use-cache"::xs -> Benl_clflags.use_cache := true; parse_common_args xs | x::xs -> x::(parse_common_args xs) | [] -> [] let print_help () = Printf.printf "Usage: %s command [options]\n%!" Sys.argv.(0); Printf.printf "List of available commands:\n%!"; List.iter (fun frontend -> Printf.printf " - %s\n%!" frontend; (get_frontend frontend).help () ) (available_frontends ()); Printf.printf "List of available options:\n%!"; List.iter (fun (option, desc) -> Printf.printf " * %s\t%s\n%!" option desc ) [ "--dry-run" , "Dry run"; "--quiet|-q", "Quiet mode"; "--verbose", "Verbose mode"; "--mirror", "Mirror to use"; "--mirror-binaries", "Mirror to use for binaries"; "--mirror-sources", "Mirror to use for sources"; "--areas", "Areas to consider"; "--archs", "Architectures to consider"; "--suite", "Suite"; "--cache-dir", "Path to cache dir"; "--config|-c", "Config file" ]; exit 0 let main () = match Array.to_list Sys.argv with | [] -> (* we assume Sys.argv.(0) is always here! *) assert false | _ :: ("-h"|"-help"|"--help") :: _ -> print_help () | cmd::xs -> let sc, args = try let cmd = to_cmd (Filename.basename cmd) in get_frontend cmd, xs with Error (Unknown_command _) -> match xs with | cmd::xs -> get_frontend cmd, xs | _ -> print_help () in Printexc.catch sc.main args ben-0.6.6ubuntu1/lib/query.ml0000644000000000000000000001115512233757266012766 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Benl_error open Benl_types open Benl_base type t = Benl_types.expr let of_expr x = x let of_string s = let lexbuf = Lexing.from_string s in Benl_parser.full_expr Benl_lexer.token lexbuf let parens show expr = if show then sprintf "(%s)" expr else expr let rec to_string_b ?(escape = true) last_op = function | EMatch (f, ERegexp r) -> sprintf ".%s ~ %s" f (string_of_regexp r) | ENot e -> sprintf "!%s" (to_string_b last_op e) | Etrue -> sprintf "true" | Efalse -> sprintf "false" | EAnd (e1, e2) -> parens (last_op <> "&" && last_op <> "") (sprintf "%s & %s" (to_string_b "&" e1) (to_string_b "&" e2)) | EOr (e1, e2) -> parens (last_op <> "|" && last_op <> "") (sprintf "%s | %s" (to_string_b "|" e1) (to_string_b "|" e2)) | EList xs -> sprintf "[%s]" (String.concat "; " (List.map (to_string_b "") xs)) | ESource -> "source" | EString x -> string_of_string escape x | EVersion (cmp, x) -> parens (last_op <> "") (sprintf ".%s \"%s\"" (string_of_cmp cmp) x) | EMatch (field, EDep (package, cmp, ref_version)) -> parens (last_op <> "") (sprintf ".%s ~ \"%s\" %s \"%s\"" field package (string_of_cmp cmp) ref_version) | EMatch (field, EString package) -> parens (last_op <> "") (sprintf ".%s ~ \"%s\"" field package) | x -> raise (Unexpected_expression "") let to_string ?(escape = true) = to_string_b ~escape "" let rec eval kind pkg = function | EMatch (field, ERegexp (r, rex)) -> begin try let value = Package.get field pkg in ignore (Pcre.exec ~rex value); true with Not_found -> false end | Etrue -> true | Efalse -> false | ESource -> kind = `source | EOr (e1, e2) -> eval kind pkg e1 || eval kind pkg e2 | EAnd (e1, e2) -> eval kind pkg e1 && eval kind pkg e2 | ENot e -> not (eval kind pkg e) | EVersion (cmp, ref_version) -> let value = Package.get "version" pkg in version_compare cmp value ref_version | EMatch (field, EDep (package, cmp, refv)) -> let deps = Package.dependencies field pkg in List.exists (fun x -> x.Package.dep_name = package && begin match x.Package.dep_version with | None -> false | Some (rcmp, rrefv) -> match rcmp, cmp with | Ge, Ge | Gt, Ge | Gt, Gt -> Version.compare rrefv refv >= 0 | Ge, Gt -> Version.compare rrefv refv > 0 | _, _ -> false (* FIXME: missing cases *) end) deps | EMatch (field, EString package) -> let deps = Package.dependencies field pkg in List.exists (fun x -> x.Package.dep_name = package) deps | x -> raise (Unexpected_expression (to_string x)) let eval_source x = eval `source x let eval_binary x = eval `binary x let rec fields accu = function | EMatch (f, _) -> Fields.add f accu | ENot e -> fields accu e | Etrue | Efalse -> accu | EAnd (e1, e2) | EOr (e1, e2) -> fields (fields accu e1) e2 | EList xs -> List.fold_left fields accu xs | ESource | EString _ | ERegexp _ | EDep _ -> accu | EVersion _ -> Fields.add "version" accu ben-0.6.6ubuntu1/lib/benl_error.mli0000644000000000000000000000447012233760077014117 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) type error = | Illegal_escape of char | Unknown_error of exn | Nothing_to_download | Curl_error of int | Unexpected_char of string * char * int * int | Bad_marshalled_data of string | Unknown_command of string | Unknown_output_format of string | Unexpected_expression of string | Error_in_configuration_file of string | Missing_configuration_item of string | Unknown_configuration_item of string | Parsing_error of string * int * int | Template_not_found of string | Dynlink_error of Dynlink.error (** The type of Ben-specific errors *) exception Error of error (** All Ben-specific errors are wrapped into this exception. *) val string_of_error : error -> string (** Return a human-readable explanation of an error. *) val raise : error -> 'a (** Wrapper around [Pervasives.raise] to raise a Ben exception. *) val warn : error -> unit (** Emit a warning. *) ben-0.6.6ubuntu1/lib/benl.mllib0000644000000000000000000000025212233760077013216 0ustar Benl_modules Benl_core Benl_error Benl_base Benl_clflags Benl_frontend Benl_lexer Benl_parser Package Query Dependencies Benl_marshal Benl_utils Benl_templates Benl_data ben-0.6.6ubuntu1/lib/dependencies.mli0000644000000000000000000000322212233760077014406 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) val get_dep_graph : ([`source], [`source] Package.t) Package.Map.t -> ([`binary], [`source] Package.Name.t) Package.Map.t -> ([`source], [`source] Package.Set.t) Package.Map.t val topo_split : ([`source], [`source] Package.Set.t) Package.Map.t -> [`source] Package.Name.t list list ben-0.6.6ubuntu1/lib/benl_marshal.ml0000644000000000000000000000414612233760077014244 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_core open Benl_base open Benl_error module type MARSHALLABLE = sig type t val magic_number : string end module Make (I : MARSHALLABLE) = struct let load filename = with_in_file filename begin fun ic -> let n = String.length I.magic_number in let buf = String.create n in really_input ic buf 0 n; if buf = I.magic_number then begin (input_value ic : I.t) end else begin raise (Bad_marshalled_data filename) end end let dump filename (data : I.t) = with_out_file filename begin fun ic -> output_string ic I.magic_number; output_value ic data end end ben-0.6.6ubuntu1/lib/benl_dpkg.c0000644000000000000000000000404512233757266013360 0ustar /* * libdpkg - Debian packaging suite library routines * vercmp.c - comparison of version numbers * * Copyright © 1995 Ian Jackson * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 . */ /* Stolen from dpkg 1.15.7.2 by Stéphane Glondu , on Tue, 27 Jul 2010 11:56:30 -0400 (compliant to policy 3.9.0). */ #include #include int cisdigit(int c) { return (c>='0') && (c<='9'); } int cisalpha(int c) { return ((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')); } /* assume ascii; warning: evaluates x multiple times! */ #define order(x) ((x) == '~' ? -1 \ : cisdigit((x)) ? 0 \ : !(x) ? 0 \ : cisalpha((x)) ? (x) \ : (x) + 256) static int verrevcmp(const char *val, const char *ref) { if (!val) val= ""; if (!ref) ref= ""; while (*val || *ref) { int first_diff= 0; while ( (*val && !cisdigit(*val)) || (*ref && !cisdigit(*ref)) ) { int vc= order(*val), rc= order(*ref); if (vc != rc) return vc - rc; val++; ref++; } while ( *val == '0' ) val++; while ( *ref == '0' ) ref++; while (cisdigit(*val) && cisdigit(*ref)) { if (!first_diff) first_diff= *val - *ref; val++; ref++; } if (cisdigit(*val)) return 1; if (cisdigit(*ref)) return -1; if (first_diff) return first_diff; } return 0; } CAMLprim value caml_verrevcmp(value a, value b) { CAMLparam2(a, b); CAMLreturn(Val_int(verrevcmp(String_val(a), String_val(b)))); } ben-0.6.6ubuntu1/lib/benl_utils.mli0000644000000000000000000000357012233757266014134 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) val parse_control_in_channel : ([< `binary | `source] as 'a) -> string -> in_channel -> (string -> bool) -> ('a Package.Name.t -> 'a Package.t -> 'b -> 'b) -> 'b -> 'b val parse_control_file : ([< `binary | `source] as 'a) -> string -> (string -> bool) -> ('a Package.Name.t -> 'a Package.t -> 'b -> 'b) -> 'b -> 'b val parse_config_file : string -> Benl_types.config val file_content : string -> string val dump_to_file : string -> string -> unit val dump_xhtml_to_file : string -> Xhtml.M.html -> unit ben-0.6.6ubuntu1/lib/benl_frontend.mli0000644000000000000000000000362612233760077014607 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) type frontend = { name : string; main : string list -> unit; help : unit -> unit } val register_frontend : frontend -> unit val get_frontend : string -> frontend val available_frontends : unit -> string list val parse_common_args : string list -> string list val check_string : string -> Benl_types.expr -> string val check_string_list : string -> Benl_types.expr -> string list val read_config_file : string -> (string * Benl_types.expr) list val main : unit -> unit ben-0.6.6ubuntu1/lib/benl_core.ml0000644000000000000000000000606012233760077013542 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) let with_in_channel chan f = try let res = f chan in close_in chan; res with e -> close_in chan; raise e let with_in_file file f = let chan = open_in_bin file in try let res = f chan in close_in chan; res with e -> close_in chan; raise e let with_out_file file f = let chan = open_out_bin file in try let res = f chan in close_out chan; res with e -> close_out chan; raise e let escape_for_shell str = let buf = Buffer.create (2 * String.length str) in Buffer.add_char buf '\''; String.iter (function | '\'' -> Buffer.add_string buf "'\\''" | c -> Buffer.add_char buf c) str; Buffer.add_char buf '\''; Buffer.contents buf let get_rfc2822_date () = let chan = Unix.open_process_in "date -R" in let r = input_line chan in match Unix.close_process_in chan with | Unix.WEXITED 0 -> r | _ -> failwith "unexpected return of date" let list_iteri f xs = let rec aux i = function | [] -> () | x::xs -> f i x; aux (i+1) xs in aux 0 xs let list_rev_mapi f xs = let rec aux i accu = function | [] -> accu | x::xs -> aux (i+1) ((f i x)::accu) xs in aux 0 [] xs let simple_split delim str = let n = String.length str in let rec aux i accu = if i < n then let j = try String.index_from str i delim with Not_found -> n in aux (j+1) (String.sub str i (j-i) :: accu) else List.rev accu in aux 0 [] let starts_with str x = let n = String.length str and p = String.length x in n > p && String.sub str 0 p = x let ends_with str x = let n = String.length str and p = String.length x in n > p && String.sub str (n-p) p = x ben-0.6.6ubuntu1/lib/benl_base.ml0000644000000000000000000000753412233760077013533 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_core open Benl_error open Benl_types open Printf module Fields = Set.Make(String) let choose_escape str xs = let rec loop = function | c::cs -> if String.contains str c then loop cs else c | _ -> Pervasives.raise Not_found in loop xs let string_of_regexp (regexp, _) = let escape = choose_escape regexp ['/'; '@'; ','; '%'] in if escape = '/' then sprintf "/%s/" regexp else sprintf "@%c%s%c" escape regexp escape let string_of_cmp = function | Le -> "<=" | Lt -> "<<" | Eq -> "=" | Gt -> ">>" | Ge -> ">=" let string_of_string escaping string = if escaping then let escape = choose_escape string ['"'; '\''] in sprintf "%c%s%c" escape string escape else string let debian_architectures = ref [ "amd64"; "armel"; "i386"; "ia64"; "kfreebsd-amd64"; "kfreebsd-i386"; "mips"; "mipsel"; "powerpc"; "s390"; "sparc" ] let ignored_architectures : string list ref = ref [] let debian_ports_architectures = [ "armhf"; "avr32"; "m68k"; "powerpcspe"; "sh4"; "sparc64" ] type status = Unknown | Up_to_date | Outdated let string_of_status = function | Unknown -> " " | Up_to_date -> "✔" | Outdated -> "✘" let class_of_status = function | Unknown -> "unknown" | Up_to_date -> "good" | Outdated -> "bad" module Version : sig type t = string val compare : t -> t -> int end = struct type t = string external verrevcmp : string -> string -> int = "caml_verrevcmp" let decomp = let rex = Pcre.regexp "^(?:(\\d+):)?(?:([^\\s-]+)|(\\S+)-([^\\s-]+))$" in fun x -> try let r = Pcre.exec ~rex x in let epoch = try int_of_string (Pcre.get_substring r 1) with Not_found -> 0 in let upstream = try Pcre.get_substring r 2 with Not_found -> Pcre.get_substring r 3 in let debian = try Pcre.get_substring r 4 with Not_found -> "0" in (epoch, upstream, debian) with Not_found -> ksprintf invalid_arg "invalid version number: %s" x let compare x y = let (x1, x2, x3) = decomp x and (y1, y2, y3) = decomp y in let (>>=) x f = if x = 0 then f () else x in let cmp x y () = verrevcmp x y in x1 - y1 >>= cmp x2 y2 >>= cmp x3 y3 end let version_compare cmp x y = let d = Version.compare x y in match cmp with | Eq -> d = 0 | Ge -> d >= 0 | Gt -> d > 0 | Le -> d <= 0 | Lt -> d < 0 ben-0.6.6ubuntu1/lib/template.mli0000644000000000000000000000411712233760077013577 0ustar (**************************************************************************) (* Copyright © 2012 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) type page_t = title: string -> subtitle: Xhtml_types.h2_content Xhtml.M.elt list -> headers: [ `Link | `Meta | `Object | `Script | `Style ] Xhtml.M.elt list -> body: Xhtml_types.div_content Xhtml.M.elt list -> footer: Xhtml_types.div_content Xhtml.M.elt list -> Xhtml.M.html type t = { name : string ; page : page_t; intro : Xhtml_types.div_content Xhtml.M.elt list; changelog : letter:string -> src:string -> ver:string -> string; buildd : src:string -> ver:string -> string; buildds : srcs:string list -> string option; pts : src:string -> string; msg_id : mid:string -> string; bugs : src:string -> string; critical_bugs : srcs:string list -> string option; } ben-0.6.6ubuntu1/lib/dependencies.ml0000644000000000000000000000750512233760077014245 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Benl_core open Benl_base open Benl_types module M = Package.Map module S = Package.Set module N = Package.Name module I = struct type t = int let compare = ( - ) end module G = struct module V = struct type t = [`source] N.t let equal = (=) let hash = Hashtbl.hash let compare = Pervasives.compare end type t = ([`source], [`source] S.t) M.t let iter_vertex f graph = M.iter (fun k _ -> f k) graph let iter_succ f graph pkg = S.iter f (M.find pkg graph) end module C = Graph.Components.Make(G) module T = Set.Make(I) let get_dep_graph src bin = M.mapi (fun name pkg -> let deps = Package.build_depends pkg in List.fold_left (fun accu dep -> try S.add (M.find dep bin) accu with Not_found -> accu) S.empty deps) src let compute_levels graph = let n, f = C.scc graph in let visited = Array.make n (-1) in let to_visit = Array.make n None in M.iter (fun node children -> let inode = f node in let c = match to_visit.(inode) with | None -> T.empty | Some c -> c in to_visit.(inode) <- Some (S.fold (fun child accu -> T.add (f child) accu ) children c) ) graph; Array.iteri (fun i x -> match x with | None -> failwith "error in SCC computation" | Some c -> to_visit.(i) <- Some (T.remove i c) ) to_visit; let rec visit node = let i = visited.(node) in if i >= 0 then i else ( match to_visit.(node) with | None -> failwith "cycle detected in SCC graph" | Some children -> to_visit.(node) <- None; let i = T.fold (fun child i -> max i (visit child) ) children (-1) in let i = i + 1 in visited.(node) <- i; i ) in for i = 0 to n - 1 do let (_ : int) = visit i in () done; M.mapi (fun pkg _ -> visited.(f pkg)) graph let rev_cons_if_not_empty xs ys = match xs with | [] -> ys | _ :: _ -> List.rev xs :: ys let rec lvlist_to_listlist last accu result = function | [] -> List.rev (rev_cons_if_not_empty accu result) | (i, pkg) :: xs -> if i = last then lvlist_to_listlist i (pkg :: accu) result xs else lvlist_to_listlist i [pkg] (rev_cons_if_not_empty accu result) xs let topo_split dgraph = let levels = compute_levels dgraph in let packages = List.map (fun (s, n) -> n, s) (M.bindings levels) in let packages = List.sort compare packages in lvlist_to_listlist 0 [] [] packages ben-0.6.6ubuntu1/lib/benl_types.mli0000644000000000000000000000416412233757266014140 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) (** Ben-specific basic datatypes. *) type field = string (** A field name *) type regexp = string * Pcre.regexp (** A pair of a PCRE regexp and its string representation (as parsed from configuration, used for pretty-printing). *) type comparison = Le | Lt | Eq | Gt | Ge type expr = | Etrue | Efalse | EMatch of field * expr | ENot of expr | EAnd of expr * expr | EOr of expr * expr | ESource | EList of expr list | EString of string | ERegexp of regexp | EVersion of comparison * string | EDep of string * comparison * string (** The abstract syntax tree of configuration items. *) type config = (string * expr) list (** The type of parsed configuration files. Configuration files are key-value pairs, where values have type [expr]. *) ben-0.6.6ubuntu1/.header0000644000000000000000000000150412233760077011741 0ustar Copyright © 2009-2013 Stéphane Glondu © 2010-2013 Mehdi Dogguy This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version, with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ben-0.6.6ubuntu1/Makefile0000644000000000000000000000677212235727344012166 0ustar ########################################################################## # Copyright © 2009-2013 Stéphane Glondu # # © 2010-2013 Mehdi Dogguy # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU Affero General Public License as # # published by the Free Software Foundation, either version 3 of the # # License, or (at your option) any later version, with the additional # # exemption that compiling, linking, and/or using OpenSSL is allowed. # # # # 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 # # Affero General Public License for more details. # # # # You should have received a copy of the GNU Affero General Public # # License along with this program. If not, see # # . # ########################################################################## # Configuration NAME := ben PREFIX := /usr/local # Auto-detection ifeq ($(OCAMLBEST),) HAS_OPT := $(shell if which ocamlopt > /dev/null; then echo yes; fi) else ifeq ($(OCAMLBEST),native) HAS_OPT := yes else HAS_OPT := endif OCAML_STDLIB_DIR ?= $(shell /usr/bin/ocamlc -where) HAS_NATDYN = PLUGIN_EXT = cma ifneq (,$(wildcard $(OCAML_STDLIB_DIR)/dynlink.cmxa)) HAS_NATDYN := yes PLUGIN_EXT := cmxs endif CLASSIC := $(if $(INSIDE_EMACS),-classic-display) ARCH := $(if $(HAS_NATDYN),native,byte) OCAMLBUILD := ocamlbuild $(CLASSIC) $(if $(HAS_OPT),,-byte-plugin) OCAMLBUILD_ENV := # Build TARGETS := lib/benl.cma $(if $(HAS_OPT),lib/benl.cmxa) bin/$(NAME).$(ARCH) modules.dot GENERATED := modules.png TEMPLATES := $(foreach TPL,$(wildcard templates/*),$(subst .ml,.$(PLUGIN_EXT),$(TPL))) # modules w/o interfaces EXTRA_FILES := $(shell find lib -iname "*.ml" | xargs -I {} sh -c "test -f '{}'i || echo '{}'") # C stubs magic for bytecode export CAML_LD_LIBRARY_PATH=$(CURDIR)/_build/lib # Installation BINDIR := $(DESTDIR)$(PREFIX)/bin PLUGINSDIR := $(DESTDIR)$(PREFIX)/lib/ben/templates all: ocamlbuild templates $(GENERATED) doc .PHONY: ocamlbuild doc clean env ocamlbuild: $(OCAMLBUILD_ENV) $(OCAMLBUILD) $(TARGETS) doc: $(MAKE) -C doc all typerex: OCAMLBUILD_ENV := OCAMLFIND_COMMANDS='ocamlc=ocp-ocamlc ocamlopt=ocp-ocamlopt' typerex: all %.png: ocamlbuild dot -Tpng $(patsubst %.png,_build/%.dot,$@) > $@ .PHONY: templates build-templates install-templates templates: build-templates build-templates: $(patsubst %,build-%,$(TEMPLATES)) build-templates/%: $(OCAMLBUILD_ENV) $(OCAMLBUILD) templates/$* install-templates: install -d $(PLUGINSDIR) $(MAKE) $(patsubst %,install-%,$(TEMPLATES)) install-templates/%: install _build/templates/$* $(PLUGINSDIR)/$* clean: $(OCAMLBUILD) -clean rm -f *~ */*~ $(GENERATED) env: @echo export CAML_LD_LIBRARY_PATH=$(CAML_LD_LIBRARY_PATH) .PHONY: install install: install-templates install -d $(BINDIR) install _build/bin/$(NAME).$(ARCH) $(BINDIR)/ben ocamlfind install $(NAME) $(wildcard $(addprefix _build/lib/,*.cmi *.mli *.cma *.cmx *.cmxa *.a *.so)) $(EXTRA_FILES) META ben-0.6.6ubuntu1/frontends/0000755000000000000000000000000012235724304012505 5ustar ben-0.6.6ubuntu1/frontends/ben_query.ml0000644000000000000000000001023012233760077015031 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Benl_base open Printf open Benl_modules module Marshal = Benl_marshal.Make(Marshallable) open Marshallable let sources_re = Pcre.regexp "Sources" let is_source x = try ignore (Pcre.exec ~rex:sources_re x); true with Not_found -> false let is_cache x = Benl_core.ends_with x ".cache" let usage cmd = fprintf stderr "Usage: %s [ file ... ]\n" cmd; exit 1 let filters = ref [] let rec parse_local_args = function | "-s"::s::xs -> filters := Benl_core.simple_split ',' s; filters := List.map String.lowercase !filters; parse_local_args xs | x::xs -> x::(parse_local_args xs) | [] -> [] let help () = printf " [options] [ file1 ... ]\n%!"; List.iter (fun (option , desc) -> Printf.printf " %s: %s\n%!" option desc ) [ "-s FIELD,FIELD,...", "Show only the body of these fields from the matching paragraphs"; ] let main args = let args = parse_local_args (Benl_frontend.parse_common_args args) in let query, files = match args with | query::files -> query, files | _ -> usage (sprintf "%s query" Sys.argv.(0)) in let query = Query.of_string query in let caches, files = List.partition is_cache files in let sources, packages = List.partition is_source files in let sources = caches @ sources and packages = caches @ packages in let print kind filename = let keep = fun f -> !filters = [] || List.mem (String.lowercase f) !filters in let eval e = fun _ p -> if e p query then Package.filter_print !filters stdout p in let accu = fun n p () -> eval (Query.eval kind) n p in match filename with | "-" -> Benl_utils.parse_control_in_channel kind "standard input" stdin keep accu () | filename when Benl_core.ends_with filename ".gz" -> let ic = Unix.open_process_in ("zcat " ^ filename) in Benl_core.with_in_channel ic begin fun ic -> Benl_utils.parse_control_in_channel kind filename ic keep accu () end | filename when Benl_core.ends_with filename ".bz2" -> let ic = Unix.open_process_in ("bzcat " ^ filename) in Benl_core.with_in_channel ic begin fun ic -> Benl_utils.parse_control_in_channel kind filename ic keep accu () end | filename when is_cache filename -> let filename = Benl_clflags.get_cache_file ~name:filename () in let { src_map = srcs; bin_map = bins } = Marshal.load filename in begin match kind with | `binary -> PAMap.iter (eval Query.eval_binary) bins | `source -> Package.Map.iter (eval Query.eval_source) srcs end | filename -> Benl_utils.parse_control_file kind filename keep accu () in List.iter (print `source) sources; List.iter (print `binary) packages;; let frontend = { Benl_frontend.name = "query"; Benl_frontend.main = main; Benl_frontend.help = help; } ben-0.6.6ubuntu1/frontends/ben_download.ml0000644000000000000000000001061312233760077015500 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* Copyright © 2013 Johannes Schauer *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Benl_core open Benl_base open Benl_error open Benl_data open Benl_modules module Marshal = Benl_marshal.Make(Marshallable) open Marshallable let p = Benl_clflags.progress let ( / ) = Filename.concat let download_sources () = if !Benl_clflags.areas = [] then raise Nothing_to_download; let wquiet = if !Benl_clflags.verbose then "" else "-s" in let dst = !Benl_clflags.cache_dir/"Sources" in let tmp = Filename.temp_file "Sources." "" in let commands = List.map (fun area -> let url = sprintf "%s/dists/%s/%s/source/Sources.bz2" !Benl_clflags.mirror_sources !Benl_clflags.suite area in if !Benl_clflags.dry_run then p "Would download %s\n" url; let cmd = sprintf "{ curl %s %s | bzcat >> %s; }" wquiet (escape_for_shell url) tmp in cmd) !Benl_clflags.areas in let cmd = sprintf "%s && mv %s %s" (String.concat " && " commands) tmp dst in if not !Benl_clflags.dry_run then begin if not !Benl_clflags.verbose then p "Downloading Sources..."; let r = Sys.command cmd in if not !Benl_clflags.verbose then p "\n"; if r <> 0 then raise (Curl_error r) else ignore (Sys.command (sprintf "rm -f %s" tmp)) end;; let download_binaries arch = if !Benl_clflags.areas = [] then raise Nothing_to_download; let wquiet = if !Benl_clflags.verbose then "" else "-s" in let dst = !Benl_clflags.cache_dir/"Packages_"^arch in let tmp = Filename.temp_file ("Packages.") "" in let commands = List.map (fun area -> let url = sprintf "%s/dists/%s/%s/binary-%s/Packages.bz2" !Benl_clflags.mirror_binaries !Benl_clflags.suite area arch in if !Benl_clflags.dry_run then p "Would download %s\n" url; let cmd = sprintf "{ curl %s %s | bzcat >> %s; }" wquiet (escape_for_shell url) tmp in cmd) !Benl_clflags.areas in let cmd = sprintf "%s && mv %s %s" (String.concat " && " commands) tmp dst in if not !Benl_clflags.dry_run then begin if not !Benl_clflags.verbose then p "Downloading Packages_%s..." arch; let r = Sys.command cmd in p "\n"; if r <> 0 then raise (Curl_error r) else ignore (Sys.command (sprintf "rm -f %s" tmp)) end;; let download_all () = download_sources (); List.iter download_binaries !Benl_clflags.architectures;; let save_cache () = if !Benl_clflags.use_cache then begin let src_raw = Benl_data.file_origin.get_sources M.empty in let bin_raw = List.fold_left Benl_data.file_origin.get_binaries PAMap.empty !Benl_clflags.architectures in let data = { src_map = src_raw; bin_map = bin_raw; } in let file = Benl_clflags.get_cache_file () in Marshal.dump file data; end let main args = ignore (Benl_frontend.parse_common_args args); download_all (); save_cache () let frontend = { Benl_frontend.name = "download"; Benl_frontend.main = main; Benl_frontend.help = fun () -> (); } ben-0.6.6ubuntu1/frontends/ben_monitor.ml0000644000000000000000000004545512235724264015374 0ustar (**************************************************************************) (* Copyright © 2009 Stéphane Glondu *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Benl_core open Benl_base open Benl_marshal open Xhtml.M module M = Package.Map module S = Package.Set let use_colors = ref false let output_file = ref None let baseurl = ref "file:///.." type output_type = Text | Xhtml | Levels let output_type = ref Levels let p = Benl_clflags.progress let ( // ) = Filename.concat let ( !! ) = Lazy.force let ( !!! ) = Package.Name.to_string let is_affected () = lazy (Query.of_expr (Benl_clflags.get_config "is_affected")) let is_good () = lazy (Query.of_expr (Benl_clflags.get_config "is_good")) let is_bad () = lazy (Query.of_expr (Benl_clflags.get_config "is_bad")) let to_forget = List.fold_left (fun accu x -> Benl_base.Fields.add x accu) Benl_base.Fields.empty [ "description"; ] open Benl_modules open Marshallable open Benl_data let format_arch x = let f = match x with | Unknown -> (fun x -> "."^x^".") | Up_to_date -> (fun x -> "("^x^")") | Outdated -> (fun x -> "["^x^"]") in let f = if !use_colors then match x with | Unknown -> f | Up_to_date -> (fun x -> "\027[32m"^(f x)^"\027[0m") | Outdated -> (fun x -> "\027[1m\027[31m"^(f x)^"\027[0m") else f in f let ben_webpage = "http://ben.debian.net" let print_dep_line src deps = printf "%s:" !!!src; S.iter (fun dep -> printf " %s" !!!dep) deps; printf "\n%!" let print_dep_graph x = M.iter print_dep_line x let rec parse_local_args = function | "--run-debcheck"::xs -> Benl_data.run_debcheck := true; parse_local_args xs | "--color"::xs -> use_colors := true; output_type := Text; parse_local_args xs | "--text"::xs -> output_type := Text; parse_local_args xs | "--html"::xs -> output_type := Xhtml; parse_local_args xs | "--use-projectb"::xs -> Benl_data.use_projectb := true; parse_local_args xs | ("--output"|"-o")::filename::xs -> output_file := Some filename; parse_local_args xs | "--template"::template::xs -> Benl_templates.load_template template; parse_local_args xs | x::xs -> x::(parse_local_args xs) | [] -> [] let help () = List.iter (fun (option , desc) -> Printf.printf " %s: %s\n%!" option desc ) [ "--run-debcheck", "Run dose-debcheck and add virtual .uninstallable field"; "--use-projectb", "Get package lists from Projectb database"; "--color", "Color if text output"; "--text", "Select text output format"; "--html", "Select HTML output format"; "--output|-o", "Select output file"; "--template", "Select an HTML template"; ] let check_media_dir base = let mediad = base // "media" in if not (Sys.file_exists mediad) then Unix.symlink !Benl_clflags.media_dir mediad else match (Unix.stat mediad).Unix.st_kind with | Unix.S_LNK -> let target = Unix.readlink mediad in if target != !Benl_clflags.media_dir then begin Unix.unlink mediad; Unix.symlink !Benl_clflags.media_dir mediad end | _ -> () let relevant_arch arch_ref arch_pkg = (arch_pkg = "all" && arch_ref = "i386") || arch_ref = arch_pkg let compute_state pkg = if Query.eval_binary pkg !!(is_bad ()) then Outdated else if Query.eval_binary pkg !!(is_good ()) then Up_to_date else Unknown let combine_states state1 state2 = match state1, state2 with | Outdated, _ | _, Outdated -> Outdated | Up_to_date, _ | _, Up_to_date -> Up_to_date | Unknown, Unknown -> state2 let compute_monitor_data sources binaries rounds = List.map begin fun xs -> let packages = List.sort (fun x y -> compare !!!x !!!y) xs in List.map begin fun sname -> let src = M.find sname sources in let src_name = Package.get "package" src in let states = List.map begin fun arch -> (* FIXME: indexing by name+arch is not a good idea after all *) arch, PAMap.fold (fun (_, arch') pkg accu -> if arch' = arch && Package.get "source" pkg = src_name then let state = compute_state pkg in combine_states accu state else accu ) binaries Unknown end !Benl_clflags.architectures in src, states end packages end rounds let print_text_monitor sources binaries rounds = let monitor_data = compute_monitor_data sources binaries rounds in let nmax = M.fold begin fun src _ accu -> let n = String.length !!!src in if n > accu then n else accu end sources 0 in let width = String.length (String.concat " " !Benl_clflags.architectures)+6+nmax in let nrounds = String.length (string_of_int (List.length rounds)) in let hwidth = String.length "> Dependency level <" + nrounds in let header_fmt = let width = width-hwidth+2 in let left = width/2 in let right = width-left in let buf = Buffer.create 64 in for i = 1 to left do Buffer.add_char buf '=' done; bprintf buf "> Dependency level %%%dd <" nrounds; for i = 1 to right do Buffer.add_char buf '=' done; Buffer.add_char buf '\n'; Scanf.format_from_string (Buffer.contents buf) "%d" in list_iteri begin fun i xs -> printf header_fmt i; List.iter begin fun (src, states) -> let in_testing = try not (Package.get "is-in-testing" src = "no") with Not_found -> true in let sname = Package.get "package" src in let sname = if in_testing then sname else "_"^sname in printf "%*s:" (nmax+3) sname; List.iter begin fun (arch, state) -> printf " %s" (format_arch state arch) end states; printf "\n"; end xs; printf "\n" end monitor_data let a_link url text = a ~a:[a_href (uri_of_string url)] [pcdata text] let escape = Netencoding.Url.encode let pts t src = a_link (t.Template.pts (escape src)) src let buildd t show src ver = if show then a_link (t.Template.buildd src ver) "build logs" else small [ pcdata "arch:all" ] let buildds t show srcs = match t.Template.buildds srcs with | None -> raise Exit | Some s -> a_link s "build logs" let rc_bugs t src = match t.Template.critical_bugs src with | None -> raise Exit | Some s -> a_link s "RC bugs" let changelog t ver dir src = small [ a_link ( t.Template.changelog dir src ver) ver ] let generated_on_text () = [ pcdata "Page generated by "; a_link ben_webpage "Ben"; pcdata (Printf.sprintf " on %s" (Benl_core.get_rfc2822_date ())); pcdata "; bzr branch "; a_link "https://code.launchpad.net/+branch/ubuntu-transition-tracker" "lp:ubuntu-transition-tracker" ] module SS = Set.Make(String) let overrall_state l = let _ (* ignored_archs *), release_archs = List.partition (fun (arch,_) -> List.mem arch !Benl_base.ignored_architectures) l in if List.for_all (fun (_,status) -> status = Unknown) release_archs then Unknown else if List.for_all (fun (_,status) -> status <> Outdated) release_archs then Up_to_date else Outdated let generate_stats monitor_data = List.fold_left (fun (all, bad, packages) level -> List.fold_left (fun (all, bad, packages) (package, statuses) -> let is_in_testing = try Package.get "is-in-testing" package = "yes" with _ -> false in let package = Package.Name.of_string (Package.get "package" package) in let overrall_state = overrall_state statuses in let packages = package::packages in let return all bad = all, bad, packages in match overrall_state with | Outdated when (not !Benl_data.use_projectb || is_in_testing) -> return (all+1) (bad+1) | Up_to_date -> return (all+1) bad | _ -> return all bad ) (all, bad, packages) level ) (0, 0, []) monitor_data let starts_with text head = let s = try String.sub text 0 (String.length head) with _ -> text in s = head let cut_head text head = try let len = String.length head in String.sub text len (String.length text - len) with _ -> text let beautify_text = let r_link = Pcre.regexp "#[0-9]{4,}|[a-z]{3,}://[^\\s><]+|<[^\\s><]+@[^\\s><]+>|[Pp][Tt][Ss]:[a-z0-9+\\-\\.]+|[Bb][Uu][Ii][Ll][Dd][Dd]:[a-z0-9+\\-\\.]+" in fun tpl text -> let t = Pcre.full_split ~rex:r_link text in List.map (function | Pcre.Text s -> pcdata s | Pcre.Delim s -> let l = String.lowercase s in if s.[0] = '#' then let ss = String.sub s 1 (String.length s -1) in let link = tpl.Template.bugs ss in a_link link s else if s.[0] = '<' then let ss = String.sub s 1 (String.length s - 2) in let link = tpl.Template.msg_id ss in a_link link s else if starts_with l "pts" then let text = cut_head s "pts:" in let link = tpl.Template.pts text in a_link link s else if starts_with l "buildd" then let text = cut_head s "buildd:" in let link = tpl.Template.buildd text "" in a_link link s else a_link s s | Pcre.Group _ | Pcre.NoGroup -> (* Ignore this case *) pcdata "" ) t let print_html_monitor template sources binaries dep_graph rounds = let monitor_data = compute_monitor_data sources binaries rounds in let all, bad, packages = generate_stats monitor_data in let affected = List.map (fun x -> Package.Name.of_string (Package.get "package" (fst x)) ) (List.flatten monitor_data) in let mytitle = try Query.to_string ~escape:false (Query.of_expr (Benl_clflags.get_config "title")) with _ -> "(no title)" in let notes = try Query.to_string ~escape:false (Query.of_expr (Benl_clflags.get_config "notes")) with _ -> "" in let is_affected = Query.to_string (Lazy.force (is_affected ())) in let is_good = Query.to_string (Lazy.force (is_good ())) in let is_bad = Query.to_string (Lazy.force (is_bad ())) in let archs_count = List.length !Benl_clflags.architectures in let has_testing_data = match monitor_data with | ((src, _) :: _) :: _ -> (* if is-in-testing has been injected, it has been injected into all packages, so just pick any *) (try let _ = Package.get "is-in-testing" src in true with Not_found -> false) | _ -> false in let page_title = sprintf "Transition: %s" mytitle in let extra_headers = [ script ~contenttype:"text/javascript" (pcdata (sprintf "var nb_columns = %d; var nb_rounds = %d;" (2 + archs_count) (List.length monitor_data)) ); script ~contenttype:"text/javascript" ~a:[a_src (uri_of_string "media/jquery.min.js")] (pcdata ""); script ~contenttype:"text/javascript" ~a:[a_src (uri_of_string ("media/script.js"))] (pcdata ""); ] in let hbody table = [ b [ pcdata "Parameters:" ]; ul~a:[ a_class ["parameters"] ] (li [ small [ b [ pcdata "Affected: " ]; pcdata is_affected ] ]) [li [ small [ b [ pcdata "Good: " ]; pcdata is_good ] ]; li [ small [ b [ pcdata "Bad: " ]; pcdata is_bad ] ]; ]; if String.length notes = 0 then div [ ] else div ~a:[ a_class ["parameters"] ] [ small [ b [ pcdata "Notes: " ] ]; pre ( beautify_text template notes ) ] ; div [ pcdata "Filter by status: "; input ~a:[a_input_type `Checkbox; a_id "good"] (); pcdata "good "; input ~a:[a_input_type `Checkbox; a_checked `Checked; a_id "bad"] (); pcdata "bad "; input ~a:[a_input_type `Checkbox; a_checked `Checked; a_id "unknown"] (); pcdata "unknown"; span ~a:[a_id "count"] []; ]; div (if has_testing_data then [ input ~a:[a_input_type `Checkbox; a_id "notintesting"] (); pcdata "ignore packages that are not in testing"; ] else [] ); table; ] in let footer = [ small (generated_on_text ()) ] in let abrege = function | "hurd-i386" -> "hurd" | "kfreebsd-amd64" -> "kbsd64" | "kfreebsd-i386" -> "kbsd32" | "powerpc" -> "ppc" | x -> x in let archs_columns = List.map begin fun arch -> th [ small [ pcdata (abrege arch) ] ] end !Benl_clflags.architectures in let archs_columns round header = tr ~a:[ a_id (sprintf "header%d" round) ] header archs_columns in let rows, _ = List.fold_left begin fun (rows, i) xs -> let names, rows = (List.fold_left begin fun (arch_any_s, acc) (source, states) -> let src = Package.get "package" source in let has_ma_same = List.exists (fun bin -> List.exists (fun arch -> try let pkg = PAMap.find (bin, arch) binaries in Package.get "multi-arch" pkg = "same" with Not_found -> false ) !Benl_clflags.architectures ) (Package.binaries source) in let has_ma_same_html = if has_ma_same then [ pcdata " ["; small [pcdata "ma:same"]; pcdata "]"; ] else [] in let in_testing = try not (Package.get "is-in-testing" source = "no") with Not_found -> true in let classes = [ "src"; sprintf "round%d" i ] @ (if in_testing then [] else ["notintesting"]) in let deps = S.elements (Package.Map.find (Package.Name.of_string src) dep_graph) in let deps = List.filter (fun p -> List.mem p affected) deps in let deps = match (List.map (!!!) deps) with | [] -> "" | _ as l-> "Dependencies: " ^ (String.concat ", " l) in let version = Package.get "version" source in let directory = Package.get "directory" source in let arch_any = Package.get "architecture" source <> "all" in let arch_any_s = if arch_any then src::arch_any_s else arch_any_s in let overrall_state = [ class_of_status (overrall_state states) ] in let src_text = (pts template src)::(if in_testing then [] else [pcdata " (sid only)"]) in arch_any_s, tr (td ~a:[ a_class ("srcname" :: (overrall_state @ classes)); a_id src; a_title deps ] src_text) ( td ~a:[ a_class [ "src"] ] ([ pcdata "["; buildd template arch_any (escape src) version; pcdata "] ("; changelog template (sprintf "%s" version) directory (escape src); pcdata ")" ] @ has_ma_same_html) :: (List.map begin fun (_, state) -> (td ~a:[ a_class [ Benl_base.class_of_status state ] ] [ small [ pcdata (Benl_base.string_of_status state) ] ]) end states) ) :: acc end ([], rows) (List.rev xs)) in let column_arg = try let buildd_link = if names = [] then small [ pcdata "arch:all" ] else buildds template true (List.map escape names) in let rc_bugs_link = rc_bugs template (List.map escape names) in [ pcdata " ("; buildd_link; pcdata " "; rc_bugs_link; pcdata ")" ] with Exit -> [] in archs_columns i (th ~a:[ a_colspan 2; a_class [ "level" ] ] (pcdata (sprintf "Dependency level %d" (i+1)) :: column_arg) ) :: rows, (i - 1) end ([], (List.length monitor_data - 1)) (List.rev monitor_data) in let table = table (tr (td [ pcdata "" ]) []) rows in let subtitle = [a_link (Filename.concat !baseurl "index.html") "Transitions"; pcdata (Printf.sprintf " → %s" mytitle) ] in let html = template.Template.page page_title subtitle extra_headers (hbody table) footer in (all, bad, packages, html) let print_dependency_levels dep_graph rounds = list_iteri begin fun i xs -> printf "===[ Dependency level %d ]=====\n" i; let packages = List.sort (fun x y -> compare !!!x !!!y) xs in List.iter begin fun src -> let deps = M.find src dep_graph in print_dep_line src deps end packages end rounds let compute_graph () = let {src_map = sources; bin_map = binaries} = get_data is_affected in let src_of_bin : ([`binary], [`source] Package.Name.t) M.t = PAMap.fold (fun (name, _) pkg accu -> let source = Package.get "source" pkg in M.add name (Package.Name.of_string source) accu) binaries M.empty in let dep_graph = Dependencies.get_dep_graph sources src_of_bin in let rounds = Dependencies.topo_split dep_graph in rounds, sources, binaries, dep_graph let main args = let _ = parse_local_args (Benl_frontend.parse_common_args args) in let rounds, sources, binaries, dep_graph = compute_graph () in match !output_type with | Levels -> print_dependency_levels dep_graph rounds | Text -> print_text_monitor sources binaries rounds | Xhtml -> let template = Benl_templates.get_registered_template () in let (_, _, _, output) = print_html_monitor template sources binaries dep_graph rounds in match !output_file with | None -> Xhtml.P.print print_string output; print_newline () | Some file -> check_media_dir (Filename.basename file); Benl_utils.dump_xhtml_to_file file output let frontend = { Benl_frontend.name = "monitor"; Benl_frontend.main = main; Benl_frontend.help = help; } ben-0.6.6ubuntu1/frontends/ben_tracker.ml0000644000000000000000000003076512235723041015326 0ustar (**************************************************************************) (* Copyright © 2011 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Xhtml.M open Printf open Benl_clflags open Benl_utils open Ben_monitor open Benl_error let ($) f x = f x let base = ref "." let config_dir = ref "config" let global_config = ref (FilePath.concat !config_dir "global.conf") let lock = ref "ben.lock" let update = ref false let tconfig = ref None let redownload = ref true open Benl_types open Benl_frontend let read_global_config () = if Sys.file_exists !global_config then begin let config = Benl_utils.parse_config_file !global_config in List.iter (function | "architectures", archs -> Benl_base.debian_architectures := check_string_list "architectures" archs | "ignored", archs -> Benl_base.ignored_architectures := check_string_list "ignored" archs | "suite", (EString suite) -> Benl_clflags.suite := suite | "areas", areas -> Benl_clflags.areas := check_string_list "areas" areas | "base", (EString path) -> base := path | "config-dir", (EString path) -> config_dir := path | "cache-dir", (EString dir) -> Benl_clflags.cache_dir := dir | "mirror-binaries", (EString mirror) -> Benl_clflags.mirror_binaries := mirror | "mirror-sources", (EString mirror) -> Benl_clflags.mirror_sources := mirror | "mirror", (EString mirror) -> Benl_clflags.mirror_sources := mirror; Benl_clflags.mirror_binaries := mirror | "use-cache", Etrue -> Benl_clflags.use_cache := true | "run-debcheck", Etrue -> Benl_data.run_debcheck := true | "use-projectb", Etrue -> Benl_data.use_projectb := true | "base-url", (EString url) -> Ben_monitor.baseurl := url | "template", (EString template) -> Benl_templates.load_template template; | "redownload", Efalse -> redownload := false | "output-type", (EString format) -> (match String.lowercase format with | "text" -> Ben_monitor.output_type := Text | "levels" -> Ben_monitor.output_type := Levels | "xhtml" -> Ben_monitor.output_type := Xhtml | format -> warn (Unknown_output_format format); Ben_monitor.output_type := Xhtml ) | item, _ -> warn (Unknown_configuration_item item) ) config end let lockf () = FilePath.concat !cache_dir !lock let rec parse_local_args = function | ("--config-dir"|"-cd")::x::xs -> config_dir := x; parse_local_args xs | ("--global-conf"|"-g")::x::xs -> global_config := x; parse_local_args xs | ("--transition"|"-t")::x::xs -> tconfig := Some x; parse_local_args xs | ("--update"|"-u")::xs -> update := true; parse_local_args xs | ("--base"|"-b")::x::xs -> base := x; parse_local_args xs | ("--use-projectb")::xs -> Benl_data.use_projectb := true; parse_local_args xs | "--template"::template::xs -> Benl_templates.load_template template; parse_local_args xs | x::xs -> x::(parse_local_args xs) | [] -> [] let help () = List.iter (fun (option , desc) -> printf " %s: %s\n%!" option desc ) [ "--base|-b [dir]", "Specifies the \"base\" directory."; "--config-dir|-cd [dir]", "Location of ben trackers"; "--transition|-t [profile/transition]", "Generate only that tracker page"; "--update|-u", "Updates cache files"; "--use-projectb", "Get package lists from Projectb database"; "--template", "Select an HTML template"; ] exception Unknown_profile of string type profile = Planned | Ongoing | Permanent | Finished | Old | Unknown let string_of_profile = function | Planned -> "planned" | Ongoing -> "ongoing" | Permanent -> "permanent" | Finished -> "finished" | Old -> "old" | Unknown -> "unknown" let profile_of_string = function | "planned" -> Planned | "ongoing" -> Ongoing | "permanent" -> Permanent | "finished" -> Finished | "old" -> Old | _ -> Unknown let profiles_desc = [ Planned , ( "Some planned transitions" , false ); Ongoing , ( "Ongoing transitions" , true ); Permanent , ( "Permanent trackers" , false ); Finished , ( "(almost) Finished transitions", true ); Old , ( "Old trackers" , false ); Unknown , ( "Miscellaneous transitions" , false ); ] open FileUtil let p = Benl_clflags.progress let is_packages_file name = try let name = String.sub (Filename.basename name) 0 9 in name = "Packages_" with _ -> false let clear_cache () = let cached = !cache_dir in let cachef = !cache_file in let test_cond = Basename_is cachef in let pkgs = find test_cond cached (fun x y -> y ::x) [] in rm ~force:Force pkgs let update_test () = let cachef = Benl_clflags.get_cache_file () in !update || test (Not Exists) cachef let update_cache () = let () = clear_cache () in if !redownload && not !Benl_data.use_projectb then Ben_download.download_all () let profile_of_file file = try profile_of_string $ Filename.basename (Filename.dirname file) with _ -> Unknown let run_monitor template file = let ($) = Filename.concat in let (!!) = Filename.basename in let profile = profile_of_file file in let transition = FilePath.chop_extension !!file in let () = p "Generating (%s) %s\n" (string_of_profile profile) transition in (* Reset config variables before reading .ben files *) let () = Benl_clflags.reset () in (* Read a .ben file *) let () = Benl_clflags.config := Benl_frontend.read_config_file file in let rounds, sources, binaries, dep_graph = compute_graph () in let all, bad, packages, output = Ben_monitor.print_html_monitor template sources binaries dep_graph rounds in let htmlf = FilePath.replace_extension !!file "html" in let htmlp = "html" $ htmlf in let html = !base $ htmlp in let export = try Benl_clflags.get_config "export" = Benl_types.Etrue with _ -> true in let result = all, bad, htmlp, profile, transition, packages, export in try Benl_utils.dump_xhtml_to_file html output; result with _ -> eprintf "Something bad happened while generating %s!\n" html; result module SMap = Map.Make(String) let sadd mp p t = let ts = try SMap.find p mp with _ -> [] in SMap.add p (t::ts) mp let generate_stats results = List.fold_left (fun (packages, profiles) (all, bad, htmlp, p, t, pkgs, export) -> let pkgs = List.map Package.Name.to_string pkgs in let profiles = sadd profiles (string_of_profile p) (htmlp, t, all, bad) in let packages = List.fold_left (fun packages package -> if export then sadd packages package (t, p, export) else packages ) packages pkgs in packages, profiles ) (SMap.empty, SMap.empty) results let dump_yaml smap file = let transition (name, profile, _) = sprintf "[ '%s' , '%s' ]" name (string_of_profile profile) in let file = Filename.concat !base (Filename.concat "export" file) in let string = SMap.fold (fun key list string -> let list = List.filter (fun (_,_,export) -> export) list in sprintf "%s- {'name': '%s',\n 'list': [%s]\n }\n" string key (String.concat ", " (List.map transition list)) ) smap "" in try mkdir ~parent:true (Filename.dirname file); let newfile = FilePath.add_extension file "new" in dump_to_file newfile string; mv newfile file with exc -> eprintf "E: %s\n" $ Printexc.to_string exc; Printexc.print_backtrace stderr; eprintf "Something bad happened while generating %s!\n" file let tracker template profiles = let page_title = "Transition tracker" in let footer = [ small (generated_on_text ()) ] in let tget show_score (path, name, all, bad) = li ( (Ben_monitor.a_link path name):: if show_score then let score = if all = 0 then 0 else 100*(all-bad)/all in [ pcdata (sprintf " (%d%%)" score) ] else [] ) in let contents = SMap.fold (fun profile tlist acc -> let title, show_score = try let profile = profile_of_string profile in List.assoc profile profiles_desc with _ -> List.assoc Unknown profiles_desc in let tlist = List.map (tget show_score) tlist in match tlist with | [] -> acc | h::l -> let tdiv = div ~a:[ a_class [ "transitions" ] ] [ b [ pcdata title ]; ul h l ] in tdiv::acc ) profiles [] in let contents = template.Template.intro @ contents in let index = Filename.concat !base "index.html" in let subtitle = [ pcdata "Transition tracker" ] in let output = template.Template.page page_title subtitle [] contents footer in try p "Generating index...\n"; dump_xhtml_to_file index output with exc -> eprintf "E: %s\n" $ Printexc.to_string exc; Printexc.print_backtrace stderr; eprintf "Something bad happened while generating index.html!\n" let () = at_exit (fun () -> rm [lockf ()] ) let main args = let _ = parse_local_args (Benl_frontend.parse_common_args args) in let () = read_global_config () in let lockf = lockf () in if test Exists lockf then eprintf "Please wait until %s is removed!\n" lockf else try touch lockf; if update_test () then update_cache (); let htmld = Filename.concat !base "html" in if test (Not Exists) htmld then mkdir ~parent:true htmld; Ben_monitor.check_media_dir !base; let confd = !config_dir in let test_cond = And (Size_not_null, And (Has_extension "ben", And (Is_file, Is_readable))) in let template = Benl_templates.get_registered_template () in let results = match !tconfig with (* Here we suppose that config is relative to base directory *) | Some transition -> let transition = Filename.concat !config_dir transition in [ run_monitor template transition ] | None -> find test_cond confd (fun results transition -> match profile_of_file transition with | Old -> results | _ -> try let result = run_monitor template transition in result :: results with Benl_error.Error e -> (* Ben file has errors *) warn e; results ) [] in (* Should we yell if all .ben files were broken? i.e. results == [] *) let packages, profiles = generate_stats results in let () = dump_yaml packages "packages.yaml" in (match !tconfig with | None -> tracker template profiles | Some _ -> ()) with exc -> eprintf "E: %s\n" $ Printexc.to_string exc; Printexc.print_backtrace stderr let frontend = { Benl_frontend.name = "tracker"; Benl_frontend.main = main; Benl_frontend.help = help; } ben-0.6.6ubuntu1/myocamlbuild.ml0000644000000000000000000001471212233760077013530 0ustar (**************************************************************************) (* Copyright © 2009-2013 Stéphane Glondu *) (* © 2010-2013 Mehdi Dogguy *) (* *) (* This program is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Affero General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version, with the additional *) (* exemption that compiling, linking, and/or using OpenSSL is allowed. *) (* *) (* 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 *) (* Affero General Public License for more details. *) (* *) (* You should have received a copy of the GNU Affero General Public *) (* License along with this program. If not, see *) (* . *) (**************************************************************************) open Printf open Ocamlbuild_plugin let name = "ben" let packages = [ "dynlink"; "unix"; "pcre"; "ocamlgraph"; "tyxml"; "fileutils"; "threads"; "postgresql"; ] exception Require_findlib exception Missing_findlib_package of string exception Subprocess_died_unexpectedly of Unix.process_status let try_exec cmd = Sys.command (sprintf "%s >/dev/null 2>&1" cmd) = 0 let require pkg = if not (try_exec (sprintf "ocamlfind query %s" pkg)) then raise (Missing_findlib_package pkg) let ocamlfind x = S[A"ocamlfind"; A x] let has_ocamlopt = try_exec "which ocamlopt" let best = try Sys.getenv "OCAMLBEST" with Not_found -> if has_ocamlopt then "native" else "byte" let () = if not (try_exec "ocamlfind printconf") then raise Require_findlib let () = List.iter require packages let main_executable = sprintf "bin/%s.%s" name best let () = dispatch begin function | Before_options -> Options.ocamlc := ocamlfind "ocamlc"; Options.ocamlopt := ocamlfind "ocamlopt"; Options.ocamldep := ocamlfind "ocamldep"; Options.ocamldoc := ocamlfind "ocamldoc"; Options.use_menhir := true; Options.ocaml_yaccflags := ["--explain"] | After_rules -> Pathname.define_context "lib/benlib" ["lib"]; Pathname.define_context "frontends" ["lib"]; Pathname.define_context "templates" ["lib"]; Pathname.define_context "bin" ["lib"; "frontends"]; flag ["ocaml"; "link"; "program"] & A"-linkpkg"; List.iter (fun pkg -> let flag x = flag (x::["ocaml"]) & S[A"-package"; A pkg] in List.iter flag ["ocamldep"; "compile"; "link"; "doc"]) packages; (* why isn't this done by default? *) flag ["library"; "link"; "thread"] (A"-thread"); (* C stubs *) flag ["link"; "library"; "ocaml"; "byte"; "use_libbenl"] (S[A"-dllib"; A"-lbenl"; A"-cclib"; A"-lbenl"]); flag ["link"; "library"; "ocaml"; "native"; "use_libbenl"] (S[A"-cclib"; A"-lbenl"]); flag ["link"; "library"; "ocaml"; "native"; "use_libbenl"] (S[A"-cclib"; A"-lbenl"]); flag ["link"; "program"; "ocaml"; "byte"; "use_libbenl"] (S[A"-dllib"; A"-lbenl"]); dep ["link"; "ocaml"; "use_libbenl"] ["lib/libbenl.a"]; (* rule for the main executable that will link all frontends *) rule "bin/ben.ml" ~deps:["bin/ben.mlp"] ~prod:"bin/ben.ml" begin let prefix = name^"_" in let p = String.length prefix in fun _ _ -> let files = Array.to_list (Sys.readdir "../frontends") in let static = List.filter (fun x -> let n = String.length x in n > p+5 && String.sub x 0 p = prefix && String.sub x (n-3) 3 = ".ml") files in let static = List.map (fun x -> (Filename.chop_suffix x ".ml")^".frontend") static in let static = String.concat "; " (List.map String.capitalize static) in Cmd (S [A"sed"; A"-e"; A (sprintf "s/@STATIC_FRONTENDS@/%s/" static); P"bin/ben.mlp"; Sh">"; P"bin/ben.ml"]) end; (* rule for dependency graph *) rule "modules.dot" ~deps:[main_executable] ~prod:"modules.dot" begin fun _ _ -> let ic = Unix.open_process_in "find -name '*.ml.depends'" in let buf = Buffer.create 1024 in bprintf buf "digraph build_graph {\n"; let rec loop accu = match (try Some (input_line ic) with End_of_file -> None) with | None -> accu | Some filename -> let node = let n = String.length filename in let j = n - String.length ".ml.depends" in let i = try String.rindex_from filename j '/' with Not_found -> 0 in String.capitalize (String.sub filename (i+1) (j-i-1)) in let deps = List.tl (string_list_of_file filename) in loop ((node, deps)::accu) in let deps_assoc = loop [] in let module S = Set.Make(String) in let mynodes = List.fold_left (fun accu (x, _) -> S.add x accu) S.empty deps_assoc in let () = List.iter (fun (x, deps) -> List.iter (fun dep -> if S.mem dep mynodes then bprintf buf " \"%s\" -> \"%s\";\n" x dep) deps) deps_assoc in bprintf buf "}\n"; begin match Unix.close_process_in ic with | Unix.WEXITED 0 -> () | e -> raise (Subprocess_died_unexpectedly e) end; Echo ([Buffer.contents buf], "modules.dot") end | _ -> () end