Skip to content
FutureBlitz

    Install

    Guide

    Writing a package

    A library from fb new to a published version: its modules, its Public API, docs, tests, and fb publish.

    A package is a folder with a project.toml. A library is a package other programs use: its modules’ Public declarations are its API. This guide makes one, prices, and publishes it.

    1. Make the package

    fb new prices
    cd prices

    A library has no main file, so delete main.fb, and say what it is in project.toml, with what the registry shows of it:

    project.toml
    [project]
    name = "prices"
    version = "0.1.0"
    type = "library"
    description = "Prices with discounts and taxes, in whole cents"
    license = "MIT"
    repository = "https://github.com/ada/prices"
    keywords = ["money", "retail"]

    2. Write its modules

    Each .fb file is a module, named by the package and its path: discount.fb is prices.discount. Only what’s Public is the package’s API; the rest stays inside its file. Doc comments, /// on a declaration and //! at the top of a file, are what its users read, on hover and on the package site.

    discount.fb
    //! Discounts on a price in cents: see [Percent] and [BulkFree].
    
    Import std.core
    Import std.test
    
    /// `cents` less `percent` of it, rounded down to a whole cent.
    ///
    /// # Examples
    ///
    /// ```
    /// Expect(Percent(1000, 15) == 850)
    /// ```
    Public Function Percent(cents: Int, percent: Int): Int
        Return cents - cents * percent / 100
    End Function
    
    /// The price of `count` items at `each` cents, with one free for every `per` bought.
    Public Function BulkFree(count: Int, each: Int, per: Int): Int
        Return (count - count / per) * each
    End Function
    
    @Test
    Function BulkFreeGivesEveryTenth()
        Expect(BulkFree(9, 100, 10) == 900)
        Expect(BulkFree(10, 100, 10) == 900)
    End Function

    3. Test it

    fb test

    fb test runs the @Test Functions beside the code, the tests in the package’s tests/ folder, which see only its Public API, and the doc comments’ examples. What it prints for this package is under discount.fb above: its test, and Percent’s example.

    4. Use it from a program

    Before it’s published, a program uses it by its folder, with a path dependency. Here the program, shop, keeps the library in a folder of its own, prices/:

    project.toml
    [project]
    name = "shop"
    version = "0.1.0"
    
    [dependencies]
    prices = { path = "prices" }
    prices/project.toml
    [project]
    name = "prices"
    version = "0.1.0"
    type = "library"
    prices/discount.fb
    Import std.core
    
    /// `cents` less `percent` of it, rounded down to a whole cent.
    Public Function Percent(cents: Int, percent: Int): Int
        Return cents - cents * percent / 100
    End Function
    main.fb
    Import std.core
    Import prices
    Import prices.discount
    
    Print(Percent(2000, 10))
    Print(prices.Percent(1999, 10))
    Print(discount.Percent(500, 50))
    Output
    1800
    1800
    250

    Import prices brings in every module of the package: their Public names, as Percent, and under the package’s name, as prices.Percent. Import prices.discount brings in one module, under its last name too, as discount.Percent. From prices.discount Import Percent brings in one name alone.

    5. Publish it

    The registry needs a license file and a readme in the package’s folder: LICENSE, LICENSE.md, LICENSE.txt, or COPYING, and README.md, README, or README.txt, or the files project.toml’s license_file and readme name:

    LICENSE
    Copyright (c) the prices authors. Anyone may use, copy, and change this software.
    README.md
    # prices
    
    Prices with discounts and taxes, in whole cents.
    Output
         Running 2 tests
    test prices.discount.BulkFreeGivesEveryTenth ... ok
    test prices.discount.Percent (example) ... ok
    
    test result: ok. 2 passed; 0 failed; 0 skipped; 0 filtered out; finished in 0.02s

    Sign in once with fb login, then check what would go up, and publish:

    fb publish --dry-run
    fb publish
    Output
       Packaging prices v0.1.0 (C:/Users/ada/prices)
        Packaged prices-0.1.0.fbpkg: 4 files, 738 B
    prices-0.1.0.fbpkg  LICENSE
    prices-0.1.0.fbpkg  README.md
    prices-0.1.0.fbpkg  discount.fb
    prices-0.1.0.fbpkg  project.toml
        Finished the dry run of prices v0.1.0; nothing was published to https://index.futureblitz.dev/
       Packaging prices v0.1.0 (C:/Users/ada/prices)
        Packaged prices-0.1.0.fbpkg: 4 files, 738 B
      Publishing prices v0.1.0 to https://index.futureblitz.dev/
       Published prices v0.1.0

    --dry-run builds the archive and the docs, checks them as the registry does, and lists the files, without uploading anything. Then other programs add it with fb add prices.

    To publish the next version, change project.toml’s version, by semver: the patch number for fixes, the minor for what’s added, and the major for what breaks. To publish from CI, see Publishing from GitHub Actions.

    Report an issue with this page or with FutureBlitz on GitHub.