XML DTD for the package configuration file

Daan Leijen daanleijen at xs4all.nl
Wed Oct 15 14:53:11 EDT 2003


Hi all,

Although creating package description files in XML
sounds neat, it also sounds like over-design at this
stage. Why don't we use Haskell *values* to describe
the packages? If we describe packages just like ghc-pkg
is doing, as a Haskell record, we get:

- very simple code for reading and writing those
- syntax that is understood by all haskell programmers
- optional elements (by using records)
- list elements (by using lists)


Might be not as powerful as using XML, but it might
be just right for the thing we are trying to do.

Just my 2cents,

-- Daan Leijen


> -----Original Message-----
> From: libraries-bounces at haskell.org 
> [mailto:libraries-bounces at haskell.org] On Behalf Of Isaac Jones
> Sent: woensdag 15 oktober 2003 6:55
> To: libraries
> Subject: XML DTD for the package configuration file
> 
> 
> This is my first attempt at an XML DTD.  Does anyone have any 
> suggestions for good XML references either a book or a web 
> site? Google seems to be suffering from too much XML 
> information.  Is there a Haddock / Javadoc type way to notate 
> a DTD?  Should I be using schemas?  Are they overkill?  What 
> do you think of the style? Sometimes I have trouble choosing 
> between using an attribute, and using a nested element.  For instance:
> 
> <envitem><var>x</var><val>y</val></envitem>
> 
> verses
> 
> <envitem var="x">y</envitem>
> 
> Here's a shot at a DTD for the packages configuration file 
> and an example config file that validates with the DTD (I 
> used xmllint --noout --valid) and the Haskell datatype that 
> it's meant to reflect. I expect it will change a lot as I 
> learn more about XML and about packaging, but I wanted to get 
> it out there in case I'm going horribly wrong somehow.
> 
> I'm not really satisfied with the version stuff or the 
> versionrange stuff (mostly the Haskell code).
> 
> Slight background for people who know less about xml than me: 
> a DTD is a means of verifying that an XML file has the 
> correct structure.  It seems rather limited in that there are 
> no types, and the regular expressions are weaker than one 
> might expect (I can't say "the data in this field should 
> correspond to the following regexp).  XML Schemas seem to fix 
> some of these problems.  But DTDs seem to be a nice way to 
> document and share information about the format of an XML file.
> 
> peace,
> 
> isaac
> 
> ------------------------------------------------------------
> Packages.dtd
> ------------------------------------------------------------
> -- CUT HERE --
> <!ELEMENT packageconf (package+)>
> <!ATTLIST packageconf version CDATA #REQUIRED>
> 
> <!-- package -->
> <!ELEMENT package 
> (version?,importdirs?,sourcedirs?,librarydirs?,hslibraries?,ex
> tralibraries?,depends?,builddepends?,ccopts?,ldopts?,environme
> nt?,graftpoint?,extraframeworks?)>
> <!ATTLIST package version CDATA #IMPLIED>
> 
> <!ATTLIST package name CDATA #REQUIRED>
> <!ATTLIST package auto (false | true) "false">
> 
> <!ELEMENT packageident (#PCDATA)>
> 
> <!-- Path related -->
> <!ELEMENT filepath (#PCDATA)>
> <!ELEMENT sourcedirs (filepath+)>
> <!ELEMENT importdirs (filepath+)>
> <!ELEMENT librarydirs (filepath+)>
> 
> <!-- Libraries -->
> <!ELEMENT hslibraries (library+)>
> <!ELEMENT cincludes (include+)>
> <!ELEMENT extralibraries (library+)>
> <!ELEMENT library (#PCDATA)>
> <!ELEMENT include (#PCDATA)>
> 
> <!-- Options -->
> <!ELEMENT ccopts (option+)>
> <!ELEMENT ldopts (option+)>
> <!ELEMENT option (#PCDATA)>
> <!ATTLIST option type (short | long | verbatim) "verbatim">
> 
> <!-- Depends -->
> <!ELEMENT builddepends (dependency+)>
> <!ELEMENT depends      (dependency+)>
> 
> <!ELEMENT dependency   (versionrange?)>
> <!ATTLIST dependency name CDATA #REQUIRED>
> <!ATTLIST dependency version CDATA #IMPLIED>
> 
> <!-- Documentation -->
> <!ELEMENT haddockhtmlroot  (#PCDATA)>
> <!ELEMENT haddockinterface (#PCDATA)>
> 
> <!-- Versioning -->
> <!ELEMENT versionrange (version,version?)> <!-- second one is 
> for range --> <!ATTLIST versionrange type (any | orlater | 
> exactly | orearlier | between) "orlater">
> 
> <!-- I'm not exactly satisfied with this. I should also be 
> able to say <= -->
> <!-- and >=, but these are already pretty verbose. -->
> 
> <!ELEMENT version (numberversion | simpleversion | 
> dateversion)> <!ELEMENT numberversion (major?,minor?,patch?)> 
> <!ELEMENT simpleversion (#PCDATA)>
> 
> <!ELEMENT major (#PCDATA)>
> <!ELEMENT minor (#PCDATA)>
> <!ELEMENT patch (#PCDATA)>
> 
> <!ELEMENT dateversion (year,month?,day?,patch?)>
> <!ELEMENT year  (#PCDATA)>
> <!ELEMENT month (#PCDATA)>
> <!ELEMENT day   (#PCDATA)>
> <!-- Simpleversions should be a fixed format: 1.2.3-4 or so -->
> 
> <!-- Environment -->
> <!ELEMENT environment (envitem+)>
> <!ELEMENT envitem (var,val)+>
> <!ELEMENT var (#PCDATA)>
> <!ELEMENT val (#PCDATA)>
> <!--        Or maybe this would be preferred? -->
> <!--        <envitem> var="boing">boo</envitem> -->
> 
> <!-- Misc -->
> <!ELEMENT graftpoint (#PCDATA)>
> <!ELEMENT extraframeworks (framework+)>
> <!ELEMENT framework (#PCDATA)>
> -- CUT HERE --
> 
> ------------------------------------------------------------
> Packages.xml
> ------------------------------------------------------------
> -- CUT HERE --
> <?xml version="1.0"?>
> <!DOCTYPE packageconf  SYSTEM "Packages.dtd">
> <packageconf version="0.1">
>   <package name="packageName" version="1.0" auto="true">
>     <importdirs><filepath>/foo</filepath>
>                 <filepath>/foo/bar/bang</filepath></importdirs>
>     <sourcedirs><filepath>/foo</filepath>
>                 <filepath>/foo/bar/bang</filepath></sourcedirs>
> 
>     <graftpoint>System.IO</graftpoint>
>   </package>
> <!-- ============================== -->
>   <package name="dependExample" version="3">
>      <builddepends>
>         <dependency name="otherPkg">
>           <versionrange type="exactly">
> 	    <version><simpleversion>3.4.5-6</simpleversion></version>
> 	  </versionrange>
>         </dependency>
> 
>         <dependency name="otherPkg2">
>           <versionrange type="orlater">
> 	    
> <version><dateversion><year>1998</year></dateversion></version>
> 	  </versionrange>
>         </dependency>
> 
> 	<dependency name="otherPkg3" version="2.0.0-0" />
> 
>         <dependency name="otherPkg3">
>           <versionrange type="between">
> 	    <version><simpleversion>3.3</simpleversion></version>
> 	    <version><simpleversion>3.5</simpleversion></version>
> 	  </versionrange>
>         </dependency>
> 
>      </builddepends>
>   </package>
> <!-- ============================== -->
>   <package name="optionExample">
>      <version><numberedversion><major>10</major>
>                                <minor>11</minor>
>                                
> <patch>12</patch></numberedversion></version>
>      <ccopts>
>          <option type="short">b</option>
>          <option type="long">foo</option>
>          <option type="verbatim">--bar</option>
>          <option>--bang</option>
>      </ccopts>
> 
>      <environment>
>        <envitem><var>foo</var><val>bar</val></envitem>
>        <envitem><var>bang</var><val>baz</val></envitem>
>      </environment>
>   </package>
> </packageconf>
> -- CUT HERE --
> ------------------------------------------------------------
> Package Config data structure
> ------------------------------------------------------------
> -- CUT HERE --
> data PkgIdentifier
>     = PkgIdentifier {pkgName::String, pkgVersion::Version}
> {- ^Often need name and version since multiple versions of a single
>     package can exist on a system. -}
> 
> data PackageConfig
>    = Package {
>         pkgIdent        :: PkgIdentifier,
>         license         :: License,
>         auto            :: Bool,
> <!--         provides        :: [String], -->
> <!-- {- ^A bit pie-in-the-sky; might indicate that this 
> package provides -->
> <!--     functionality that other packages also provide, such 
> as a compiler -->
> <!--     or GUI framework, and upon which other packages 
> might depend. -} -->
> 
> <!--         isDefault       :: Bool, -->
> <!-- -- ^might indicate if this is the default compiler or 
> GUI framework. -->
> <!-- think through isDefault more, maybe we actually want a 
> list of defaults -->
> 
>         import_dirs     :: [FilePath],
>         source_dirs     :: [FilePath],
>         library_dirs    :: [FilePath],
>         include_dirs    :: [FilePath],
>         hs_libraries    :: [String],
>         extra_libraries :: [String],
>         c_includes      :: [String],
>         build_deps      :: [Dependency], -- build dependencies
>         depends         :: [Dependency], -- use dependencies
> <!--         extra_ghc_opts  :: [String], -->
>         extra_cc_opts   :: [String],
>         extra_ld_opts   :: [String],
>         framework_dirs  :: [String],
>         haddock_html_root :: String,
>         haddock_interface :: String,
>         default_grafting_point :: String,
> -- ^Related to new packages proposal
>         vars            :: [(String, String)],
> -- ^Variable, value pairs, whatever author wants here
>         extra_frameworks:: [String]}
> 
> data Version = DateVersion {versionYear  :: Integer,
>                             versionMonth :: Month,
>                             versionDay   :: Integer}
>              | NumberedVersion {versionMajor      :: Integer,
>                                 versionMinor      :: Integer,
>                                 versionPatchLevel :: Integer}
> 
> data License = GPL | LGPL | BSD | {- ... | -} OtherLicense FilePath
> 
> data Dependency = Dependency String VersionRange
> 
> data VersionRange
>   = AnyVersion
>   | OrLaterVersion     Version
>   | ExactlyThisVersion Version
>   | OrEarlierVersion   Version
> 
> type PackageMap = FiniteMap PkgIdentifier PackageConfig
> -- CUT HERE --
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org 
> http://www.haskell.org/mailman/listinfo/librar> ies
> 
> 




More information about the Libraries mailing list