diff options
65 files changed, 3841 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2af088f --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/config.mk +/config.h +/config.sh +*.o +.*.mk +/*.tar.* +/*-[0-9]*/ +tmp.* @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 <http://www.gnu.org/licenses/>. + +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 +<http://www.gnu.org/licenses/>. @@ -0,0 +1,295 @@ +#!/bin/less + + Version 0.8c re-implements the wrapper in C, to allow better + cooperation between plugins via dependencies. This probably makes + a lot of this document out-dated, but a lot of it is still good, it + describes the workings of the plugins, and the repo structure. + + I know this file is long* and boring. I try to keep it preened and + informative, but would rather spend my time actually hacking. If + you think you can help this file, have at it! ~ Luke Shumaker + + * at 200+ lines, it's longer than any rvs source file + +- - -cut-here- - 8< - - - - - - - - - - - - - - - - - - - - - - - - - +////////////////////////////////////////////////////////////////////// + rvs 0.7.0 + retroactive versioning system + a versioning system that allows you to check + in commit 2 before commit 1 +////////////////////////////////////////////////////////////////////// + + hacking + + build basics + + One of the coolest things about rvs (IMO) is how modular and + customizable it is. If you wish to create a fork of rvs, it would + be a good idea to give it a different name. This can be done + without even changing a single source file! Simply run configure + with `--name=NAME' option (variables that have `rvs' in the name + will not be renamed, but the user will never know this unless they + peek at the code). + + Other options to configure and their default values are: + + name='rvs' + The name of the program. Note that unlike most + variables, you should NOT call this in Makefiles + (`$(name)'), but use `$(rvs)' instead. + RVS='$(bindir)/$(rvs)' + Where the executable will be. `$(rvs)' is the same as + `$(name)' (see above). In this document it is + sometimes referred to as the `wrapper'. + SHELL='/bin/sh' + The shell that will be used by make, and the shell + that scripts will run in. (Perhaps we should make + these separate variables?) + prefix='/usr/local' + Standard GNU variable. Many of you will want to + change this to `/usr', or `/home/USER_NAME' + exec_prefix='$(prefix)' + Standard GNU variable. + bindir='$(exec_prefix)/bin' + Standard GNU variable. + sbindir='$(exec_prefix)/sbin' + Standard GNU variable. + libexecdir='$(exec_prefix)/libexec' + Standard GNU variable. The plugins will be installed + at $(libexecdir)/$(name) + srcdir=$(readlink -f `dirname "$0"`) + Where the source code is. The default value evaluates + to the directory of the `configure' script. + + These can either be changed by manually changing `configure' or by + running it like: + ./configure --VAR_NAME=VALUE + + In this document, the `$(VAR_NAME)' refers to whatever you set the + value to. + + The configure script will run on any instance of `Makefile.in' in + $(srcdir). + + Currently, rvs is distributed with 2 plugins. `repo'[sitory] is + the core of the rvs file database. `users' handles all usernames, + settings, and other info. + + commands + + By itself, rvs does almost nothing. All real functionality is + provided by plugins. When you invoke rvs, you do so in the format + `rvs COMMAND'. Plugins work by adding new commands. + + Most commands are provided by plugins, however, a few are built in: + init + Initializes a repository in the current directory. It creates + `./.$(name)', and runs any initalizers for + plugins. + install PLUGIN DIR + Installs PLUGIN, for which the files are found in DIR. Unless + an older version is already installed, it adds the plugin to + have lowest priority (see `$(libexecdir)/$(rvs)/plugins'). + uninstall PLUGIN + Uninstalls PLUGIN. Did that really need to be said? + + A plugin is simply a collection of independent executable files. + When rvs is invoked, it looks for the COMMAND in a few places: + 1) checks if COMMAND is an built-in command + 2) looks at the file `$(libexecdir)/$(rvs)/plugins'. This is a + newline-delimited list of plugin names. + 3) loops through the directories `$(libexecdir)/$(rvs)/PLUGIN', + where PLUGIN is one of the values in + `$(libexecdir)/$(rvs)/plugins', in the order they appear in + the file. + 4) if rvs does not find the command, it reports an error + + If you would like to contribute a plugin, or distribute one with a + fork, all you have to do is put it in `$(srcdir)/plugins/NAME'. The + main Makefile will recognize any directory in `$(srcdir)/plugins/' + as a plugin, and will run `make -C `plugins/NAME/Makefile'. It + should create a directory (mine use `plugins/NAME/out') to put ALL, + and ONLY the final files to be used by that plugin. + +========this is outdated but I don't really want to keep editing it == + + build system + + The build system rvs uses is rather simple. + `./configure' does two things: + * create a sed script (`var.sed') + * run every instance of `$(srcdir)/Makefile.in' through + `var.sed' to generate a proper `Makefile' + + `var.sed' contains all configuration variables. When it processes + a file every instance of `@VAR_NAME@' is replaced by that + variable's value. This makes `configure' act much like a GNU + package `configure'. Note that this replacement only happens for + defined variables. + + Most of these can easily be changed _after_ `compilation' also: + VER line 4 of the wrapper + SHELL line 1 of each shell script + prefix simply move the wrapper + bindir simply move the wrapper + libexecdir move the directory, then update the line + `RVSDIR=...' in the wrapper + + I have designed this system to be extremely modular. As you may + have figured out, each bit on functionality is in it's own + executable, and the file you call when you type `rvs' is just a + wrapper for them. + + The wrapper is quite simple in mechanism. It simply checks if + `$$libdir$$/COMMAND_NAME' exists, and if so, runs that file. + + The `rvs commit' command is also quite simple in design. It takes a + single argument; the file to commit. If no target is specified, it + defaults to `./'. It checks which type of file the target is, and + runs `rvs commit.FILE_CODE TARGET'. The file codes are as follows: + + block (buffered) special b + character (unbuffered) special c + directory d + named pipe (FIFO) p + regular file f + symbolic link l + socket s + door (Solaris only) D + + As you probably noticed (if you've looked at the blueprints or + source files), only directories and regular files have been + implemented as of rvs 0.7.0. + + After `rvs commit' has done this, it creates a meta-file for that + commit. The meta file contains author, copyright owner, license + data, file permissions, timestamps, etc. The id of the meta-file is + written to stdout, and used to later check out that commit. + + get works in much the same way as commit, only it reads the file + type from the meta-file, then runs `rvs get.FILE_CODE COMMIT_ID'. + + If you implement any other file types, save the commit and get + functions in the proper locations. + + Any commit function should take a filename as an argument and + output the according commit id to stdout. stderr should be used + for all messages. + + Any get function should take the commit id as an argument and + uses stdout only if verbose, or to report errors. + + To summarize, the modules are separate programs and communicate via + pipes, which is generally considered bad-design, and libraries + should be used instead. I deliberately broke this because: + + 1. incompatible licenses can be used for different modules + 2. modules can be added/removed on the fly + 3. one can use any language to write new modules, without + having to worry about bindings`$(libexecdir)/$(rvs) + + $$libdir$$/lib/ + + THIS WAS WRITTEN FOR rvs 0.6.2 + THIS PORTION OF THE CODE IS BEING REVISED IN rvs 0.6.3 + + I have created two 'libraries' for use by rvs components. They + provide several functions that can be accessed by shell script by + using the code: + source "`rvs -d`/lib/stdio" + or + source "`rvs -d`/lib/rvsdb" + (`rvs -d' returns $$libdir$$) + stdio provides several functions for printing messages: + verbose MESSAGE + print MESSAGE to stdout only if $verbose is set to '-v' + out MESSAGE + print MESSAGE to stdout if $verbose isn't set to '-q' + warn MESSAGE + print "rvs: MESSAGE" to stderr + error MESSAGE + print "rvs: MESSAGE" and a quick message about `rvs --help' + (hinting at user error) to stderr, then exit with error + fatal MESSAGE + For internal error. Print "rvs: MESSAGE" to stderr and exit + with error + version + print the version information and exit with success + + rvsdb provides several functions and variables for dealing with the + rvs database: + getid FILE + returns what the id of a given file would be if it were in + the database. This is used to know where to put files when + committing them. In 0.5.8-0.6.3 this is just the sha1sum of + the file + NOTE: the "log*" functions aren't very stable or developed + loginit FILE + initialize an rvs log at FILE. These logs are used for + metafiles, directory listings, and (probably) eventually + checkout logs + lograw LOG + prepare LOG for reading, and write the output to stdout (to + pipe into another function). This is mostly for internal + use by rvsdb + logread LOG VAR + read variable VAR from the logfile LOG + logwrite LOG VAR VAL + set variable VAR to VAL in the logfile LOG + logfind LOG VAL + return all the names of variables in logfile LOG who have + the value VAL + + the database (.rvs/*) + + So, what are all these files doing in this database? The scheme is + fairly simple. In the `.rvs' directory there is 1 directory, the + `files' directory. There used to be a folder for tmpfiles (0.5.8- + 0.6.2), but no more (0.6.3+). If you need a tmpfile, just run: + FILENAME=$(mktemp -t) + The `files' directory is where all the data is kept. + + When any file is committed, whether it be a regular file, a + directory, a link, or any other type of file, 2 files are created + in `.rvs/files', the "raw-file" and the "meta-file". When we speak + of file IDs, we mean the filename of the corresponding file in + `.rvs/files' in rvs 0.5.8-0.6.3 this is just the sha1sum of the + file. The meta-file stores everything not part of the file itself; + the filename, file-type, author, copyright owner, file permissions, + timestamps, etc, and the ID of the corresponding raw-file. In the + case of an regular file, the raw-file contains the file itself. For + directories, it contains pointers to each file inside the + directory. + + $$libdir$$/commit calls $$libdir$$/commit.FILETYPE to generate the + raw-file, but generates the meta-file itself (in `.rvs/tmp', then + calls commit.f to commit the meta-file). It then returns the ID of + the meta-file. Therefore, the user never deals with the IDs of + raw-files, and doesn't need to. The metafiles contain pointers to + the corresponding raw-files. + + To keep things modular, commit.f is the ONLY thing that should + actually put files in `.rvs/files', and get.f the only thing that + should get them. Everything else should call them. + + The repo and init are the ONLY things that should have `.rvs' + hardcoded into them. If the repository directory is needed, then + use `rvs repo'. Again, in the core, these should only be the .f + functions, however, it will be useful to plugins. + + Why do we have the `files' directory, why don't we just put + everything in `.rvs'? This way: + * There is a spot to put user data, when we get around to writing + it + + final thoughts + + I have set up bazaar repository at Launchpad: + https://launchpad.net/rvs + Only until rvs becomes self-hosting. + + If anyone needs any help, let me know, either via email, or via + Launchpad, I'll be happy to help/would love to have your help! + +~ Luke Shumaker <LukeShu@sbcglobal.net> +Happy Hacking! diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c939ea9 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +#!/usr/bin/make -f +# Copyright (C) 2015 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +include $(dir $(lastword $(MAKEFILE_LIST)))/config.mk +include $(topsrcdir)/automake.head.mk + +am_subdirs = wrapper modules + +makefiles = Makefile automake.head.mk automake.tail.mk automake.txt common.once.head.mk common.once.tail.mk common.each.head.mk common.each.tail.mk +am_src_files = COPYING HACKING README configure config.mk.in +am_cfg_files = config.mk +am_out_files = config.sh config.h + +config_vars = $(filter-out topsrcdir,$(shell $(SED) -n 's/^\s*\([a-z][^ !?:=]*\).*=.*/\1/p' $(topoutdir)/config.mk) PACKAGE VERSION) +$(outdir)/config.sh: $(outdir)/config.mk + $(PRINTF) '%s=%s\n' $(foreach v,$(config_vars),$v $($v)) | LC_ALL=C $(SORT) > $@ +$(outdir)/config.h: $(outdir)/config.sh + . $(abspath $<) && $(PRINTF) '#define %s "%s"\n' $(foreach v,$(config_vars),$v '$($v)') PACKAGE_UPPER $${PACKAGE^^} | LC_ALL=C $(SORT) > $@ + +include $(topsrcdir)/automake.tail.mk @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////// + rvs 0.8c r54 + retroactive versioning system + a versioning system that allows you to check + in commit 2 before commit 1 +////////////////////////////////////////////////////////////////////// + +introduction + + rvs is about being able to go back and edit *anything* that has + already been committed. Yes, some other SCMs do this, but get + nasty if someone else has a copy of the old version. + + Why would you want to do this? Take for example the Bazaar + repository rvs is hosted on: It starts at 0.6.0, what if I later + want to import 0.0.0 - 0.5.10? Or if I'm trying to construct a + history of BSD, and import all the BSDs I can find, such as 1,3,4, + then latter find 2? + +system requirements + + Pretty much any *nix system should be able to run rvs. If you need + to use a shell other than `/bin/sh`, run `./configure` with the + `--SHELL=YOUR_SHELL` option. rvs is not designed for Windows, but + should be able to run in bash if you have some *nix pack installed. + + To my knowledge, this is the absolute requirements (all but the + shell need to be in your PATH): + * a POSIX shell (tested with dash, and GNU BASH) + * cat (included in GNU Core Utils) + * cp (included in GNU Core Utils) + * cut (included in GNU Core Utils) + * echo (included in GNU Core Utils) + * mkdir (included in GNU Core Utils) + * rm (included in GNU Core Utils) + * sed (included in GNU Core Utils) + * sha1sum (included in GNU Core Utils) + * tempfile (included in GNU Core Utils) + * tr (included in GNU Core Utils) + +building + + rvs doesn't exactly use the GNU build system, but acts much like it + does. To build rvs with default configuration, simply run: + + $ ./configure + $ make + # make install + + It's generally considered good practice to build in another + directory than the source directory. If you would like to do this, + it can be done in rvs-0.6.1 and up. + + Configuration + + There are several configuration variables that can be set. You can + modify these configuration variables by running `./configure` such + as: + + $ ./configure --VAR_NAME=VALUE + + The different configuration variables are as follows: + + name='rvs' + The name of the program. Note that unlike most + variables, you should NOT call this in Makefiles + (`$(name)'), but use `$(rvs)'s instead. + CC='gcc' + The C language compiler to use. + RVS='$(bindir)/$(rvs)' + Where the executable will be. `$(rvs)' is the same as + `$(name)' (see above) + SHELL='/bin/sh' + The shell that will be used by make, and the shell + that scripts will run in. (Perhaps we should make + these separate variables?) + prefix='/usr/local' + Standard GNU variable. Many of you will want to + change this to `/usr', or `/home/USER_NAME' + exec_prefix='$(prefix)' + Standard GNU variable. + bindir='$(exec_prefix)/bin' + Standard GNU variable. + sbindir='$(exec_prefix)/sbin' + Standard GNU variable. + libexecdir='$(exec_prefix)/libexec' + Standard GNU variable. The plugins will be installed + at $(libexecdir)/$(name) + srcdir=$(readlink -f `dirname "$0"`) + Where the source code is. The default value evaluates + to the directory of the `configure' script. + +-- +Happy hacking! +~ Luke Shumaker <LukeShu@sbcglobal.net> diff --git a/common.each.head.mk b/common.each.head.mk new file mode 100644 index 0000000..596e4f0 --- /dev/null +++ b/common.each.head.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2016 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +makefiles = diff --git a/common.each.tail.mk b/common.each.tail.mk new file mode 100644 index 0000000..d649602 --- /dev/null +++ b/common.each.tail.mk @@ -0,0 +1,42 @@ +# Copyright (C) 2015 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +dirs := $(dirs) + +am_clean_files += .*.mk *.o +ifneq ($(AUTODEPS),) +-include $(wildcard $(outdir)/.*.mk) +endif + +$(outdir)/% : $(srcdir)/%.m4 + $(M4) -P $(M4FLAGS) $< > $@ + +$(outdir)/% : $(srcdir)/%.sh + $(INSTALL_PROGRAM) $< $@ +$(outdir)/% : $(outdir)/%.sh + $(INSTALL_PROGRAM) $< $@ + +$(outdir)/%.o : $(srcdir)/%.c $(topoutdir)/config.mk + $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< + +$(outdir)/% : $(outdir)/%.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +ifneq ($(srcdir),$(outdir)) +$(addprefix $(outdir)/,$(makefiles)): $(outdir)/%: $(srcdir)/% + cp -Tf -- $< $@ +endif +am_src_files += $(makefiles) +am_cfg_files += $(makefiles) diff --git a/common.once.head.mk b/common.once.head.mk new file mode 100644 index 0000000..d50c639 --- /dev/null +++ b/common.once.head.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2015-2016 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +MAKEFLAGS += -rR +.SECONDARY: +.DELETE_ON_ERROR: + +# Have GCC generate header dependency info (pair this with `-include` +# in common.each.mk +ifneq ($(AUTODEPS),) +CFLAGS += -MD -MF $(patsubst $(@D)/%.o,$(@D)/.%.mk,$@) -MP +endif + +CPPFLAGS += -I$(topoutdir) +M4FLAGS += -I$(topoutdir) -I$(<D) -I$(@D) diff --git a/common.once.tail.mk b/common.once.tail.mk new file mode 100644 index 0000000..f326c6b --- /dev/null +++ b/common.once.tail.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2015-2016 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +# Make directories +dirs += $(addprefix $(DESTDIR),$(bindir) $(libexedir) $(datarootdir) $(datadir) $(sysconfdir) $(sharedstatedir) $(localstatedir) $(runstatedir) $(pkgdatadir) $(pkglibexecdir)) +$(sort $(dirs)): + $(MKDIRS) $@ diff --git a/config.mk.in b/config.mk.in new file mode 100644 index 0000000..0a8d70c --- /dev/null +++ b/config.mk.in @@ -0,0 +1,48 @@ +ifeq ($(topsrcdir),) +topoutdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) +topsrcdir := $(topoutdir) + +PACKAGE = rvs +VERSION = 0.10 +pkgtextdomain = $(PACKAGE) + +DESTDIR = +prefix = /usr/local +exec_prefix = $(prefix) + +bindir = $(exec_prefix)/bin +sbindir = $(exec_prefix)/sbin +libexecdir = $(exec_prefix)/libexec +datarootdir = $(prefix)/share +datadir = $(datarootdir) +sysconfdir = $(prefix)/etc +sharedstatedir = $(prefix)/com +localstatedir = $(prefix)/var +runstatedir = $(localstatedir)/run +localedir = $(datarootdir)/locale + +pkgdatadir = $(datadir)/$(PACKAGE) +pkglibexecdir = $(libexecdir)/$(PACKAGE) + +CFLAGS = -std=c99 -Werror -Wall -Wextra -pedantic -O2 +CPPFLAGS = -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE + +CC = cc +M4 = m4 +MKDIR = mkdir +MKDIRS = mkdir -p +RMDIRS = rmdir -p +INSTALL_DATA = install -m644 +INSTALL_PROGRAM = install -m755 +CP = cp +MV = mv +RM = rm -f +SED = sed +SORT = sort +TAR = tar +TRUE = true +PRINTF = printf + +AUTODEPS = t + +endif diff --git a/configure b/configure new file mode 100755 index 0000000..5e99fa6 --- /dev/null +++ b/configure @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +name='configure' # Luke's configuration script +#version='1.0' +# Copyright (C) 2009, 2016 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +srcdir="$(dirname -- "$0")" +outdir="." + +error() { + echo "$name: $1" >&2 + exit 1 +} + +if [ "${srcdir:0:1}" = / ]; then + topsrcdir=$srcdir +else + topsrcdir="&/$srcdir" +fi +topsrcdir="${topsrcdir%/.}" + +edit=(sed -E -e "s|^topsrcdir := .*|$topsrcdir|") +setvar() { + edit+=(-e "s@^(\s*$1\s*:?=).*@\1 $2@") +} + +vars=($(<"$srcdir/config.mk.in" sed -n 's/^\([ a-z_-]*\)=.*/\1/p')) + +printf -v lopt '%s:,' "${vars[@]}" +lopt+='enable-autodeps,disable-autodeps' + +sopt='' + +args=$(getopt -n "$name" -o "${sopt}" -l "${lopt}" -- "$@") || exit $? +eval set -- "$args" +while [ $# -gt 0 ]; do + case "$1" in + --) break;; + --enable-autodeps) setvar AUTODEPS t;; + --disable-autodeps) setvar AUTODEPS '';; + --*) setvar "${1#--}" "$2" shift;; + *) error "unrecognized option \`$1'"; + esac + shift +done + +"${edit[@]}" < "$srcdir/config.mk.in" > "$outdir/config.mk" + +Makefiles=($(find "$srcdir/" -name 'Makefile') "$srcdir"/modules/module.mk "$srcdir"/modules/*/Makefile.inc.mk) +for src in "${Makefiles[@]}"; do + out="$outdir/${src#$srcdir/}" + mkdir -p -- $(dirname -- "$out") + if ! test "$src" -ef "$out"; then + cp -fT -- "$src" "$out" + fi +done diff --git a/modules/.gitignore b/modules/.gitignore new file mode 100644 index 0000000..3c197bc --- /dev/null +++ b/modules/.gitignore @@ -0,0 +1,5 @@ +*/* +!*/Makefile +!*/.gitignore +!*/*.mk +!*/*.sh diff --git a/modules/Makefile b/modules/Makefile new file mode 100644 index 0000000..d9de6c0 --- /dev/null +++ b/modules/Makefile @@ -0,0 +1,24 @@ +#!/usr/bin/make -f +# Copyright (C) 2015 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +include $(dir $(lastword $(MAKEFILE_LIST)))/../config.mk +include $(topsrcdir)/automake.head.mk + +dirs += $(DESTDIR)$(pkglibexecdir)/modules +makefiles = Makefile module.mk +am_subdirs = comments date.author blobs tags tree + +include $(topsrcdir)/automake.tail.mk diff --git a/modules/blobs/.#get.f.sh b/modules/blobs/.#get.f.sh new file mode 120000 index 0000000..c2c97da --- /dev/null +++ b/modules/blobs/.#get.f.sh @@ -0,0 +1 @@ +luke@build64-par.lan.670:1436421582
\ No newline at end of file diff --git a/modules/blobs/Makefile b/modules/blobs/Makefile new file mode 120000 index 0000000..fa7273c --- /dev/null +++ b/modules/blobs/Makefile @@ -0,0 +1 @@ +../module.mk
\ No newline at end of file diff --git a/modules/blobs/Makefile.inc.mk b/modules/blobs/Makefile.inc.mk new file mode 100644 index 0000000..9f3f112 --- /dev/null +++ b/modules/blobs/Makefile.inc.mk @@ -0,0 +1,8 @@ +am_src_files += commit.d.sh commit.f.sh commit.sh get.d.sh get.f.sh get.sh ls.sh print.sh tree.sh +am_out_files += commit.d commit.f commit get.d get.f get ls print tree + +am_src_files += _stdio.sh +am_sys_files += $(pkglibexecdir)/modules/$(name)/_stdio.sh + +$(DESTDIR)$(pkglibexecdir)/modules/$(name)/_stdio.sh: $(srcdir)/_stdio.sh | $(DESTDIR)$(pkglibexecdir)/modules/$(name) + $(INSTALL_DATA) $< $@ diff --git a/modules/blobs/Module.mk b/modules/blobs/Module.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/modules/blobs/Module.mk diff --git a/modules/blobs/_stdio.sh b/modules/blobs/_stdio.sh new file mode 100644 index 0000000..0da03f0 --- /dev/null +++ b/modules/blobs/_stdio.sh @@ -0,0 +1,74 @@ +#!/bin/sh +#name='stdio' +#ver=0.9 +# Copyright (C) 2009-2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +verbose() { + if [ "$volume" == '-v' ]; then + echo $@ >> /dev/stderr + fi +} + +out() { + if [ "$volume" != '-q' ]; then + echo $@ >> /dev/stderr + fi +} + +warn () { + echo "$name: $1" >> /dev/stderr +} + +fatal () { + warn "$1" + exit 1 +} + +error() { + warn "$1" + cat << __error__ >> /dev/stderr +Usage: $RVS $name $usage + +Try \`$RVS help $name' for more options. +__error__ + exit 1 +} + +getvar() { + if [ -z "$1" ]; then + error + else + echo $1 + fi +} + +version() { + echo "$name $ver" + if [ "$volume" != '-q' ]; then + cat << __disclaimer__ +$name is copyright (C) 2009-2010 Luke Shumaker +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Originally written by Luke Shumaker <LukeShu@sbcglobal.net>. +__disclaimer__ + fi + exit 0 +} + diff --git a/modules/blobs/commit.d.sh b/modules/blobs/commit.d.sh new file mode 100644 index 0000000..620a88f --- /dev/null +++ b/modules/blobs/commit.d.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# rvs blobs/commit.d - add a directory to the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='DIRECTORY' +[[ $# -eq 1 ]] || errusage +dir="$1" + +shopt -s dotglob +cd "$dir" +tmpfile="$(mktemp -t "${0##*/}.XXXXXXXXXX")" +for file in *; do + id="$("$RVS" commit "$file")" + stat -c $'%a\t%u (%U)\t%g (%G)\t' -- "$file" + printf $'%s\t%s\n' "$id" "$file" +done > "$tmpfile" +"$RVS" commit.f "$tmpfile" d diff --git a/modules/blobs/commit.f.sh b/modules/blobs/commit.f.sh new file mode 100644 index 0000000..8a97c2a --- /dev/null +++ b/modules/blobs/commit.f.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# rvs blobs/commit.f - add a plain file to the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='FILENAME [TYPE]' +case $# in + 0) errusage;; + 1) infile=$1; type=f;; + 2) infile=$1; type=$2;; + *) errusage;; +esac + +hash="$(<"$file" sha1sum | cut -d ' ' -f1)" +outfile="$RVS_REPO/blobs/$hash" +if [ ! -f "$outfile" ]; then + mkdir -p -- "${outfile%/*}" + < "$infile" gzip -9 > "$outfile" +fi +printf '%s:%s\n' "$type" "$hash" + diff --git a/modules/blobs/commit.sh b/modules/blobs/commit.sh new file mode 100644 index 0000000..e23af27 --- /dev/null +++ b/modules/blobs/commit.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# rvs blobs/commit - add a file to the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='[FILES...]' +if [[ $# -lt 1 ]]; then + set -- . +fi + +for file in "$@"; do + local type + if test -L "$file"; then + type=l + elif test -f "$file"; then + type=f + elif test -d "$file"; then + type=d + else + error 'Unsupported file type: %s' "$file" + fi + "$RVS" "commit.$type" "$file" +done diff --git a/modules/blobs/get.d.sh b/modules/blobs/get.d.sh new file mode 100644 index 0000000..989dbe8 --- /dev/null +++ b/modules/blobs/get.d.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# rvs blobs/get.d - get a directory from the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage="DIRNAME ID" +[[ $# -eq 2 ]] || errusage +name=$1 +id=$2 + +tmpfile="$(mktemp -t "${0##*/}.XXXXXXXXXX")" +"$RVS" get.f "$tmpfile" "$id" + +mkdir -p -- "$name" +cd "$name" + +IFS=$'\t' +while read -r perm user group id name; do + "$RVS" get "$name" "$id" + chmod "$perm" "$name" +done < "$tmpfile" diff --git a/modules/blobs/get.f.sh b/modules/blobs/get.f.sh new file mode 100644 index 0000000..02185a6 --- /dev/null +++ b/modules/blobs/get.f.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# rvs blobs/get.f - get a plain file from the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +. "$LIBDIR/@ID@/stdio" + +usage="FILENAME ID" +[[ $# -eq 2 ]] || errusage +name=$1 +id=$2 + +mkdir -p -- "${name%/*}" +< "$REPO/blobs/${id#*:}" gunzip > "$name" + diff --git a/modules/blobs/get.sh b/modules/blobs/get.sh new file mode 100644 index 0000000..4be2732 --- /dev/null +++ b/modules/blobs/get.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# rvs blobs/get - get a file from the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage="FILENAME ID" +[[ $# -eq 2 ]] || errusage +name=$1 +id=$2 + +"$RVS" "get.${id%%:*}" "$name" "$id" + diff --git a/modules/blobs/ls.sh b/modules/blobs/ls.sh new file mode 100644 index 0000000..1c4d620 --- /dev/null +++ b/modules/blobs/ls.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +name='ls' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +. "$LIBDIR/@ID@/stdio" + +usage="DIR_ID [FORMAT]" +id="`getvar "$1"`" +form="${2-%p\t%o\t%g\t%n\t%i}" + +# %p - permissions +# %o - owner +# %g - group +# %i - blob id +# %n - name +# \t - a tab char + +tmp="`mktemp`" +"$RVS" get.f "$tmp" "$id" + +while read line; do + p="`echo "$line" | cut -f1`" + o="`echo "$line" | cut -f2`" + g="`echo "$line" | cut -f3`" + i="`echo "$line" | cut -f4`" + n="`echo "$line" | cut -f5-`" + echo "$form" | sed \ + -e 's:\\t:\t:g' \ + -e "s:%p:${p/:/\\:}:g" \ + -e "s:%o:${o/:/\\:}:g" \ + -e "s:%g:${g/:/\\:}:g" \ + -e "s:%i:${i/:/\\:}:g" \ + -e "s:%n:${n/:/\\:}:g" +done < "$tmp" + diff --git a/modules/blobs/print.sh b/modules/blobs/print.sh new file mode 100644 index 0000000..0e23adc --- /dev/null +++ b/modules/blobs/print.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# rvs files/print - ??? +# Copyright (C) 2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='ID' +[[ $# -eq 1 ]] || errusage +id=$1 + +hash="${id#*:}" +file="$REPO/blobs/$hash" + +if [ -e "$file" ]; then + t="${id%%:*}" + type='' + case "$t" in + f) type='regular file';; + d) type='directory';; + l) type='link';; + esac + printf 'File Type: %s (%s)\n' "$t" "$type" +else + fatal 'no object with ID `%s'\' "$id" +fi + diff --git a/modules/blobs/tree.sh b/modules/blobs/tree.sh new file mode 100644 index 0000000..80202ea --- /dev/null +++ b/modules/blobs/tree.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +name='tree' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +. "${0%/*}/_stdio.sh" + +usage="DIR_ID [NAME] [PREFIX] [LAST]" +id="`getvar "$1"`" +name="${2-.}" +pref="$3" +last="$4" + +echo "$pref $name $id" +pref=' | ' +"$RVS" ls "$id" '%i\t%n' | while read line; do + i="`echo "$line" | cut -f1`" + n="`echo "$line" | cut -f2-`" + t="`"$RVS" blob-gettype "$i"`" + if [ "$t" = 'd' ] + "$RVS" tree "$i" "$n" "$pref" + else + echo "$pref $n $i" + fi +done + diff --git a/modules/comments/Makefile b/modules/comments/Makefile new file mode 120000 index 0000000..fa7273c --- /dev/null +++ b/modules/comments/Makefile @@ -0,0 +1 @@ +../module.mk
\ No newline at end of file diff --git a/modules/comments/Makefile.inc.mk b/modules/comments/Makefile.inc.mk new file mode 100644 index 0000000..d5632d7 --- /dev/null +++ b/modules/comments/Makefile.inc.mk @@ -0,0 +1,2 @@ +am_src_files += comment.sh commit.sh print.sh showcomment.sh +sm_out_files += comment commit print showcomment diff --git a/modules/comments/Module.mk b/modules/comments/Module.mk new file mode 100644 index 0000000..aa0a9af --- /dev/null +++ b/modules/comments/Module.mk @@ -0,0 +1 @@ +comments/commit : blobs/commit diff --git a/modules/comments/comment.sh b/modules/comments/comment.sh new file mode 100644 index 0000000..aa615ca --- /dev/null +++ b/modules/comments/comment.sh @@ -0,0 +1,26 @@ +#!/bin/sh +name='comment' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS $name ID" +id="${1?"$usage"}" + +file="$REPO/@ID@/$id" +mkdir -p "`dirname "$file"`" +editor "$file" >> /dev/stderr + diff --git a/modules/comments/commit.sh b/modules/comments/commit.sh new file mode 100644 index 0000000..4163387 --- /dev/null +++ b/modules/comments/commit.sh @@ -0,0 +1,24 @@ +#!/bin/sh +name='rvs @ID@ commit' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +if [ "$RVS_LEVEL" = '0' ]; then + id=`cat "$TMPDIR/commit/files"` + "$RVS" comment "$id" +fi + diff --git a/modules/comments/print.sh b/modules/comments/print.sh new file mode 100644 index 0000000..bef8e87 --- /dev/null +++ b/modules/comments/print.sh @@ -0,0 +1,28 @@ +#!/bin/sh +name='print' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="Usage: $RVS $name ID" +id="${1?"$usage"}" + +file="$REPO/@ID@/$id" +if [ -e "$file" ]; then + echo "Comment:" + sed 's/\(.*\)/ > \1/' "$file" +fi + diff --git a/modules/comments/showcomment.sh b/modules/comments/showcomment.sh new file mode 100644 index 0000000..3e4e943 --- /dev/null +++ b/modules/comments/showcomment.sh @@ -0,0 +1,27 @@ +#!/bin/sh +name='showcomment' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="Usage: $RVS $name ID" +id="${1?"$usage"}" + +file="$REPO/@ID@/$id" +if [ -e "$file" ]; then + cat "$file" +fi + diff --git a/modules/date.author/Makefile b/modules/date.author/Makefile new file mode 120000 index 0000000..fa7273c --- /dev/null +++ b/modules/date.author/Makefile @@ -0,0 +1 @@ +../module.mk
\ No newline at end of file diff --git a/modules/date.author/Makefile.inc.mk b/modules/date.author/Makefile.inc.mk new file mode 100644 index 0000000..ac9d0df --- /dev/null +++ b/modules/date.author/Makefile.inc.mk @@ -0,0 +1,2 @@ +am_src_files += commit.sh +am_out_files += commit diff --git a/modules/date.author/Module.mk b/modules/date.author/Module.mk new file mode 100644 index 0000000..2b94226 --- /dev/null +++ b/modules/date.author/Module.mk @@ -0,0 +1 @@ +date.author/commit : blobs/commit diff --git a/modules/date.author/commit.sh b/modules/date.author/commit.sh new file mode 100644 index 0000000..8079fda --- /dev/null +++ b/modules/date.author/commit.sh @@ -0,0 +1,28 @@ +#!/bin/sh +name='rvs @ID@ commit' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +if [ "$RVS_LEVEL" = '0' ]; then + id=`cat "$TMPDIR/commit/files"` + time=`date +%s` + file="$REPO/@ID@/$time" + if [ -n "$wch" ]; then + "$RVS" addparent "$id" "$wch" + fi +fi + diff --git a/modules/git-fast-import/gen-parser.mk b/modules/git-fast-import/gen-parser.mk new file mode 100644 index 0000000..7837e5c --- /dev/null +++ b/modules/git-fast-import/gen-parser.mk @@ -0,0 +1,154 @@ +# (See Documentation/git-fast-import.txt for maintained documentation.) +# Format of STDIN stream: +# +# stream ::= cmd*; +# +# cmd ::= new_blob +# | new_commit +# | new_tag +# | reset_branch +# | checkpoint +# | progress +# ; +# +# new_blob ::= 'blob' lf +# mark? +# file_content; +# file_content ::= data; +# +# new_commit ::= 'commit' sp ref_str lf +# mark? +# ('author' (sp name)? sp '<' email '>' sp when lf)? +# 'committer' (sp name)? sp '<' email '>' sp when lf +# commit_msg +# ('from' sp commit-ish lf)? +# ('merge' sp commit-ish lf)* +# (file_change | ls)* +# lf?; +# commit_msg ::= data; +# +# ls ::= 'ls' sp '"' quoted(path) '"' lf; +# +# file_change ::= file_clr +# | file_del +# | file_rnm +# | file_cpy +# | file_obm +# | file_inm; +# file_clr ::= 'deleteall' lf; +# file_del ::= 'D' sp path_str lf; +# file_rnm ::= 'R' sp path_str sp path_str lf; +# file_cpy ::= 'C' sp path_str sp path_str lf; +# file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf; +# file_inm ::= 'M' sp mode sp 'inline' sp path_str lf +# data; +# note_obm ::= 'N' sp (hexsha1 | idnum) sp commit-ish lf; +# note_inm ::= 'N' sp 'inline' sp commit-ish lf +# data; +# +# new_tag ::= 'tag' sp tag_str lf +# 'from' sp commit-ish lf +# ('tagger' (sp name)? sp '<' email '>' sp when lf)? +# tag_msg; +# tag_msg ::= data; +# +# reset_branch ::= 'reset' sp ref_str lf +# ('from' sp commit-ish lf)? +# lf?; +# +# checkpoint ::= 'checkpoint' lf +# lf?; +# +# progress ::= 'progress' sp not_lf* lf +# lf?; +# +# # note: the first idnum in a stream should be 1 and subsequent +# # idnums should not have gaps between values as this will cause +# # the stream parser to reserve space for the gapped values. An +# # idnum can be updated in the future to a new object by issuing +# # a new mark directive with the old idnum. +# # +# mark ::= 'mark' sp idnum lf; +# data ::= (delimited_data | exact_data) +# lf?; +# +# # note: delim may be any string but must not contain lf. +# # data_line may contain any data but must not be exactly +# # delim. +# delimited_data ::= 'data' sp '<<' delim lf +# (data_line lf)* +# delim lf; +# +# # note: declen indicates the length of binary_data in bytes. +# # declen does not include the lf preceding the binary data. +# # +# exact_data ::= 'data' sp declen lf +# binary_data; +# +# # note: quoted strings are C-style quoting supporting \c for +# # common escapes of 'c' (e..g \n, \t, \\, \") or \nnn where nnn +# # is the signed byte value in octal. Note that the only +# # characters which must actually be escaped to protect the +# # stream formatting is: \, " and LF. Otherwise these values +# # are UTF8. +# # +# commit-ish ::= (ref_str | hexsha1 | sha1exp_str | idnum); +# ref_str ::= ref; +# sha1exp_str ::= sha1exp; +# tag_str ::= tag; +# path_str ::= path | '"' quoted(path) '"' ; +# mode ::= '100644' | '644' +# | '100755' | '755' +# | '120000' +# ; +# +# declen ::= # unsigned 32 bit value, ascii base10 notation; +# bigint ::= # unsigned integer value, ascii base10 notation; +# binary_data ::= # file content, not interpreted; +# +# when ::= raw_when | rfc2822_when; +# raw_when ::= ts sp tz; +# rfc2822_when ::= # Valid RFC 2822 date and time; +# +# sp ::= # ASCII space character; +# lf ::= # ASCII newline (LF) character; +# +# # note: a colon (':') must precede the numerical value assigned to +# # an idnum. This is to distinguish it from a ref or tag name as +# # GIT does not permit ':' in ref or tag strings. +# # +# idnum ::= ':' bigint; +# path ::= # GIT style file path, e.g. "a/b/c"; +# ref ::= # GIT ref name, e.g. "refs/heads/MOZ_GECKO_EXPERIMENT"; +# tag ::= # GIT tag name, e.g. "FIREFOX_1_5"; +# sha1exp ::= # Any valid GIT SHA1 expression; +# hexsha1 ::= # SHA1 in hexadecimal format; +# +# # note: name and email are UTF8 strings, however name must not +# # contain '<' or lf and email must not contain any of the +# # following: '<', '>', lf. +# # +# name ::= # valid GIT author/committer name; +# email ::= # valid GIT author/committer email; +# ts ::= # time since the epoch in seconds, ascii base10 notation; +# tz ::= # GIT style timezone; +# +# # note: comments, ls and cat requests may appear anywhere +# # in the input, except within a data command. Any form +# # of the data command always escapes the related input +# # from comment processing. +# # +# # In case it is not clear, the '#' that starts the comment +# # must be the first character on that line (an lf +# # preceded it). +# # +# +# cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf; +cat_blob = cat-blob${sp}(${hexsha1}|${idnum})${lf} +# ls_tree ::= 'ls' sp (hexsha1 | idnum) sp path_str lf; +ls_tree = ls${sp}(${hexsha1}|${idnum})${sp}${path_str}${lf} +# +# comment ::= '#' not_lf* lf; +comment = \#$(not_lf) +# not_lf ::= # Any byte that is not ASCII newline (LF); +not_lf = [^\n] diff --git a/modules/git-fast-import/parse.sh b/modules/git-fast-import/parse.sh new file mode 100644 index 0000000..16bc5d2 --- /dev/null +++ b/modules/git-fast-import/parse.sh @@ -0,0 +1,1077 @@ +#!/bin/bash + +program_invocation_name=$0 +if type gettext &>/dev/null; then + _() { gettext -- "$@"; } +else + _() { echo "$*"; } +fi + +IFS= + +die() { + printf "$(_ "$1")" "${@:2}" + exit 2 +} + + +# Input Format +# ------------ +# With the exception of raw file data (which Git does not interpret) +# the fast-import input format is text (ASCII) based. This text based +# format simplifies development and debugging of frontend programs, +# especially when a higher level language such as Perl, Python or +# Ruby is being used. +# +# fast-import is very strict about its input. Where we say SP below we mean +# *exactly* one space. Likewise LF means one (and only one) linefeed +# and HT one (and only one) horizontal tab. +# Supplying additional whitespace characters will cause unexpected +# results, such as branch names or file names with leading or trailing +# spaces in their name, or early termination of fast-import when it encounters +# unexpected input. +# +# Stream Comments +# ~~~~~~~~~~~~~~~ +# To aid in debugging frontends fast-import ignores any line that +# begins with `#` (ASCII pound/hash) up to and including the line +# ending `LF`. A comment line may contain any sequence of bytes +# that does not contain an LF and therefore may be used to include +# any detailed debugging information that might be specific to the +# frontend and useful when inspecting a fast-import data stream. + +get_line() { + line='#' + while [[ ${line:0:1} == '#' ]]; do + read -r line || break + done +} + +# +# Date Formats +# ~~~~~~~~~~~~ +# The following date formats are supported. A frontend should select +# the format it will use for this import by passing the format name +# in the --date-format=<fmt> command-line option. +# +# `raw`:: +# This is the Git native format and is `<time> SP <offutc>`. +# It is also fast-import's default format, if --date-format was +# not specified. +# + +# The time of the event is specified by `<time>` as the number of +# seconds since the UNIX epoch (midnight, Jan 1, 1970, UTC) and is +# written as an ASCII decimal integer. +# + +# The local offset is specified by `<offutc>` as a positive or negative +# offset from UTC. For example EST (which is 5 hours behind UTC) +# would be expressed in `<tz>` by ``-0500'' while UTC is ``+0000''. +# The local offset does not affect `<time>`; it is used only as an +# advisement to help formatting routines display the timestamp. +# + +# If the local offset is not available in the source material, use +# ``+0000'', or the most common local offset. For example many +# organizations have a CVS repository which has only ever been accessed +# by users who are located in the same location and time zone. In this +# case a reasonable offset from UTC could be assumed. +# + +# Unlike the `rfc2822` format, this format is very strict. Any +# variation in formatting will cause fast-import to reject the value. +# +# `rfc2822`:: +# This is the standard email format as described by RFC 2822. +# + +# An example value is ``Tue Feb 6 11:22:18 2007 -0500''. The Git +# parser is accurate, but a little on the lenient side. It is the +# same parser used by 'git am' when applying patches +# received from email. +# + +# Some malformed strings may be accepted as valid dates. In some of +# these cases Git will still be able to obtain the correct date from +# the malformed string. There are also some types of malformed +# strings which Git will parse wrong, and yet consider valid. +# Seriously malformed strings will be rejected. +# + +# Unlike the `raw` format above, the time zone/UTC offset information +# contained in an RFC 2822 date string is used to adjust the date +# value to UTC prior to storage. Therefore it is important that +# this information be as accurate as possible. +# + +# If the source material uses RFC 2822 style dates, +# the frontend should let fast-import handle the parsing and conversion +# (rather than attempting to do it itself) as the Git parser has +# been well tested in the wild. +# + +# Frontends should prefer the `raw` format if the source material +# already uses UNIX-epoch format, can be coaxed to give dates in that +# format, or its format is easily convertible to it, as there is no +# ambiguity in parsing. +# +# `now`:: +# Always use the current time and time zone. The literal +# `now` must always be supplied for `<when>`. +# + +# This is a toy format. The current time and time zone of this system +# is always copied into the identity string at the time it is being +# created by fast-import. There is no way to specify a different time or +# time zone. +# + +# This particular format is supplied as it's short to implement and +# may be useful to a process that wants to create a new commit +# right now, without needing to use a working directory or +# 'git update-index'. +# + +# If separate `author` and `committer` commands are used in a `commit` +# the timestamps may not match, as the system clock will be polled +# twice (once for each command). The only way to ensure that both +# author and committer identity information has the same timestamp +# is to omit `author` (thus copying from `committer`) or to use a +# date format other than `now`. +# +# Commands +# ~~~~~~~~ +# fast-import accepts several commands to update the current repository +# and control the current import process. More detailed discussion +# (with examples) of each command follows later. +# +parse() { + while get_line; do + case "$line" in +# `commit`:: +# Creates a new branch or updates an existing branch by +# creating a new commit and updating the branch to point at +# the newly created commit. + 'commit '*) cmd_commit "${line#commit }";; +# +# `tag`:: +# Creates an annotated tag object from an existing commit or +# branch. Lightweight tags are not supported by this command, +# as they are not recommended for recording meaningful points +# in time. + 'tag '*) cmd_tag "${line#tag }";; +# +# `reset`:: +# Reset an existing branch (or a new branch) to a specific +# revision. This command must be used to change a branch to +# a specific revision without making a commit on it. + 'reset '*) cmd_reset "${line#reset }";; +# +# `blob`:: +# Convert raw file data into a blob, for future use in a +# `commit` command. This command is optional and is not +# needed to perform an import. + 'blob '*) cmd_blob "${line#blob }";; +# +# `checkpoint`:: +# Forces fast-import to close the current packfile, generate its +# unique SHA-1 checksum and index, and start a new packfile. +# This command is optional and is not needed to perform +# an import. + 'checkpoint '*) cmd_checkpoint "${line#checkpoint }";; +# +# `progress`:: +# Causes fast-import to echo the entire line to its own +# standard output. This command is optional and is not needed +# to perform an import. + 'progress '*) cmd_progress "${line#progress }";; +# +# `done`:: +# Marks the end of the stream. This command is optional +# unless the `done` feature was requested using the +# `--done` command-line option or `feature done` command. + 'done '*) cmd_done "${line#done }";; +# +# `cat-blob`:: +# Causes fast-import to print a blob in 'cat-file --batch' +# format to the file descriptor set with `--cat-blob-fd` or +# `stdout` if unspecified. + 'cat-blob '*) cmd_cat-blob "${line#cat-blob }";; +# +# `ls`:: +# Causes fast-import to print a line describing a directory +# entry in 'ls-tree' format to the file descriptor set with +# `--cat-blob-fd` or `stdout` if unspecified. + 'ls '*) cmd_ls "${line#ls }";; +# +# `feature`:: +# Enable the specified feature. This requires that fast-import +# supports the specified feature, and aborts if it does not. + 'feature '*) cmd_feature "${line#feature }";; +# +# `option`:: +# Specify any of the options listed under OPTIONS that do not +# change stream semantic to suit the frontend's needs. This +# command is optional and is not needed to perform an import. + 'option '*) cmd_option "${line#option }";; + *) die 'Unsupported command: %s' "$line";; + esac + done +# +} +# `commit` +# ~~~~~~~~ +# Create or update a branch with a new commit, recording one logical +# change to the project. +# +cmd_commit() { +# .... +# 'commit' SP <ref> LF + local ref=$1 + get_line +# mark? + get_mark || true +# ('author' (SP <name>)? SP LT <email> GT SP <when> LF)? + if [[ $line = 'author '* ]]; then + author="${line#author }" + get_line + fi +# 'committer' (SP <name>)? SP LT <email> GT SP <when> LF + if [[ $line = 'committer '* ]]; then + committer="${line#committer }" + get_line + else + die "Expected committer but didn't get one"; + fi +# data + get_data +# ('from' SP <commit-ish> LF)? + if [[ $line = 'from '* ]]; then + from="${line#from }" + get_line + fi +# ('merge' SP <commit-ish> LF)* + while [[ $line = 'merge '* ]]; do + parents+=("${line#merge }") + get_line + done +# (filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)* + while cmd_commit--filemodify || + cmd_commit--filedelete || + cmd_commit--filecopy || + cmd_commit--filerename || + cmd_commit--filedeleteall || + cmd_commit--notemodify + do :; done +# LF? + [[ -n $line ]] || get_line +# .... +} +# +# where `<ref>` is the name of the branch to make the commit on. +# Typically branch names are prefixed with `refs/heads/` in +# Git, so importing the CVS branch symbol `RELENG-1_0` would use +# `refs/heads/RELENG-1_0` for the value of `<ref>`. The value of +# `<ref>` must be a valid refname in Git. As `LF` is not valid in +# a Git refname, no quoting or escaping syntax is supported here. +# +# A `mark` command may optionally appear, requesting fast-import to save a +# reference to the newly created commit for future use by the frontend +# (see below for format). It is very common for frontends to mark +# every commit they create, thereby allowing future branch creation +# from any imported commit. +# +# The `data` command following `committer` must supply the commit +# message (see below for `data` command syntax). To import an empty +# commit message use a 0 length data. Commit messages are free-form +# and are not interpreted by Git. Currently they must be encoded in +# UTF-8, as fast-import does not permit other encodings to be specified. +# +# Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`, +# `filedeleteall` and `notemodify` commands +# may be included to update the contents of the branch prior to +# creating the commit. These commands may be supplied in any order. +# However it is recommended that a `filedeleteall` command precede +# all `filemodify`, `filecopy`, `filerename` and `notemodify` commands in +# the same commit, as `filedeleteall` wipes the branch clean (see below). +# +# The `LF` after the command is optional (it used to be required). +# +# `author` +# ^^^^^^^^ +# An `author` command may optionally appear, if the author information +# might differ from the committer information. If `author` is omitted +# then fast-import will automatically use the committer's information for +# the author portion of the commit. See below for a description of +# the fields in `author`, as they are identical to `committer`. +# +# `committer` +# ^^^^^^^^^^^ +# The `committer` command indicates who made this commit, and when +# they made it. +# +# Here `<name>` is the person's display name (for example +# ``Com M Itter'') and `<email>` is the person's email address +# (``\cm@example.com''). `LT` and `GT` are the literal less-than (\x3c) +# and greater-than (\x3e) symbols. These are required to delimit +# the email address from the other fields in the line. Note that +# `<name>` and `<email>` are free-form and may contain any sequence +# of bytes, except `LT`, `GT` and `LF`. `<name>` is typically UTF-8 encoded. +# +# The time of the change is specified by `<when>` using the date format +# that was selected by the --date-format=<fmt> command-line option. +# See ``Date Formats'' above for the set of supported formats, and +# their syntax. +# +# `from` +# ^^^^^^ +# The `from` command is used to specify the commit to initialize +# this branch from. This revision will be the first ancestor of the +# new commit. The state of the tree built at this commit will begin +# with the state at the `from` commit, and be altered by the content +# modifications in this commit. +# +# Omitting the `from` command in the first commit of a new branch +# will cause fast-import to create that commit with no ancestor. This +# tends to be desired only for the initial commit of a project. +# If the frontend creates all files from scratch when making a new +# branch, a `merge` command may be used instead of `from` to start +# the commit with an empty tree. +# Omitting the `from` command on existing branches is usually desired, +# as the current commit on that branch is automatically assumed to +# be the first ancestor of the new commit. +# +# As `LF` is not valid in a Git refname or SHA-1 expression, no +# quoting or escaping syntax is supported within `<commit-ish>`. +# +# Here `<commit-ish>` is any of the following: +# +# * The name of an existing branch already in fast-import's internal branch +# table. If fast-import doesn't know the name, it's treated as a SHA-1 +# expression. +# +# * A mark reference, `:<idnum>`, where `<idnum>` is the mark number. +# + +# The reason fast-import uses `:` to denote a mark reference is this character +# is not legal in a Git branch name. The leading `:` makes it easy +# to distinguish between the mark 42 (`:42`) and the branch 42 (`42` +# or `refs/heads/42`), or an abbreviated SHA-1 which happened to +# consist only of base-10 digits. +# + +# Marks must be declared (via `mark`) before they can be used. +# +# * A complete 40 byte or abbreviated commit SHA-1 in hex. +# +# * Any valid Git SHA-1 expression that resolves to a commit. See +# ``SPECIFYING REVISIONS'' in linkgit:gitrevisions[7] for details. +# +# * The special null SHA-1 (40 zeros) specifies that the branch is to be +# removed. +# +# The special case of restarting an incremental import from the +# current branch value should be written as: +# ---- +# from refs/heads/branch^0 +# ---- +# The `^0` suffix is necessary as fast-import does not permit a branch to +# start from itself, and the branch is created in memory before the +# `from` command is even read from the input. Adding `^0` will force +# fast-import to resolve the commit through Git's revision parsing library, +# rather than its internal branch table, thereby loading in the +# existing value of the branch. +# +# `merge` +# ^^^^^^^ +# Includes one additional ancestor commit. The additional ancestry +# link does not change the way the tree state is built at this commit. +# If the `from` command is +# omitted when creating a new branch, the first `merge` commit will be +# the first ancestor of the current commit, and the branch will start +# out with no files. An unlimited number of `merge` commands per +# commit are permitted by fast-import, thereby establishing an n-way merge. +# +# Here `<commit-ish>` is any of the commit specification expressions +# also accepted by `from` (see above). +# +# `filemodify` +# ^^^^^^^^^^^^ +# Included in a `commit` command to add a new file or change the +# content of an existing file. This command has two different means +# of specifying the content of the file. +# +cmd_commit--filemodify() { +# External data format:: +# The data content for the file was already supplied by a prior +# `blob` command. The frontend just needs to connect it. +# + +# .... +# 'M' SP <mode> SP <dataref> SP <path> LF +# .... +# + +# Here usually `<dataref>` must be either a mark reference (`:<idnum>`) +# set by a prior `blob` command, or a full 40-byte SHA-1 of an +# existing Git blob object. If `<mode>` is `040000`` then +# `<dataref>` must be the full 40-byte SHA-1 of an existing +# Git tree object or a mark reference set with `--import-marks`. + local re='^M ([0-7]+) (\S+) (.+)' + if [[ $line =~ $re ]]; then + local mode=${BASH_REMATCH[1]} + local dataref=${BASH_REMATCH[2]} + local ifs=$IFS + IFS=$' \t\n' + local path=($(parse_path "${BASH_REMATCH[3]}")) + IFS=$ifs + if [[ -n "${path[1]}" ]]; then + error + fi + get_line + else + return 1 + fi +# +# Inline data format:: +# The data content for the file has not been supplied yet. +# The frontend wants to supply it as part of this modify +# command. +# + +# .... +# 'M' SP <mode> SP 'inline' SP <path> LF +# data +# .... +# + +# See below for a detailed description of the `data` command. + if [[ $dataref = 'inline' ]]; then + get_data + fi +# +# In both formats `<mode>` is the type of file entry, specified +# in octal. Git only supports the following modes: +# +# * `100644` or `644`: A normal (not-executable) file. The majority +# of files in most projects use this mode. If in doubt, this is +# what you want. +# * `100755` or `755`: A normal, but executable, file. +# * `120000`: A symlink, the content of the file will be the link target. +# * `160000`: A gitlink, SHA-1 of the object refers to a commit in +# another repository. Git links can only be specified by SHA or through +# a commit mark. They are used to implement submodules. +# * `040000`: A subdirectory. Subdirectories can only be specified by +# SHA or through a tree mark set with `--import-marks`. +# +} +# In both formats `<path>` is the complete path of the file to be added +# (if not already existing) or modified (if already existing). +# +# A `<path>` string must use UNIX-style directory separators (forward +# slash `/`), may contain any byte other than `LF`, and must not +# start with double quote (`"`). +# +# A path can use C-style string quoting; this is accepted in all cases +# and mandatory if the filename starts with double quote or contains +# `LF`. In C-style quoting, the complete name should be surrounded with +# double quotes, and any `LF`, backslash, or double quote characters +# must be escaped by preceding them with a backslash (e.g., +# `"path/with\n, \\ and \" in it"`). +# +# The value of `<path>` must be in canonical form. That is it must not: +# +# * contain an empty directory component (e.g. `foo//bar` is invalid), +# * end with a directory separator (e.g. `foo/` is invalid), +# * start with a directory separator (e.g. `/foo` is invalid), +# * contain the special component `.` or `..` (e.g. `foo/./bar` and +# `foo/../bar` are invalid). +# +# The root of the tree can be represented by an empty string as `<path>`. +# +# It is recommended that `<path>` always be encoded using UTF-8. +unquote_c_style() { # this is based on the function from git:quote.c + local in=$1 + local out='' + if [[ "${in:0:1}" != '"' ]]; then + return 1 + fi + in=${in:1} + while true; do + #local add="${in%%['"\']*}" + in=${in:${#add}} + out+=$add + case "${in:0:1}" in + '"') + in=${in:1} + printf '%q %q' "$out" "$in" + return 0 + ;; + "\\") + in=${in:1};; + *) + return 1;; + esac + local ch="${in:0:1}" + in=${in:1}; + case "$ch" in + a) ch=$'\a';; + b) ch=$'\b';; + f) ch=$'\f';; + n) ch=$'\n';; + r) ch=$'\r';; + t) ch=$'\t';; + v) ch=$'\v';; + ['"\']) :;; # verbatim + # octal values with first digit over 4 overflow + [0-3]) + ch+="$ch${in:0:2}" + in=${in:2}; + if [[ $ch != [0-3][0-7][0-7] ]]; then + return 1 + fi + ;; + esac + out+=$ch + fi +} +parse_path() { + local str=$1 + local split + if unquote_c_style "$str"; then + : + else + local path="${str%% *}" + local rest="${str#"$path"}" + printf '%q %q' "$path" "$rest" + fi +} +# +# `filedelete` +# ^^^^^^^^^^^^ +# Included in a `commit` command to remove a file or recursively +# delete an entire directory from the branch. If the file or directory +# removal makes its parent directory empty, the parent directory will +# be automatically removed too. This cascades up the tree until the +# first non-empty directory or the root is reached. +# +cmd_commit--filedelete() { +# .... +# 'D' SP <path> LF +# .... + if [[ $line != 'D '* ]]; then + return 1 + fi + local path=${line#D } +# +# here `<path>` is the complete path of the file or subdirectory to +# be removed from the branch. +# See `filemodify` above for a detailed description of `<path>`. +# +} +# `filecopy` +# ^^^^^^^^^^ +# Recursively copies an existing file or subdirectory to a different +# location within the branch. The existing file or directory must +# exist. If the destination exists it will be completely replaced +# by the content copied from the source. +# +cmd_commit--filecopy() { +# .... +# 'C' SP <path> SP <path> LF +# .... +# +# here the first `<path>` is the source location and the second +# `<path>` is the destination. See `filemodify` above for a detailed +# description of what `<path>` may look like. To use a source path +# that contains SP the path must be quoted. +# +# A `filecopy` command takes effect immediately. Once the source +# location has been copied to the destination any future commands +# applied to the source location will not impact the destination of +# the copy. +# +# `filerename` +# ^^^^^^^^^^^^ +# Renames an existing file or subdirectory to a different location +# within the branch. The existing file or directory must exist. If +# the destination exists it will be replaced by the source directory. +# +# .... +# 'R' SP <path> SP <path> LF +# .... +# +# here the first `<path>` is the source location and the second +# `<path>` is the destination. See `filemodify` above for a detailed +# description of what `<path>` may look like. To use a source path +# that contains SP the path must be quoted. +# +# A `filerename` command takes effect immediately. Once the source +# location has been renamed to the destination any future commands +# applied to the source location will create new files there and not +# impact the destination of the rename. +# +# Note that a `filerename` is the same as a `filecopy` followed by a +# `filedelete` of the source location. There is a slight performance +# advantage to using `filerename`, but the advantage is so small +# that it is never worth trying to convert a delete/add pair in +# source material into a rename for fast-import. This `filerename` +# command is provided just to simplify frontends that already have +# rename information and don't want bother with decomposing it into a +# `filecopy` followed by a `filedelete`. +# +# `filedeleteall` +# ^^^^^^^^^^^^^^^ +# Included in a `commit` command to remove all files (and also all +# directories) from the branch. This command resets the internal +# branch structure to have no files in it, allowing the frontend +# to subsequently add all interesting files from scratch. +# +# .... +# 'deleteall' LF +# .... +# +# This command is extremely useful if the frontend does not know +# (or does not care to know) what files are currently on the branch, +# and therefore cannot generate the proper `filedelete` commands to +# update the content. +# +# Issuing a `filedeleteall` followed by the needed `filemodify` +# commands to set the correct content will produce the same results +# as sending only the needed `filemodify` and `filedelete` commands. +# The `filedeleteall` approach may however require fast-import to use slightly +# more memory per active branch (less than 1 MiB for even most large +# projects); so frontends that can easily obtain only the affected +# paths for a commit are encouraged to do so. +# +# `notemodify` +# ^^^^^^^^^^^^ +# Included in a `commit` `<notes_ref>` command to add a new note +# annotating a `<commit-ish>` or change this annotation contents. +# Internally it is similar to filemodify 100644 on `<commit-ish>` +# path (maybe split into subdirectories). It's not advised to +# use any other commands to write to the `<notes_ref>` tree except +# `filedeleteall` to delete all existing notes in this tree. +# This command has two different means of specifying the content +# of the note. +# +# External data format:: +# The data content for the note was already supplied by a prior +# `blob` command. The frontend just needs to connect it to the +# commit that is to be annotated. +# + +# .... +# 'N' SP <dataref> SP <commit-ish> LF +# .... +# + +# Here `<dataref>` can be either a mark reference (`:<idnum>`) +# set by a prior `blob` command, or a full 40-byte SHA-1 of an +# existing Git blob object. +# +# Inline data format:: +# The data content for the note has not been supplied yet. +# The frontend wants to supply it as part of this modify +# command. +# + +# .... +# 'N' SP 'inline' SP <commit-ish> LF +# data +# .... +# + +# See below for a detailed description of the `data` command. +# +# In both formats `<commit-ish>` is any of the commit specification +# expressions also accepted by `from` (see above). +# +# `mark` +# ~~~~~~ +# Arranges for fast-import to save a reference to the current object, allowing +# the frontend to recall this object at a future point in time, without +# knowing its SHA-1. Here the current object is the object creation +# command the `mark` command appears within. This can be `commit`, +# `tag`, and `blob`, but `commit` is the most common usage. +# +# .... +# 'mark' SP ':' <idnum> LF +# .... +# +# where `<idnum>` is the number assigned by the frontend to this mark. +# The value of `<idnum>` is expressed as an ASCII decimal integer. +# The value 0 is reserved and cannot be used as +# a mark. Only values greater than or equal to 1 may be used as marks. +# +# New marks are created automatically. Existing marks can be moved +# to another object simply by reusing the same `<idnum>` in another +# `mark` command. +# +# `tag` +# ~~~~~ +# Creates an annotated tag referring to a specific commit. To create +# lightweight (non-annotated) tags see the `reset` command below. +# +# .... +# 'tag' SP <name> LF +# 'from' SP <commit-ish> LF +# 'tagger' (SP <name>)? SP LT <email> GT SP <when> LF +# data +# .... +# +# where `<name>` is the name of the tag to create. +# +# Tag names are automatically prefixed with `refs/tags/` when stored +# in Git, so importing the CVS branch symbol `RELENG-1_0-FINAL` would +# use just `RELENG-1_0-FINAL` for `<name>`, and fast-import will write the +# corresponding ref as `refs/tags/RELENG-1_0-FINAL`. +# +# The value of `<name>` must be a valid refname in Git and therefore +# may contain forward slashes. As `LF` is not valid in a Git refname, +# no quoting or escaping syntax is supported here. +# +# The `from` command is the same as in the `commit` command; see +# above for details. +# +# The `tagger` command uses the same format as `committer` within +# `commit`; again see above for details. +# +# The `data` command following `tagger` must supply the annotated tag +# message (see below for `data` command syntax). To import an empty +# tag message use a 0 length data. Tag messages are free-form and are +# not interpreted by Git. Currently they must be encoded in UTF-8, +# as fast-import does not permit other encodings to be specified. +# +# Signing annotated tags during import from within fast-import is not +# supported. Trying to include your own PGP/GPG signature is not +# recommended, as the frontend does not (easily) have access to the +# complete set of bytes which normally goes into such a signature. +# If signing is required, create lightweight tags from within fast-import with +# `reset`, then create the annotated versions of those tags offline +# with the standard 'git tag' process. +# +# `reset` +# ~~~~~~~ +# Creates (or recreates) the named branch, optionally starting from +# a specific revision. The reset command allows a frontend to issue +# a new `from` command for an existing branch, or to create a new +# branch from an existing commit without creating a new commit. +# +# .... +# 'reset' SP <ref> LF +# ('from' SP <commit-ish> LF)? +# LF? +# .... +# +# For a detailed description of `<ref>` and `<commit-ish>` see above +# under `commit` and `from`. +# +# The `LF` after the command is optional (it used to be required). +# +# The `reset` command can also be used to create lightweight +# (non-annotated) tags. For example: +# +# ==== +# reset refs/tags/938 +# from :938 +# ==== +# +# would create the lightweight tag `refs/tags/938` referring to +# whatever commit mark `:938` references. +# +# `blob` +# ~~~~~~ +# Requests writing one file revision to the packfile. The revision +# is not connected to any commit; this connection must be formed in +# a subsequent `commit` command by referencing the blob through an +# assigned mark. +# +# .... +# 'blob' LF +# mark? +# data +# .... +# +# The mark command is optional here as some frontends have chosen +# to generate the Git SHA-1 for the blob on their own, and feed that +# directly to `commit`. This is typically more work than it's worth +# however, as marks are inexpensive to store and easy to use. +# +# `data` +# ~~~~~~ +# Supplies raw data (for use as blob/file content, commit messages, or +# annotated tag messages) to fast-import. Data can be supplied using an exact +# byte count or delimited with a terminating line. Real frontends +# intended for production-quality conversions should always use the +# exact byte count format, as it is more robust and performs better. +# The delimited format is intended primarily for testing fast-import. +# +# Comment lines appearing within the `<raw>` part of `data` commands +# are always taken to be part of the body of the data and are therefore +# never ignored by fast-import. This makes it safe to import any +# file/message content whose lines might start with `#`. +# +# Exact byte count format:: +# The frontend must specify the number of bytes of data. +# + +# .... +# 'data' SP <count> LF +# <raw> LF? +# .... +# + +# where `<count>` is the exact number of bytes appearing within +# `<raw>`. The value of `<count>` is expressed as an ASCII decimal +# integer. The `LF` on either side of `<raw>` is not +# included in `<count>` and will not be included in the imported data. +# + +# The `LF` after `<raw>` is optional (it used to be required) but +# recommended. Always including it makes debugging a fast-import +# stream easier as the next command always starts in column 0 +# of the next line, even if `<raw>` did not end with an `LF`. +get_data--exact-byte-count() { + declare -i count="${line#data }" + blob="$(head -c "${count}" | "$RVS" commit.f -)" + get_line + [[ -n $line ]] || get_line +} +# +# Delimited format:: +# A delimiter string is used to mark the end of the data. +# fast-import will compute the length by searching for the delimiter. +# This format is primarily useful for testing and is not +# recommended for real data. +# + +# .... +# 'data' SP '<<' <delim> LF +# <raw> LF +# <delim> LF +# LF? +# .... +# + +# where `<delim>` is the chosen delimiter string. The string `<delim>` +# must not appear on a line by itself within `<raw>`, as otherwise +# fast-import will think the data ends earlier than it really does. The `LF` +# immediately trailing `<raw>` is part of `<raw>`. This is one of +# the limitations of the delimited format, it is impossible to supply +# a data chunk which does not have an LF as its last byte. +# + +# The `LF` after `<delim> LF` is optional (it used to be required). +get_data--delimited() { + local delim="${line#'data <<'}" + blob="$( + while get_line && [[ $line != "$delim" ]]; do + printf '%s\n' "$line" + done | "$RVS" commit.f -)" + get_line + [[ -n $line ]] || get_line +} +get_data() { + if [[ $line = 'data <<'* ]]; then get_data--delimited + elif [[ $line = 'data '+([0-9]) ]]; then get_data--exact-byte-count + else false; fi +} +# +# `checkpoint` +# ~~~~~~~~~~~~ +# Forces fast-import to close the current packfile, start a new one, and to +# save out all current branch refs, tags and marks. +# +# .... +# 'checkpoint' LF +# LF? +# .... +# +# Note that fast-import automatically switches packfiles when the current +# packfile reaches --max-pack-size, or 4 GiB, whichever limit is +# smaller. During an automatic packfile switch fast-import does not update +# the branch refs, tags or marks. +# +# As a `checkpoint` can require a significant amount of CPU time and +# disk IO (to compute the overall pack SHA-1 checksum, generate the +# corresponding index file, and update the refs) it can easily take +# several minutes for a single `checkpoint` command to complete. +# +# Frontends may choose to issue checkpoints during extremely large +# and long running imports, or when they need to allow another Git +# process access to a branch. However given that a 30 GiB Subversion +# repository can be loaded into Git through fast-import in about 3 hours, +# explicit checkpointing may not be necessary. +# +# The `LF` after the command is optional (it used to be required). +# +# `progress` +# ~~~~~~~~~~ +# Causes fast-import to print the entire `progress` line unmodified to +# its standard output channel (file descriptor 1) when the command is +# processed from the input stream. The command otherwise has no impact +# on the current import, or on any of fast-import's internal state. +# +# .... +# 'progress' SP <any> LF +# LF? +# .... +# +# The `<any>` part of the command may contain any sequence of bytes +# that does not contain `LF`. The `LF` after the command is optional. +# Callers may wish to process the output through a tool such as sed to +# remove the leading part of the line, for example: +# +# ==== +# frontend | git fast-import | sed 's/^progress //' +# ==== +# +# Placing a `progress` command immediately after a `checkpoint` will +# inform the reader when the `checkpoint` has been completed and it +# can safely access the refs that fast-import updated. +# +# `cat-blob` +# ~~~~~~~~~~ +# Causes fast-import to print a blob to a file descriptor previously +# arranged with the `--cat-blob-fd` argument. The command otherwise +# has no impact on the current import; its main purpose is to +# retrieve blobs that may be in fast-import's memory but not +# accessible from the target repository. +# +# .... +# 'cat-blob' SP <dataref> LF +# .... +# +# The `<dataref>` can be either a mark reference (`:<idnum>`) +# set previously or a full 40-byte SHA-1 of a Git blob, preexisting or +# ready to be written. +# +# Output uses the same format as `git cat-file --batch`: +# +# ==== +# <sha1> SP 'blob' SP <size> LF +# <contents> LF +# ==== +# +# This command can be used anywhere in the stream that comments are +# accepted. In particular, the `cat-blob` command can be used in the +# middle of a commit but not in the middle of a `data` command. +# +# See ``Responses To Commands'' below for details about how to read +# this output safely. +# +# `ls` +# ~~~~ +# Prints information about the object at a path to a file descriptor +# previously arranged with the `--cat-blob-fd` argument. This allows +# printing a blob from the active commit (with `cat-blob`) or copying a +# blob or tree from a previous commit for use in the current one (with +# `filemodify`). +# +# The `ls` command can be used anywhere in the stream that comments are +# accepted, including the middle of a commit. +# +# Reading from the active commit:: +# This form can only be used in the middle of a `commit`. +# The path names a directory entry within fast-import's +# active commit. The path must be quoted in this case. +# + +# .... +# 'ls' SP <path> LF +# .... +# +# Reading from a named tree:: +# The `<dataref>` can be a mark reference (`:<idnum>`) or the +# full 40-byte SHA-1 of a Git tag, commit, or tree object, +# preexisting or waiting to be written. +# The path is relative to the top level of the tree +# named by `<dataref>`. +# + +# .... +# 'ls' SP <dataref> SP <path> LF +# .... +# +# See `filemodify` above for a detailed description of `<path>`. +# +# Output uses the same format as `git ls-tree <tree> -- <path>`: +# +# ==== +# <mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF +# ==== +# +# The <dataref> represents the blob, tree, or commit object at <path> +# and can be used in later 'cat-blob', 'filemodify', or 'ls' commands. +# +# If there is no file or subtree at that path, 'git fast-import' will +# instead report +# +# ==== +# missing SP <path> LF +# ==== +# +# See ``Responses To Commands'' below for details about how to read +# this output safely. +# +# `feature` +# ~~~~~~~~~ +# Require that fast-import supports the specified feature, or abort if +# it does not. +# +# .... +# 'feature' SP <feature> ('=' <argument>)? LF +# .... +# +# The <feature> part of the command may be any one of the following: +# +# date-format:: +# export-marks:: +# relative-marks:: +# no-relative-marks:: +# force:: +# Act as though the corresponding command-line option with +# a leading '--' was passed on the command line +# (see OPTIONS, above). +# +# import-marks:: +# import-marks-if-exists:: +# Like --import-marks except in two respects: first, only one +# "feature import-marks" or "feature import-marks-if-exists" +# command is allowed per stream; second, an --import-marks= +# or --import-marks-if-exists command-line option overrides +# any of these "feature" commands in the stream; third, +# "feature import-marks-if-exists" like a corresponding +# command-line option silently skips a nonexistent file. +# +# cat-blob:: +# ls:: +# Require that the backend support the 'cat-blob' or 'ls' command. +# Versions of fast-import not supporting the specified command +# will exit with a message indicating so. +# This lets the import error out early with a clear message, +# rather than wasting time on the early part of an import +# before the unsupported command is detected. +# +# notes:: +# Require that the backend support the 'notemodify' (N) +# subcommand to the 'commit' command. +# Versions of fast-import not supporting notes will exit +# with a message indicating so. +# +# done:: +# Error out if the stream ends without a 'done' command. +# Without this feature, errors causing the frontend to end +# abruptly at a convenient point in the stream can go +# undetected. This may occur, for example, if an import +# front end dies in mid-operation without emitting SIGTERM +# or SIGKILL at its subordinate git fast-import instance. +# +# `option` +# ~~~~~~~~ +# Processes the specified option so that git fast-import behaves in a +# way that suits the frontend's needs. +# Note that options specified by the frontend are overridden by any +# options the user may specify to git fast-import itself. +# +# .... +# 'option' SP <option> LF +# .... +# +# The `<option>` part of the command may contain any of the options +# listed in the OPTIONS section that do not change import semantics, +# without the leading '--' and is treated in the same way. +# +# Option commands must be the first commands on the input (not counting +# feature commands), to give an option command after any non-option +# command is an error. +# +# The following command-line options change import semantics and may therefore +# not be passed as option: +# +# * date-format +# * import-marks +# * export-marks +# * cat-blob-fd +# * force +# +# `done` +# ~~~~~~ +# If the `done` feature is not in use, treated as if EOF was read. +# This can be used to tell fast-import to finish early. +# +# If the `--done` command-line option or `feature done` command is +# in use, the `done` command is mandatory and marks the end of the +# stream. diff --git a/modules/module.mk b/modules/module.mk new file mode 100644 index 0000000..b2dbde8 --- /dev/null +++ b/modules/module.mk @@ -0,0 +1,36 @@ +#!/usr/bin/make -f +# Copyright (C) 2009, 2015 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +name := $(lastword $(subst /, ,$(abspath $(srcdir)))) +include $(srcdir)/Makefile.inc.mk + +makefiles = Makefile Makefile.inc.mk +dirs += $(DESTDIR)$(pkglibexecdir)/modules/$(name) +am_src_files += Module.mk +am_sys_files += $(pkglibexecdir)/modules/$(name).mk +am_sys_files += $(addprefix $(pkglibexecdir)/modules/$(name)/,$(am_out_files)) + +$(DESTDIR)$(pkglibexecdir)/modules/$(name).mk: $(srcdir)/Module.mk | $(DESTDIR)$(pkglibexecdir)/modules + $(INSTALL_DATA) $< $@ +$(DESTDIR)$(pkglibexecdir)/modules/$(name)/%: $(srcdir)/% | $(DESTDIR)$(pkglibexecdir)/modules/$(name) + $(INSTALL_PROGRAM) $< $@ +$(DESTDIR)$(pkglibexecdir)/modules/$(name)/%: $(outdir)/% | $(DESTDIR)$(pkglibexecdir)/modules/$(name) + $(INSTALL_PROGRAM) $< $@ + +include $(topsrcdir)/automake.tail.mk diff --git a/modules/tags/Makefile b/modules/tags/Makefile new file mode 120000 index 0000000..fa7273c --- /dev/null +++ b/modules/tags/Makefile @@ -0,0 +1 @@ +../module.mk
\ No newline at end of file diff --git a/modules/tags/Makefile.inc.mk b/modules/tags/Makefile.inc.mk new file mode 100644 index 0000000..1ccdada --- /dev/null +++ b/modules/tags/Makefile.inc.mk @@ -0,0 +1,2 @@ +am_src_files += commit.sh get-tag.sh print.sh tag-id.sh tag.sh +am_out_files += commit get-tag print tag-id tag diff --git a/modules/tags/Module.mk b/modules/tags/Module.mk new file mode 100644 index 0000000..30224d0 --- /dev/null +++ b/modules/tags/Module.mk @@ -0,0 +1 @@ +tags/commit : blobs/commit tree/commit diff --git a/modules/tags/commit.sh b/modules/tags/commit.sh new file mode 100644 index 0000000..d8df1d0 --- /dev/null +++ b/modules/tags/commit.sh @@ -0,0 +1,24 @@ +#!/bin/sh +name='rvs @ID@ commit' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +if [ "$RVS_LEVEL" = '0' ]; then + id=`cat "$TMPDIR/commit/files"` + "$RVS" tag "$id" wch +fi + diff --git a/modules/tags/get-tag.sh b/modules/tags/get-tag.sh new file mode 100644 index 0000000..27d04da --- /dev/null +++ b/modules/tags/get-tag.sh @@ -0,0 +1,25 @@ +#!/bin/sh +name='rvs @ID@ get-tag' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS get-tag FILENAME TAG" +name="${1?"$usage"}" + tag="${2?"$usage"}" + +"$RVS" get "$name" "`"$RVS" tag-id "$tag"`" + diff --git a/modules/tags/print.sh b/modules/tags/print.sh new file mode 100644 index 0000000..f9f7a54 --- /dev/null +++ b/modules/tags/print.sh @@ -0,0 +1,30 @@ +#!/bin/sh +name='print' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="Usage: $RVS $name ID" +id="${1?"$usage"}" + +dir="$REPO/@ID@" +if [ -d "$dir" ]; then + cd "$dir" + echo "Tags:" + grep -rFxl "$id" ./ | sed 's/^\.\/\(.*\)/ \1/' +fi + + diff --git a/modules/tags/tag-id.sh b/modules/tags/tag-id.sh new file mode 100644 index 0000000..050d12e --- /dev/null +++ b/modules/tags/tag-id.sh @@ -0,0 +1,33 @@ +#!/bin/sh +name='tag-id' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS $name TAG" +tag="${1?"$usage"}" + +file="$REPO/@ID@/$tag" + +if [ -f "$file" ]; then + cat "$REPO/@ID@/$tag" +else + echo "$0: cannot find tag \`$tag'" >> /dev/stderr + exit 1 +fi + + + diff --git a/modules/tags/tag.sh b/modules/tags/tag.sh new file mode 100644 index 0000000..90ff0f1 --- /dev/null +++ b/modules/tags/tag.sh @@ -0,0 +1,28 @@ +#!/bin/sh +name='rvs @ID@ tag' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +# tag ID TAG +usage="usage: $RVS tag ID TAG" + ID="${1?"$usage"}" +tag="${2?"$usage"}" + +file="$REPO/@ID@/$tag" +mkdir -p "`dirname "$file"`" +echo "$ID" > "$file" + diff --git a/modules/tree/Makefile b/modules/tree/Makefile new file mode 120000 index 0000000..fa7273c --- /dev/null +++ b/modules/tree/Makefile @@ -0,0 +1 @@ +../module.mk
\ No newline at end of file diff --git a/modules/tree/Makefile.inc.mk b/modules/tree/Makefile.inc.mk new file mode 100644 index 0000000..c91bef2 --- /dev/null +++ b/modules/tree/Makefile.inc.mk @@ -0,0 +1,2 @@ +am_src_files += addparent.d.sh addparent.f.sh addparent.sh commit.sh delparent.f.sh getchildren.sh getparents.sh print.sh +am_out_files += addparent.d addparent.f addparent commit delparent.f getchildren getparents print diff --git a/modules/tree/Module.mk b/modules/tree/Module.mk new file mode 100644 index 0000000..b57eb5a --- /dev/null +++ b/modules/tree/Module.mk @@ -0,0 +1 @@ +tree/commit : blobs/commit diff --git a/modules/tree/addparent.d.sh b/modules/tree/addparent.d.sh new file mode 100644 index 0000000..20c28b4 --- /dev/null +++ b/modules/tree/addparent.d.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +name='addparent.d' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS $name CHILD PARENT" + child=${1?"$usage"} +parent=${2?"$usage"} + +tc="`mktemp`" +tp="`mktemp`" + +"$RVS" ls "$child" '%i\t%n' > "$tc" +"$RVS" ls "$parent" '%i\t%n' > "$tp" + +while read line; do + name="`echo "$line" | cut -f2-`" + nID="`echo "$line" | cut -f1`" + oID="`sed -n "s:^\([a-z]\:[0-9a-f]*\)\t${name/:/\\:}$:\1:p" "$tp"`" + + if [ -n "$oID" ]; then + nT="`"$RVS" blob-gettype "$nID"`" + oT="`"$RVS" blob-gettype "$oID"`" + if [ "$nT" = "$oT" ]; then + "$RVS" addparent "$nID" "$oID" + fi + fi +done < "$tc" + +"$RVS" addparent.f "$child" "$parent" diff --git a/modules/tree/addparent.f.sh b/modules/tree/addparent.f.sh new file mode 100644 index 0000000..5d913da --- /dev/null +++ b/modules/tree/addparent.f.sh @@ -0,0 +1,27 @@ +#!/bin/sh +name='addparent.f' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS $name CHILD PARENT" + child=${1?"$usage"} +parent=${2?"$usage"} + +file="$REPO/tree/$child/$parent" +mkdir -p "`dirname "$file"`" +echo "$parent" > "$file" + diff --git a/modules/tree/addparent.sh b/modules/tree/addparent.sh new file mode 100644 index 0000000..4f1fd86 --- /dev/null +++ b/modules/tree/addparent.sh @@ -0,0 +1,35 @@ +#!/bin/sh +name='addparent' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS $name CHILD PARENT" + child=${1?"$usage"} +parent=${2?"$usage"} + +if [ ! "$child" = "$parent" ]; then + ct="`"$RVS" blob-gettype "$child"`" + pt="`"$RVS" blob-gettype "$parent"`" + + if [ "$ct" = "$pt" ]; then + "$RVS" "addparent.$ct" "$child" "$parent" + else + echo "$0: CHILD and PARENT must be the same type">>/dev/stderr + exit 1 + fi +fi + diff --git a/modules/tree/commit.sh b/modules/tree/commit.sh new file mode 100644 index 0000000..1715f23 --- /dev/null +++ b/modules/tree/commit.sh @@ -0,0 +1,27 @@ +#!/bin/sh +name='rvs @ID@ commit' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +if [ "$RVS_LEVEL" = '0' ]; then + id=`cat "$TMPDIR/commit/files"` + wch="`"$RVS" tag-id wch 2>/dev/null`" + if [ -n "$wch" ]; then + "$RVS" addparent "$id" "$wch" + fi +fi + diff --git a/modules/tree/delparent.f.sh b/modules/tree/delparent.f.sh new file mode 100644 index 0000000..422778d --- /dev/null +++ b/modules/tree/delparent.f.sh @@ -0,0 +1,34 @@ +#!/bin/sh +name='delparent.f' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="usage: $RVS $name CHILD PARENT" + child=${1?"$usage"} +parent=${2?"$usage"} + +file="$REPO/tree/$child/$parent" +rm "$file" +if [ -z "$(ls "`dirname "$file"`")" ]; then + rmdir "`dirname "$file"`" +fi + + dir="$REPO/tree/$child" +if [ -z "$(ls "`dirname "$dir"`")" ]; then + rmdir "`dirname "$dir"`" +fi + diff --git a/modules/tree/getchildren.sh b/modules/tree/getchildren.sh new file mode 100644 index 0000000..4ef5a22 --- /dev/null +++ b/modules/tree/getchildren.sh @@ -0,0 +1,28 @@ +#!/bin/sh +name='getchildren' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="Usage: $RVS $name ID" +id="${1?"$usage"}" + +dir="$REPO/@ID@/" +if [ -d "$dir" ]; then + grep -rFxh "$id" "$dir" +fi + + diff --git a/modules/tree/getparents.sh b/modules/tree/getparents.sh new file mode 100644 index 0000000..c060605 --- /dev/null +++ b/modules/tree/getparents.sh @@ -0,0 +1,27 @@ +#!/bin/sh +name='getparents' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="Usage: $RVS $name ID" +id="${1?"$usage"}" + +dir="$REPO/@ID@/$id" +if [ -d "$dir" ]; then + cat "$dir"/* +fi + diff --git a/modules/tree/print.sh b/modules/tree/print.sh new file mode 100644 index 0000000..709d125 --- /dev/null +++ b/modules/tree/print.sh @@ -0,0 +1,27 @@ +#!/bin/sh +name='print' +ver=0.1 +# Copyright (C) 2010 Luke Shumaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, see <http://www.gnu.org/licenses>. + +usage="Usage: $RVS $name ID" +id="${1?"$usage"}" + +echo "Parents:" +"$RVS" getparents "$id" | sed 's/\(.*\)/ \1/' +echo "Children:" +"$RVS" getchildren "$id" | sed 's/\(.*\)/ \1/' + diff --git a/wrapper/.gitignore b/wrapper/.gitignore new file mode 100644 index 0000000..0c3c90a --- /dev/null +++ b/wrapper/.gitignore @@ -0,0 +1,3 @@ +/outer +/inner +/inner.sh diff --git a/wrapper/Makefile b/wrapper/Makefile new file mode 100644 index 0000000..65a6613 --- /dev/null +++ b/wrapper/Makefile @@ -0,0 +1,36 @@ +#!/usr/bin/make -f +# Copyright (C) 2009, 2015 Luke Shumaker +# +# 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 <http://www.gnu.org/licenses/>. + +include $(dir $(lastword $(MAKEFILE_LIST)))/../config.mk +include $(topsrcdir)/automake.head.mk + +makefiles = Makefile +am_src_files += outer.c inner.sh.m4 runcmd.mk +am_out_files += outer inner +am_clean_files += inner.sh +am_sys_files += $(bindir)/$(PACKAGE) $(pkglibexecdir)/$(PACKAGE) $(pkglibexecdir)/runcmd.mk + +$(outdir)/outer.o: $(topoutdir)/config.h +$(outdir)/inner.sh: $(topoutdir)/config.sh + +$(DESTDIR)$(bindir)/$(PACKAGE) : $(outdir)/outer | $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) $< $@ +$(DESTDIR)$(pkglibexecdir)/$(PACKAGE) : $(outdir)/inner | $(DESTDIR)$(pkglibexecdir) + $(INSTALL_PROGRAM) $< $@ +$(DESTDIR)$(pkglibexecdir)/runcmd.mk : $(srcdir)/runcmd.mk | $(DESTDIR)$(pkglibexecdir) + $(INSTALL_PROGRAM) $< $@ + +include $(topsrcdir)/automake.tail.mk diff --git a/wrapper/inner.sh.m4 b/wrapper/inner.sh.m4 new file mode 100644 index 0000000..b07199e --- /dev/null +++ b/wrapper/inner.sh.m4 @@ -0,0 +1,156 @@ +#!/usr/bin/env bash +# rvs inner.sh - The main RVS program +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# 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 <http://www.gnu.org/licenses/>. +set -u + +m4_include(config.sh) + +declare -r varname_REPO="${PACKAGE^^}_REPO" +declare -r varname_EXEC_PATH="${PACKAGE^^}_EXEC_PATH" + +declare -r program_name="$1"; shift + + + +_() { + if type gettext &>/dev/null; then + TEXTDOMAINDIR=$localedir gettext "$pkgtextdomain" "$1"; + else + echo "$1"; + fi +} + +sighandler_exit() { + local signal=$1; shift + echo + error 0 "$@" + trap -- "$signal" + kill -"$signal" "$$" +} + +install_sighandlers() { + set -E + for signal in TERM HUP QUIT; do + trap "signalhandler_exit $signal '%s signal cought. Exiting...'" $signal + done + trap 'signalhandler_exit INT "Aborted by user. Exiting..."' INT + trap 'kill -USR1 "$$"' ERR +} + +# Like GLibC's error(3), but call gettext on the format string +error() { + >&2 printf "%s: $(_ "$2")\n" "$program_name" "${@:3}" + [[ $1 -eq 0 ]] || exit $1 +} + +errusage() { + >&2 printf "$(_ "$2")\n" "$program_name" "${@:3}" + [[ $1 -eq 0 ]] || exit $1 +} + +_runcmd() { + [[ $# -ge 1 ]] || errusage 1 'Usage: %q <command> [<args>]' + local cmd=$1; shift + local args_str='' + [[ $# -eq 0 ]] || printf -v args_str '%q ' "$@" + + local exec_path="${!varname_EXEC_PATH:-$pkglibexecdir}" + + shopt -s nullglob + local files=("${exec_path}"/modules/*/"$cmd") + if [[ ${#files[@]} -eq 0 ]]; then + error 127 '%s: Not a %s command' "$cmd" "$PACKAGE" + fi + files=("${files[@]#"${exec_path/modules/}"}") + + local tmpdir + trap '[ -z "${tmpdir:-}" ] || rm -rf -- "$tmpdir"' EXIT + tmpdir="$(mktemp -dt "${PACKAGE}.XXXXXXXXXX")" + mkdir -- "$tmpdir/output" + + local repo + repo="$(_repo)" + export "${varname_REPO}=${repo}" + + local cwd + printf -v cwd '%q' "$PWD" + + make -j1 \ + -f "$exec_path/runcmd.mk" \ + -C "$tmpdir/output" \ + CWD="$cwd" \ + ARGS="$args_str" \ + EXEC_PATH="$exec_path" \ + TMPDIR="$tmpdir" \ + -- "${files[@]}" + exit $? +} + +_repo() { + [[ $# -ne 0 ]] || errusage 1 'Usage: %q repo' + if [ -z "${!varname_REPO:-}" ]; then # we aren't getting a value from then env + local repo=".${PACKAGE,,}" + + # [------can ascend-----] && ! [-not found repo--] + while [ "$PWD" != "$OLDPWD" ] && ! [ -d "$PWD/$repo" ]; do + cd .. + done + + if [ -d "$PWD/$repo" ]; then + # we found a repository + printf '%s\n' "$PWD/$repo" + else + # we didn't find a repository + error 128 "No %s repository found" "$PACKAGE" + fi + else + printf '%s\n' "${!varname_REPO}" + fi +} + +_init() { + [[ $# -gt 1 ]] || errusage 1 'Usage: %q init [directory]' + local dir="${1:-$PWD}" + mkdir -p -- "$dir" + cd "$dir" + repo="$(_repo 2> /dev/null)" || true + if [ -n "${repo:-}" ]; then + error 129 "Repository already exists at \`%s'" "$repo" + fi + export "$varname_REPO=$PWD/.${PACKAGE,,}" + mkdir "${!varname_REPO}" + _runcmd init "$dir" +} + +main() { + install_sighandlers + [[ $# -ge 1 ]] || error 'No command specified';; + export "${PACKAGE^^}=$program_name" + + local cmd=$1; shift + case "$cmd" in + repo) _repo "$@";; + init) _init "$@";; + *) _runcmd "$cmd" "$@";; + esac +} + +main "$@" + +# Copy/Paste Virus 1.3c Please copy and paste this text anywhere. Track +# its progress by searching for this MD5#f7eac285ebfe21c4587bfebb9582f90d diff --git a/wrapper/outer.c b/wrapper/outer.c new file mode 100644 index 0000000..c465555 --- /dev/null +++ b/wrapper/outer.c @@ -0,0 +1,63 @@ +/* RVS outer.c - A wrapper for $(bindir) to call the main RVS program + * Copyright (C) 2015 Luke Shumaker + * + * This file is part of rvs. + * + * 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 <http://www.gnu.org/licenses/>. + */ +#include <errno.h> /* for errno */ +#include <error.h> /* for error(3) */ +#include <libintl.h> /* for dgettext(3) */ +#include <locale.h> /* for bindtextdomain(3) and textdomain(3) */ +#include <stdio.h> /* for asprintf(3) */ +#include <stdlib.h> /* for getenv(3), calloc(3) */ +#include <string.h> /* for mempcy(3) */ +#include <unistd.h> /* for execv(3) */ + +#include "config.h" +#define _ gettext + +#define EXIT_FAILURE_OOM 126 +#define EXIT_FAILURE_EXEC 127 + +int +main(int argc, char *argv[]) { + bindtextdomain(pkgtextdomain, localedir); + textdomain(pkgtextdomain); + + unsetenv("ENV"); + unsetenv("BASH_ENV"); + + const char *varname = PACKAGE_UPPER "_EXEC_PATH"; + + char *exec_path = getenv(varname); + if (!exec_path) + exec_path = pkglibexecdir; + + char *exec_file = NULL; + if (asprintf(&exec_file, "%s/" PACKAGE, exec_path) < 0) + error(EXIT_FAILURE_OOM, errno, + _("Could not allocate memory for string")); + + char **args = calloc(argc+2, sizeof(char*)); + if (!args) + error(EXIT_FAILURE_OOM, errno, + _("Could not allocate cleared memory")); + args[0] = exec_file; + memcpy(&args[1], argv, sizeof(char*) * argc); + + execv(exec_file, args); + error(EXIT_FAILURE_EXEC, errno, _("Could not execute: %s"), exec_file); + return EXIT_FAILURE_EXEC; +} diff --git a/wrapper/runcmd.mk b/wrapper/runcmd.mk new file mode 100644 index 0000000..7340d11 --- /dev/null +++ b/wrapper/runcmd.mk @@ -0,0 +1,15 @@ +#!/usr/bin/make -f + +# Environment/command line variables: +# - ARGS +# - EXEC_DIR +# - CWD + +SHELL = bash -o pipefail + +export OUTPUT_DIR := $(realpath .) + +% : $(EXEC_PATH)/modules/% + cd $(CWD) && '$<' $(ARGS) | tee -- '$@' | sed 's,^,$@:,' >/dev/tty + +include $(wildcard $(EXEC_PATH)/modules/*.mk) |