_PLaneT_ The PLaneT Module Repository Interaction Collection The PLaneT system is a method for automatically sharing code packages, both as libraries and as full applications, that gives every user of a PLaneT client the illusion of having a local copy of every code package on the server, but is parsimonious in its transmission. It consists of a centralized server that holds all packages and individual clients that hold some portion of the archive locally. Maintenance of that archive should be transparent, and is the complete responsibility of the PLaneT client. The PLaneT client receives user requests (i.e., the (require (planet ...)) forms) and loads the appropriate modules in response. In the course of handling these requests it may download new code packages from the PLaneT server. The structure of user PLaneT invocations is listed below. PLANET-REQUEST ::= (planet FILE-NAME PKG-SPEC [PATH ...]) FILE-NAME ::= string PKG-SPEC ::= string | (FILE-PATH ... PKG-NAME) | (FILE-PATH ... PKG-NAME VER-SPEC) VER-SPEC ::= Nat | (Nat MINOR) MINOR ::= Nat ; the specified revision or above | (Nat Nat) ; a revision between the two specified numbers (inclusive) | (= Nat) ; exactly the revision specified | (+ Nat) ; the specified revision or above | (- Nat) ; the specified revision or below FILE-PATH ::= string ; the path to the given package in the repository PKG-NAME ::= string OWNER-NAME ::= string PATH ::= string ; the subdirectory path to the specified file within the package All strings must be legal filename strings. When encountered, a planet-request is interpreted as requiring the given file name from the given logical package, specified by the client's host language (automatically deduced by the client), the package spec and the collection specification, if given. If no VER-SPEC is provided, the most recent version is assumed. If no owner-name/path ... clause is provided, the default package is assumed. For example, (require (planet "test-connection.ss" ("planet" "test-connection.plt" 1 0))) requires the file "test-connection.ss" from the package owned by "planet" called "test-connection.plt", and says that any package with major version 1 and any minor version greater than or equal to 0 will do. _config.ss_: client configuration This file provides several parameters useful for configuring how PLaneT works. Parameters: > (PLANET-DIR) -> directory-string > (PLANET-DIR directory-string) -> void The root PLaneT directory. If the environment variable PLTPLANETDIR is set, default is its value; otherwise the default is the directory in which config.ss is found. > (CACHE-DIR) -> directory-string > (CACHE-DIR directory-string) -> void The root of the PLaneT client's cache directory. > (UNINSTALLED-PACKAGE-CACHE) -> directory-string > (UNINSTALLED-PACKAGE-CACHE directory-string) -> void The root of the PLaneT client's uninstalled-packages cache. PLaneT stores package distribution files in this directory, and searches for them in this directory for them if necessary. Unlike the main PLaneT cache, which contains compiled files and is specific to each particular version of PLT Scheme, the uninstalled package cache is shared by all versions of PLT Scheme that use the same package repository, and it is searched if a package is not installed in the primary cache. This behavior is intended to primarily benefit users who upgrade their PLT Scheme installations frequently. > (LINKAGE-FILE) file-string > (LINKAGE-FILE file-string) -> void The file to use as the first place PLaneT looks to determine how a particular PLaneT dependence in a file should be satisfied. The contents of this file are used to ensure that no "magic upgrades" occur after a package is installed. The default is the file "LINKAGE" in the root PLaneT directory. > (LOG-FILE) -> file-string or #f > (LOG-FILE [file-string or #f]) -> void If #f, indicates that no logging should take place. Otherwise specifies the file into which logging should be written. The default is the file "INSTALL-LOG" in the root PLaneT directory. > (USE-HTTP-DOWNLOADS?) -> boolean > (USE-HTTP-DOWNLOADS? boolean) -> void PLaneT can use two different protocols to retrieve packages. If #t, PLaneT will use the HTTP protocol; if #f it will use the custom-built PLaneT protocol. The default value for this parameter is #t. > (HTTP-DOWNLOAD-SERVLET-URL) -> url-string > (HTTP-DOWNLOAD-SERVLET-URL url-string) -> void The URL for the servlet that will provide PLaneT packages if USE-HTTP-DOWNLOADS? is #t, represented as a string. The default value is "http://planet.plt-scheme.org/servlets/planet-servlet.ss". > (PLANET-SERVER-NAME) -> string > (PLANET-SERVER-NAME string) -> void The name of the PLaneT server to which the client should connect if USE-HTTP-DOWNLOADS? is #f. The default value for this parameter is "planet.plt-scheme.org". > (PLANET-SERVER-PORT) -> Nat > (PLANET-SERVER-PORT Nat) -> void The port on the server the client should connect to if USE-HTTP-DOWNLOADS? is #f. The default value for this parameter is 270. Note that while these parameters can be useful to modify programmatically, PLaneT code runs at module-expansion time and so most user programs cannot set them until PLaneT has already run. Therefore to meaningfully change these settings it is best to manually edit the config.ss file. _util.ss_ utility functions The functions in this module support examination of the pieces of PLaneT. They are meant primarily to support debugging and to allow easier development of higher-level package-management tools. > (download/install-pkg string? string? nat nat) -> (union pkg? false/c)) Downloads and installs the package specifed by the given owner name, package name, major and minor version number. Returns false if no such package is available; otherwise returns a package structure for the installed package. > (current-cache-contents) -> ((string ((string ((nat (nat ...)) ...)) ...)) ...) Returns a listing of all package names and versions installed in the local cache. > (current-linkage) -> ((filename (package-name nat nat) ...) ...) Gives the current linkage table. > (make-planet-archive directory [file-string]) -> file-string Makes a .plt archive file suitable for PLaneT whose contents are all files in the given directory and returns that file's name. If the optional filename argument is provided, that filename will be used as the output file's name. > (remove-pkg owner name major-version minor-version) -> void Removes the specified package from the local planet cache. Owner and name must be strings; major-version and minor-version must be natural numbers and major-version must be greater than zero. > (unlink-all) -> void Removes the entire linkage table from the system, which will force all modules to relink themselves to PLaneT modules the next time they run. > (add-hard-link owner name major-version minor-version directory) -> void Adds a development link between the specified package and the given directory; once a link is established, PLaneT will treat the cache as having a package with the given owner, name, and version whose files are located in the given path. This is intended for package development; users only interested in using PLaneT packages available online should not need to create any development links. owner and name must be strings, major-version and minor-version must be natural numbers, and directory must be a path (not a string) indicating a directory. If the specified package already has a development link, this function first removes the old link and then adds the new one. > (remove-hard-link owner name major-version minor-version) -> void Removes any hard link that may be associated with the given package. > (resolve-planet-path quoted-planet-require-spec) -> path Returns the file system path to the file specified by the given quoted planet require specification. This function downloads and installs the specified package if necessary, but does not verify that the actual file within it actually exists. _The PLaneT search order_ ------------------------- PLaneT has three strategies it uses to match a request with an appropriate package that it tries in order. 1. Previous linkage Whenever a file requires a package via PLaneT and that requirement is satisfied, the system makes a note of exactly which package satisfied that requirement and from then on always uses that exact same package, even if a newer version is available. This is done to prevent "magic upgrades" in which a program stops working after installation because an unrelated package was installed. Such connections are called links and are stored in a user-specific table called the linkage table. 2. Acceptable local package If the PLaneT client doesn't have any previous linkage information, it checks its list of already-installed PLaneT packages for one that meets the requirement, and uses it if available. Both PLaneT-installed packages and packages established through a development link are checked simultaneously at this stage. 3. Acceptable remote package If there is no acceptable local package, the PLaneT client sends a request to the PLaneT server for a new package that would satisfy the requirement. The server then finds the newest matching package and sends it back to the client, which then installs it and uses it to satisfy the original requirement. _The planet command-line tool_ ------------------------------ The planet command-line tool allows you to examine and manipulate your local planet cache and linkage table. It has several modes (only one of which may be used in a single invocation): -f, --file Install local file as though it had been downloaded from the planet server. The installed package has path (planet ( )), where maj and min are natural numbers and maj is greater than 0. -c, --create-archive Create a PLaneT archive in the current directory whose contents are the directory -i, --install Download and install the package that (require (planet "file.ss" ( )) would install. In this mode, min can be any s-expression that the (require (planet ...)) form can interpret, not just a natural number. This function updates the uninstalled-package cache if it downloads a package that already appears there. -d, --download Download the given package file (specified as with the --install flag) without installing it. This function does not update the uninstalled-package cache. -r, --remove Remove the specified package from the local cache. -e, --erase Remove the specified package from the local cache and the uninstalled-packages cache. -p, --packages List the packages installed in the local cache. -l, --linkage List the current linkage table -U, --unlink-all Clear the linkage table, unlinking all packages and allowing upgrades. -a, --associate Create a development link from the given package specifier to the given directory, clearing any previous development links that may have been in place. (See below for an explanation of what development links are.) -u, --unassociate Remove any development links from the given package specifier. _Development links_ ------------------- To aid development, PLaneT allows users to establish direct associations between a particular planet package (e.g. myname myfirstpackage.plt 1 0) with an arbitrary directory on the filesystem (e.g., /home/myname/svn/mypackages/devel/). These associations are intended to allow developers to use their own directory structures, version control systems, etc. while developing PLaneT packages while still being able to use the packages they create as though they were distributed directly by PLaneT. Development links are local to a particular user and repository (but not to a particular MzScheme minor revision). To establish a development link, use the planet command-line tool: $ planet --associate myname mypackage.plt 1 0 ~/svn/mypackages/devel Once you are finished developing a package, you should remove any development links you have established for it, again using the planet command-line tool: $ planet --unassociate myname mypackage.plt 1 0 _Distributing Packages with PLaneT_ ----------------------------------- To put a package on PLaneT, or release an upgrade to an already-existing package: 0. WRITE YOUR PACKAGE PLaneT can distribute whatever programs you write, but keep these guidelines in mind as you write: i. Organize your code into modules. Since the planet client is integrated into mzscheme's `require' form, it works best if your code is arranged into modules. ii. When one module in your program depends on another, it is best to require it using the relative-file-name form rather than the planet require form. For instance, if your program contains files primary.ss and helper.ss where primary.ss requires helper, use the form (require "helper.ss") instead of (require (planet "helper.ss" ("username" "packagename.plt" 1 0))) in files that will also be a part of the package. 1. PREPARE A DIRECTORY Make sure that all source files, documentation, etc. that you want to be a part of the package are in a single directory and its subdirectories. Furthermore make sure that nothing else, e.g. unneeded backup files, is in that directory (with the exception that the subdirectories and files CVS or Subversion creates are allowed). For instance, in the following directory tree, my-app/ is set up appropriately: home/ ... jacob/ ... my-app/ doc.txt my-app.ss graphic-for-my-app.png private/ implementation.ss There are no strict requirements for what sorts of files can go in your package, but for it to work well with PLT Scheme's module system you should arrange your Scheme code into modules. 2. CREATE INFO.SS AND DOC.TXT FILES [OPTIONAL] If you put a file named info.ss in your package's root directory, the PLaneT system will look in it for descriptive metadata about your package. The PLaneT system looks for certain names in that file: The _'blurb field_ If present, the blurb field should contain a list of XHTML fragments encoded as x-expressions (see the xml collection for details) that PLaneT will use as a short description of your project. This field is also used by the Help Desk. The _'categories field_ If present, the categories field should be a list of symbols corresponding to the categories under which this package should be listed. The valid categories are: Symbol Description ------ ----------- devtools Development Tools net Networking and Protocols media Graphics and Audio xml XML-Related datastructures Data Structures and Algorithms io Input/Output and Filesystem scientific Mathematical and Scientific system Hardware/Operating System-Specific Tools ui Textual and Graphical User Interface metaprogramming Metaprogramming Tools planet PLaneT-Related misc Miscellaneous If you put symbols other than these the categories field, they will be ignored. If you put no legal symbols in the categories field or do not include this field in your info.ss file, your package will be categorized as "Miscellaneous." The _'can-be-loaded-with field_ If present, the can-be-loaded-with field should be a quoted datum of one of the following forms: can-be-loaded-with = 'all | 'none | (list 'all-except VER-SPEC ...) | (list 'only VER-SPEC ...) where VER-SPEC is a quoted instance of the VER-SPEC form defined at the beginning of this document. Depending on your package's behavior, it may or may not be okay for multiple versions of the same package to be loaded at one time on the entire system --- for instance, if your package relies on writing to a particular file and assumes that nothing else writes to that same file, then multiple versions of the same package being loaded simultaneously may be a problem. This field allows you to specify whether your package can be loaded simultaneously with older versions of itself. If its value is 'all, then the package may be loaded with any older version. If it is 'none, then it may not be loaded with older versions at all. If it is (list 'all-except VER-SPEC ...) then any package except those that match one of the given VER-SPEC forms may be loaded with this package; if it is (list 'only VER-SPEC ...) then only packages that match one of the given VER-SPEC forms may be loaded with this package. When checking to see if a package may be loaded, PLaneT compares it to all other currently-loaded instances of the same package with any version: for each comparison, it checks to see if the newer package's can-be-loaded-with field allows the older package to be loaded. If all such comparisons succeed then the new package may be loaded; otherwise PLaneT signals an error. The default for this field is 'none as a conservative protection measure. For many packages it is safe to set this field to 'any. The _'doc.txt field_ If present, the doc.txt field should be a string corresponding to the name (without path) of the text documentation file for your package. If this field is the value "doc.txt" and a file called "doc.txt" exists in your package's root directory, it will be used as the online documentation visitors to the planet.plt-scheme.org website will be able to read. The _'html-docs field_ If present, this field should be a list of strings representing subdirectories of your package. These directories will be used by Help Desk as HTML documentation for your package. See _Creating Help Desk Documentation in HTML format_ for more information on how to use HTML Help Desk documentation. The _'homepage field_ If present, the URL field should be a string corresponding to a URL for the package. PLaneT provides this link with the description of your package on the main PLaneT web page. The _'primary-file field_ If present, the primary-file field should be a string corresponding to the name (without path) of the main Scheme source file of your package. PLaneT will direct casual users of your library to require this file. The _'required-core-version field_ If present, the required-core-version field should be a string with the same syntax as the output of mzscheme's built-in (version) function. Defining this field indicates that PLaneT should only allow users of a version of mzscheme equal to or more recent than the version specified by this field. This allows you finer-grained control of your package's core-language requirements than its inclusion in a particular repository; for instance, setting this field to "300.2" would cause the PLaneT server not to serve it to MzScheme v300 clients. The _'version field_ If present, the version field should describe the version number of this code that should be presented to users (e.g., "0.15 alpha"). This field does not override or in any way interact with your package's package version number, which is assigned by PLaneT, but may be useful to users. In addition, PLaneT uses the setup-plt installer to install packages on client machines, so most fields it looks for can be included with their usual effects. In particular, adding a name field indicates that the Scheme files in the package should be compiled during installation; it is probably a good idea to add it. An example info.ss file looks like this: (module info (lib "infotab.ss" "setup") (define name "My Application") (define blurb (list "My application runs 60% faster on 20% less peanut " "butter. It even shows a fancy graphic!")) (define primary-file "my-app.ss") (define doc.txt "doc.txt") (define categories '(system xml))) See the PLT mzc: MzScheme Compiler Manual, chapter 7 for more information on info.ss files. The other special file PLaneT looks for in the root directory of your package is doc.txt. Its contents should be documentation for your package. Its contents will be available as a link on your package's listing on the PLaneT web page. 3. BUILD A .PLT FILE Use the planet command-line tool in its archive-creation mode to create a planet archive: planet --create-archive /home/jacob/my-app/ This will create a planet archive named my-app.plt in the current directory whose contents are the contents of /home/jacobm/my-app and all its subdirectories. Alternately, you can run the function make-planet-archive from the util.ss module in the planet collection with the name of the directory you've prepared as its argument: (make-planet-archive "/home/jacob/my-app/") This function will build a packaged version of your directory and return the path to that package. The path will always be a file named X.plt, where X is the name of the directory you gave to make-planet-archive, located in that same directory. You can now test that your .plt file works as intended using the planet command-line tool in its install mode: planet --file will install the specified .plt file into your local PLaneT cache as though it had been downloaded from the PLaneT server with the given owner name and major and minor versions. After you run this command, you can require your package on your local machine using (require (planet ( <.plt file name without path> ))) to verify everything works. After you do so, you can use planet --remove <.plt file name> to remove the test package from your local cache. (Not removing it is safe as long as you use the same name and version numbers the package will have on the official PLaneT server; otherwise you may experience problems.) 4. SUBMIT THE PACKAGE E-mail the .plt file you built to jacobm+planet@plt-scheme.org If the package is an upgrade to a prior package, then tell me so and tell me whether or not this package is backwards-compatible with the package it's upgrading. Also tell me what PLT Scheme version this package is intended for. There's no particular format for this message; the system isn't automated yet so I'll just be reading these and processing them by hand. Once I've added your package to the repository, I'll e-mail you back and tell you the require-line users will need to type in to get it. WARNING: It's very important that packages you say are backwards-compatible with the prior version, at a minimum contain all the same modules and provide all the same names the prior version did. If you do not, programs that use your package will break on some systems.