PkgTemplates.jl

repository·master·Indexed 20 days ago

https://github.com/juliaci/pkgtemplates.jl

A tool for creating new Julia packages in an easy, repeatable, and customizable way. It provides a structured framework for generating package boilerplate and is extensible via a plugin system (Plugin, FilePlugin, and BadgePlugin) to automate tasks such as Git setup, GitHub Actions, Codecov, and documentation generation.

Tokens
5.6K
Snippets
17
Records
30
Agent score
68%

What's inside PkgTemplates.jl

  1. How the Template and Package Creation Pipeline works

    master

    The package generation process follows a structured pipeline involving validation and multi-stage execution of plugins.

    1. Template Construction

    When a Template is constructed, the system:

    • Extracts values from keyword arguments.
    • Creates the Template object.
    • Runs validate for each plugin to catch configuration errors before generation begins.

    2. Package Generation

    Once validated, the package is generated by executing plugin hooks in a specific order based on their priority:

    1. prehook: Runs before the main generation stage (e.g., initializing a Git repository).
    2. hook: The main stage where files are typically generated or modified.
    3. posthook: Runs after the main stage (e.g., committing generated files to Git).

    Plugins can use priority to ensure they run at the correct time relative to others within the same stage.

  2. Extend PkgTemplates with Plugins

    master

    PkgTemplates is extensible via three types of plugins. You can implement a custom plugin by subtyping one of these:

    1. Plugin: The most powerful type. Provides full control over the prehook, hook, and posthook stages. Use this for complex logic like Git initialization or documentation setup.
    2. FilePlugin: A specialized plugin designed for the common task of generating a single templated file. It automates the hook stage by using source, destination, and view methods.
    3. BadgePlugin: Specifically used for managing README badges.

    To implement a full Plugin, you can use the @plugin macro to simplify struct definition and method implementation.

  3. How plugins work in PkgTemplates

    master

    Plugins are used to add functionality to Templates, automating boilerplate tasks like CI configuration, documentation setup, or license generation.

    Plugins can be:

    • Included by default: Many common plugins are included automatically.
    • Overridden: Provide a different value for the same plugin type.
    • Disabled: Use the negation operator ! on the type (e.g., !Git) within the plugins keyword to disable a default plugin.
  4. Use custom template files with Mustache syntax

    master

    Many plugins allow you to specify a custom template file via a file argument. PkgTemplates uses Mustache.jl for text templating.

    Syntax Rules:

    • Variables: Use {{{name}}} for variables.
    • Escaping: Use triple curlies {{{key}}} to disable HTML escaping (recommended for most files). Use double curlies {{key}} if you want escaping.
    • Truthiness: Values like nothing, false, or empty collections are considered 'not existing'. Use {{#key}}...{{/key}} to render content only if the key is truthy.
    • Iteration: {{#list}}...{{/list}} iterates over collections. Use {{{.}}} to refer to the current item in the list.
    • NamedTuples: When using NamedTuples in a list, you must use the syntax {{{:name}}} instead of {{{name}}}.
    • Delimiters: If you use custom delimiters like <<foo>>, use <<&foo>> to disable escaping.
  5. Run reference tests locally using Julia 1.7.2

    master

    The reference tests in PkgTemplates are designed to run on a specific Julia version (defined by REFERENCE_JULIA_VERSION in test/runtests.jl). To ensure correctness and avoid skipping these tests, you should test against Julia 1.7.2.

    You can use juliaup to install and switch to this version:

    # Install Julia 1.7.2
    juliaup add 1.7.2
    
    # Start Julia using version 1.7.2
    julia +1.7.2
  6. Save and reuse templates

    master

    To ensure consistency across multiple packages, you can save your Template configurations using several methods:

    Define a function that returns your template in your startup.jl file. This allows you to call it from anywhere without startup overhead.

    2. String Representation

    Write the string representation of the template to a .jl file and include it later.

    3. Serialization

    Use the Serialization standard library to save the template as a binary file (.bin) and deserialize it when needed. Note that this format may not be stable across Julia versions.

    # Method 1: Function approach
    function template()
        @eval begin
            using PkgTemplates
            Template(; #= ... =#)
        end
    end
    
    # Method 2: String representation
    const t = Template(; #= ... =#)
    open("template.jl", "w") do io
        println(io, "using PkgTemplates")
        print(io, t)
    end
    # Usage: const t = include("template.jl")
    
    # Method 3: Serialization
    using Serialization
    const t = Template(; #= ... =#)
    open(io -> serialize(io, t), "template.bin", "w")
    # Usage: const t = open(deserialize, "template.bin")
  7. Create a package using a Template

    master

    To create a package, first instantiate a Template object and then call it with the name of the package you wish to create.

    Note on Git Configuration: The default Template() constructor assumes you have the following Git configurations already set up on your system via git config --global:

    • user.name: Your real name.
    • user.email: Your email address.
    • github.user: Your GitHub username.
    using PkgTemplates
    tpl = Template()
    tpl("MyPkg")
  8. Migrate Documentation plugins in PkgTemplates 0.7+

    master

    The documentation plugins have been reworked to use a more explicit Documenter constructor with CI provider types. If you were using the old specialized page plugins, migrate to the new Documenter syntax:

    • GitHub Pages: Use Documenter{TravisCI} instead of GitHubPages.
    • GitLab Pages: Use Documenter{GitLabCI} instead of GitLabPages.
    # New way to configure documentation plugins
    Template(
        plugins = [
            Documenter{TravisCI}()
        ]
    )