Previously we looked inside a .pod file. The pod being the main artifact from a Fantom project. Now let's take a detailed look at how it's made. Again we'll take BedSheet as a real world example.

afBedSheet.pod was built by running its build.fan, a Fantom script held in the root of the project directory. It it shown below:

select all
using build

class Build : BuildPod {

    new make() {
        podName = "afBedSheet"
        summary = "Something fresh and clean to lay your web app on!"
        version = Version("1.3.4")

        meta = [
            "org.name"        : "Alien-Factory",
            "org.uri"         : "http://www.alienfactory.co.uk/",
            "proj.name"       : "BedSheet",
            "proj.uri"        : "http://www.fantomfactory.org/pods/afBedSheet",
            "vcs.uri"         : "https://bitbucket.org/AlienFactory/afbedsheet",
            "license.name"    : "The MIT Licence",
            "repo.private"    : "false",

            "afIoc.module"    : "afBedSheet::BedSheetModule"
        ]

        index = [
            "afIoc.module"    : "afBedSheet::BedSheetModule"
        ]

        depends = [
            "sys 1.0",
            "concurrent 1.0",
            "web 1.0",
            "webmod 1.0", // for LogMod
            "wisp 1.0",
            "util 1.0",
            "inet 1.0",

            "afIoc 1.5.2+",
            "afIocConfig 1.0.4+",
            "afIocEnv 1.0.2.1+",
            "afPlastic 1.0.10+"
        ]

        srcDirs = [`test/unit-tests/`, `test/unit-tests/public/`, `test/unit-tests/public/utils/`, `test/unit-tests/public/services/`, `test/unit-tests/internal/`, `test/unit-tests/internal/utils/`, `test/unit-tests/internal/services/`, `test/app-tests/`, `test/app/`, `fan/`, `fan/public/`, `fan/public/utils/`, `fan/public/services/`, `fan/public/responses/`, `fan/public/middleware/`, `fan/public/handlers/`, `fan/internal/`, `fan/internal/utils/`, `fan/internal/services/`, `fan/internal/proxy/`, `fan/internal/processors/`, `fan/internal/middleware/`]
        resDirs = [`doc/`, `res/web/`, `res/misc/`, `res/test/`]

        docApi = true
        docSrc = true
    }
}

Notice how the Build class extends BuildPod. It is this BuildPod that does all the heavy lifting for us, all we do is configure it. This is usually done in the ctor.

podName & summary

The podName and summary fields should be self explanatory. Note that podName can be letters only. The lack of punctuation makes namespacing a little limiting. Alien-Factory has gone with the convention of camel casing the project name and giving it an af prefix. for example, Bed Sheet becomes afBedSheet See the Global Pod Naming discussion for more detail.

version

version is optional (surprisingly!) and if omitted, defaults to the current Fantom version (currently 1.0.66). The Version object may have up to 4 segments; major, minor, build, patch, which are important when working out transitive dependencies.

meta

The above values, and other information as detailed in Pods, end up in meta.props by default. We can add more meta data to our pod (all of which is accessible via Pod.meta()) by specifying it in the meta map.

Some pod meta keys such as org.name and org.uri have been standardised (see Pods for details) while others are project dependant.

index

All the values in index end up in index.props. Index properties aren't used that much so don't worry if your pod does not define any.

depends

depends is a Str list of all the pods (and acceptable versions) that your project, um, depends on! Remember that each Str needs the pod name AND a version to be valid. See Depend for details on the syntax.

srcDirs

srcDirs tells the build where to find your fantom code. Obviously! Noteworthy points are:

  • srcDirs is a list of fantom uri literals meaning you need to surround them in back-ticks, and not double quotes or apostrophes.
  • Each directory should end with a / (See File.make() for the reason why.)
  • Nested directories are NOT included. Meaning if you have source code in both fan/ and fan/internal/ BOTH directories need to be listed.

With regards to the pod, all compiled sources end up in the focde/ directory.

If using the F4 IDE by Xored note that srcDirs is managed for you. All source folder changes in the IDE automatically update the srcDirs value.

resDirs

resDirs specify extra resource folders to include in the pod. Note that the first entry is doc/, which is how pod.metadata file ends up in the pod.

By convention, other resources are placed inside a top level res/ directory.

All syntax rules that apply to srcDirs also apply to resDirs.

docApi

Should docApi be set to true then api documentation is compiled from the source code and placed in the pod's doc/ directory.

docSrc

Should docSrc be set to true then the fantom source files from ALL the source directories are lumped together into the one pod src/.

Extra Code

Because build.fan is a script, you can run other code in the ctor should you wish! As you can see, the BedSheet build.fan strips out any test/ src and res directories.

Test code is bundled into pods by default, and in the case of Alien-Factory libraries, this amounts to quite a lot! So to reduce the size of the compiled pod, and to prevent meaningless classes appearing in IDE auto completes, they are removed before a release. These lines are normally commented out during development.



Discuss