
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@haskell.org [mailto:libraries-bounces@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, --> <!-- 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@haskell.org http://www.haskell.org/mailman/listinfo/librar> ies