diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 523475fe..e3dd867d 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-07-08T20:37:37","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-07-08T20:38:52","documenter_version":"1.5.0"}} \ No newline at end of file diff --git a/dev/10-full-guide/index.html b/dev/10-full-guide/index.html index 94e2a74f..20671e6e 100644 --- a/dev/10-full-guide/index.html +++ b/dev/10-full-guide/index.html @@ -1,8 +1,8 @@ -Full Guide · BestieTemplate.jl

Full guide

Welcome to full usage guide of BestieTemplate.

Before installing

Things to know

This template is an attempt to provide many best practices to package development. This can be overwhelming, so you might prefer to take it easy at first and install only the fewest amount of new things possible.

Thinking of you, the first optional question in the template is how to deal with the optional questions:

  • The "Recommended" option lets us select the best practices that we like the most. This means "yes" to most of the optional answers.
  • The "Minimum" option does not add any optional feature. Your package will still be a valid Julia package with a few things that we deem essential (such as online testing, documentation, and CITATION.CFF).

The "Minimum" option is still a step above the bare minimum for a Julia package, so you will still benefit from the template. The "Recommended" option adds many features that package maintainers might find useful in the long run, but might be too much at once. Check the Explanation page for more information.

If you decide to gradually adopt, do this:

  1. Follow the relevant application section for New or Existing.
  2. Remember to select the "Minimum" optional questions.
  3. Follow the Update section, change your answer from "Minimum" to "Recommended" or "Ask me".

Things to install

Install a plugin on your editor to use EditorConfig. This will ensure that your editor is configured with important formatting settings.

We use https://pre-commit.com to run the linters and formatters. In particular, the Julia code is formatted using JuliaFormatter.jl, so please install it globally first:

julia> # Press ]
+Full Guide · BestieTemplate.jl

Full guide

Welcome to full usage guide of BestieTemplate.

Before installing

Things to know

This template is an attempt to provide many best practices to package development. This can be overwhelming, so you might prefer to take it easy at first and install only the fewest amount of new things possible.

Thinking of you, the first optional question in the template is how to deal with the optional questions:

  • The "Recommended" option lets us select the best practices that we like the most. This means "yes" to most of the optional answers.
  • The "Minimum" option does not add any optional feature. Your package will still be a valid Julia package with a few things that we deem essential (such as online testing, documentation, and CITATION.CFF).

The "Minimum" option is still a step above the bare minimum for a Julia package, so you will still benefit from the template. The "Recommended" option adds many features that package maintainers might find useful in the long run, but might be too much at once. Check the Explanation page for more information.

If you decide to gradually adopt, do this:

  1. Follow the relevant application section for New or Existing.
  2. Remember to select the "Minimum" optional questions.
  3. Follow the Update section, change your answer from "Minimum" to "Recommended" or "Ask me".

Things to install

Install a plugin on your editor to use EditorConfig. This will ensure that your editor is configured with important formatting settings.

We recommend using https://pre-commit.com to run linters and formatters. If you select the "recommended" options later on, you will need pre-commit installed. To install pre-commit, we recommend using pipx as follows:

# Install pipx following the link
+pipx install pre-commit

In particular, the Julia code is formatted using JuliaFormatter.jl, so please install it globally first:

julia> # Press ]
 pkg> activate
-pkg> add JuliaFormatter

To install pre-commit, we recommend using pipx as follows:

# Install pipx following the link
-pipx install pre-commit

Install BestieTemplate (or copier)

To use the template, we recommend installing the package BestieTemplate.jl globally:

julia> # press ]
+pkg> add JuliaFormatter

Install BestieTemplate (or copier)

To use the template, we recommend installing the package BestieTemplate.jl globally:

julia> # press ]
 pkg> activate
 pkg> add BestieTemplate

The BestieTemplate package wraps copier and adds some lightweight checks and parameters to make your user experience better.

Alternative

Alternatively, you can use copier directly, in which case you will have the pure template generation experience. If that is the case, I will assume that you know what you are doing and won't show the full command here to avoid confusing new users.

Using the template

There are three use cases on using the template:

  1. You are using the template to start a new package.
  2. You already have a Julia project and you want to apply the template to your project.
  3. You already uses the template and you want to update to get the latest changes.

The three cases are listed below.

New package

Simply run

julia> using BestieTemplate
 julia> BestieTemplate.generate("full/path/to/YourPackage.jl")

This will create the folder at the given path and create a package named YourPackage using the latest release of the BestieTemplate. You will be prompted with many questions, some required and some with our recommended choices.

You can give more options to the generate function, including the source of the template, pre-filled data, and options passed to the underlying project generator copier. See the full docstring for BestieTemplate.generate for more information.

The resulting folder will not be a git package yet (to avoid trust issues), so you need to handle that yourself. You should see a short guide on screen, but here it is again:

cd full/path/to/YourPackage.jl
@@ -20,4 +20,4 @@
 git commit -m "Apply BestieTemplate vx.y.z"

Push your code to GitHub and head to Setting up your package for information on what to do next.

Now, go to Setting up your package to check what you still need to configure for your package.

Updating

To update the package, simply call

julia> BestieTemplate.update()

You will be asked the relevant questions of the package as if you had applied it. The big differences are:

  • It will only apply the things that are new since you last applied/updated
  • It will remember previous answer.
  • It will overwrite without asking.
Change previous answers

You can change your previous answers. In other words, if you though something was not mature enough in the past, but you are more confident in that now, you can adopt it now. This works even if the template was not updated itself.

As with the first application, you need to run pre-commit run -a to fix the unavoidable linting and formatting issues. Check the modifications in the relevant linter and formatting files, if you changed them manually, before doing it, though.

pre-commit run -a

The underlying package copier will use git to apply the differences and it will overwrite whatever files it finds in the way. Since git is mandatory, the changes will be left for you to review.

Review the changes

I repeat, the changes will be left for you to review. Don't just add them blindly, because some of your modifications can and will be overwritten.

If you need some help with undoing some of these changes, I recommend using a graphical interface.

Setting up your package

There are various steps to setting up your package on GitHub. Some are important now, and some will be relevant when you try to make your first release.

Add to GitHub

If you haven't yet, create a repo on GitHub and push your code to it.

Info

The actions will run and you will see errors in the documentation and linting. Do not despair.

Documentation

Go to your package setting on Github and find the "Actions" tab, the "General" link. On that page, find the "Workflow permissions" and change the selection to "Read and write permissions", and enable "Allow GitHub Actions can create and approve pull requests". This will allow the documentation workflow to work for development.

Go to the Actions page, click the failing Docs workflow and click on "re-run all jobs". It should pass now.

Now, go to your package setting on GitHub and find the "Pages" link. You should see an option to set the Source to "Deploy from a branch", and select the branch to be "gh-pages" and to deploy from the "/ (root)".

After circa 1 minute, you can check that the documentation was built properly.

Info

At this point, you should have passing workflows.

  1. Tests should have been passing from the start.
  2. Lint was fixed when we pushed the code to GitHub.
  3. Docs was fixed with the permissions change.

Documentation for releases

Info

This section is only relevant when making your first release, but it might be better to get it out of the way now.

You need to set a DOCUMENTER_KEY to build the documentation from the tags automatically when using TagBot (which we do by default). Do the following:

pkg> activate --temp
 pkg> add DocumenterTools
 julia> using DocumenterTools
-julia> DocumenterTools.genkeys(user="UserName", repo="PackageName.jl")

Follow the instruction in the terminal.

Enable Codecov for code coverage

If you don't have a Codecov account, go to https://codecov.io and create one now. After creating an account and logging in, you will see your main page with a list of your packages. Select the one that you are creating, it will open a configuration page.

On the configuration page, select "Using GitHub Actions" as your CI. The first step in the list given you the CODECOV_TOKEN. Click on the "repository secret" link on that page. It should lead you to the GitHub settings > secrets and variables > actions, under a "New secret" screen. Write CODECOV_TOKEN on the "Name" field and paste the token that you see on codecov on the "Secret" field. Click "Add secret".

Step 2 is not necessary because it is already present in the template.

The next time that the tests are run, the coverage page will be updated, and the badge will be fixed.

Add key for Copier.yml workflow

Copier.yml is work in progress

This option is not selected by default because it is a work in progress. If you want to use it, you have to pass the key "AddCopierCI" => true to the data argument of generate or apply, or select "Ask me" when deciding how to answer the optional questions.

You can reapply the template in the future. This is normally a manual job, specially because normally there are conflicts. That being said, we are experimenting with having a workflow that automatically checks whether there are updates to the template and reapplies it. A Pull Request is created with the result.

Warning

This is optional, and in development, so you might want to delete the workflow instead.

If you decide to use, here are the steps to set it up:

  1. Create a Personal Access Token to be used by the Copier workflow.
  2. Go to https://github.com/settings/tokens.
  3. Create a token with "Content", "Pull-request", and "Workflows" permissions.
  4. Copy the Token.
  5. Go to your YOUR_PACKAGE_URL/settings/secrets/actions.
  6. Create a "New repository secret" named COPIER_PAT.

CITATION.cff and Zenodo deposition

Update your CITATION.cff file with correct information. You can use cffinit to generate it easily.

Before releasing, enable Zenodo integration at https://zenodo.org/account/settings/github/ to automatically generate a deposition of your package, i.e., archive a version on Zenodo and generate a DOI.

Update README.md

  1. Update the badges
  2. Add a description

Enable discussions

Enable GitHub discussions.

First release

When you are ready to make your first release, enable the Julia Registrator bot. Make sure that you haven't skipped these sections:

+julia> DocumenterTools.genkeys(user="UserName", repo="PackageName.jl")

Follow the instruction in the terminal.

Enable Codecov for code coverage

If you don't have a Codecov account, go to https://codecov.io and create one now. After creating an account and logging in, you will see your main page with a list of your packages. Select the one that you are creating, it will open a configuration page.

On the configuration page, select "Using GitHub Actions" as your CI. The first step in the list given you the CODECOV_TOKEN. Click on the "repository secret" link on that page. It should lead you to the GitHub settings > secrets and variables > actions, under a "New secret" screen. Write CODECOV_TOKEN on the "Name" field and paste the token that you see on codecov on the "Secret" field. Click "Add secret".

Step 2 is not necessary because it is already present in the template.

The next time that the tests are run, the coverage page will be updated, and the badge will be fixed.

Add key for Copier.yml workflow

Copier.yml is work in progress

This option is not selected by default because it is a work in progress. If you want to use it, you have to pass the key "AddCopierCI" => true to the data argument of generate or apply, or select "Ask me" when deciding how to answer the optional questions.

You can reapply the template in the future. This is normally a manual job, specially because normally there are conflicts. That being said, we are experimenting with having a workflow that automatically checks whether there are updates to the template and reapplies it. A Pull Request is created with the result.

Warning

This is optional, and in development, so you might want to delete the workflow instead.

If you decide to use, here are the steps to set it up:

  1. Create a Personal Access Token to be used by the Copier workflow.
  2. Go to https://github.com/settings/tokens.
  3. Create a token with "Content", "Pull-request", and "Workflows" permissions.
  4. Copy the Token.
  5. Go to your YOUR_PACKAGE_URL/settings/secrets/actions.
  6. Create a "New repository secret" named COPIER_PAT.

CITATION.cff and Zenodo deposition

Update your CITATION.cff file with correct information. You can use cffinit to generate it easily.

Before releasing, enable Zenodo integration at https://zenodo.org/account/settings/github/ to automatically generate a deposition of your package, i.e., archive a version on Zenodo and generate a DOI.

Update README.md

  1. Update the badges
  2. Add a description

Enable discussions

Enable GitHub discussions.

First release

When you are ready to make your first release, enable the Julia Registrator bot. Make sure that you haven't skipped these sections:

diff --git a/dev/20-explanation/index.html b/dev/20-explanation/index.html index d219ebc0..32a2ee4d 100644 --- a/dev/20-explanation/index.html +++ b/dev/20-explanation/index.html @@ -1,2 +1,2 @@ -Explanation · BestieTemplate.jl

Explanation

In this section, we hope to explain the motivation for the package, and what is inside the template. Some things might have been obvious when creating the package and not at the moment, so feel free to create issues to ask, or suggest, clarifications.

Tip

If something is missing or not explained enough, please open an issue.

The engine, the project generator, and the template

Let me start by marking some names clearer.

  • The template is the collection of files and folders written with some placeholders. For instance, the link to a GitHub project will be something like https://github.com/{{ PackageOwner }}/{{ PackageName }}.jl.
  • The engine is the tool that converts the template into the end result, by changing the placeholders into the actual values that we want.
  • The project generator is the tool that interacts with the user to get the placeholder values and give to the engine.

Comparison with existing solutions

Julia has a very good package generator called PkgTemplates.jl, so why did we create another one?

The short answer is that we want a more streamlined development experience, a template more focused on best practices, and the ability to keep reusing the template whenever new tools and ideas are implemented.

In more details, first, see the differences in the parts of the project in the table below:

BestieTemplate.jlPkgTemplates.jl
TemplatePart of the packagePart of the package
EngineJinjaMustache
Project generatorcopier, with some wrappers in the packagePart of the package

Now, we can split this into three comparisons.

Template differences

The template differences are mostly due to opinion and contributions and it should be easy to translate files from one template to the other. We are heavily inspired by PkgTemplates.jl, as we used it for many years, but we made some changes in the hopes of improving software sustainability, package maintainability and code quality (which we just overtly simplify as best practices). As such, our current differences (as of the time of writing) are:

  • We have more best practices tools, such as pre-commit, configuration for linters and formatters for Julia, Markdown, TOML, YAML and JSON, CITATION.cff, Lint GitHub workflow, .editorconfig file, issues and pull requests templates, etc.
  • We focus on the main use cases (GitHub and GitHub actions), so we have much less options.

Engine differences

We can't say much about these, since we don't know or care in details.

Project generator differences

PkgTemplates.jl is a project generator. This means that if you want to programmatically create templates inside Julia, this is the best solution. The questions (user interface) are implemented by the package, which then translates that into the answers for the engine. Disclaimer: We haven't worked on the package, this information is based on the docs.

We use copier as project generator. It is an external Python tool, so we also include some wrappers in the package to use it from Julia without the need to explicitly install it. Copier has many features, so we recommend that you check their comparisons pages for more information.

Most notably, the feature that made us choose copier in the first place has the ability to applied and reapplied to existing projects. This means that existing packages can benefit from all best practices that we provide. Furthermore, they can keep reaping benefits when we create new versions of the template.

Template details

Let's dive into the details of the template now.

Basic package structure

This is the basic structure of a package:

  • PackageName.jl/
    • src/
      • PackageName.jl
    • test/
      • Project.toml
      • runtests.jl
    • LICENSE.md
    • Project.toml
    • README.md

With the exception of test/Project.toml, all other files are requirements to register a package.

Documentation

On top of the basic structure, we add some Documenter.jl structure.

  • docs/
    • src/
      • 90-contributing.md
      • 91-developer.md
      • 95-reference.md
      • index.md
    • make.jl
    • Project.toml

Brief explanation of the details:

  • The Project.toml, make.jl and src/index.md are the basic structure.
  • docs/src/90-contributing.md: Sometimes added as CONTRIBUTING.md, it explains how contributors can get involved in the project.
  • docs/src/91-developer.md: Sometimes added as README.dev.md or DEVELOPER.md, it explains how to setup your local environment and other information relevant for developers only.
  • docs/src/95-reference.md is the API reference page, which include an @autodocs.

One noteworthy aspect of our make.jl, is that we include some code to automatically generate the list of pages. Create a file in the form ##-name.md, where ## is a two-digit number, and it will be automatically added to the pages list.

index.md

You might have noticed that index.md is not numbered, and that is because Documenter.jl checks for that files specifically to define the landing page. Instead, we explicitly add "Home" => "index." to make.jl.

Linting and Formatting

The most important file related to linting and formatting is .pre-commit-config.yaml, which is the configuration for pre-commit. It defines a list of linters and formatters for Julia, Markdown, TOML, YAML, and JSON.

It requires installing pre-commit (I recommend installing it globally with pipx). Installing pre-commit (pre-commit install) will make sure that it runs the relevant hooks before committing. Furthermore, if you run pre-commit run -a, it runs all hooks.

Some hooks in the .pre-commit-config.yaml file have configuration files of their own: .JuliaFormatter.toml, .markdownlint.json, lychee.toml, and .yamllint.yml.

Also slightly related, is the .editorconfig file, which tells your editor, if you install the correct plugin, how to format some things.

GitHub Workflows

We have a few workflows, with plans to expand in the future:

  • CompatHelper.yml: Should be well known by now. It checks that your Project.toml compat entries are up-to-date.
  • Copier.yml: This will periodically check the template for updates. If there are updates, this action creates a pull request updating your repo.
  • Docs.yml: Build the docs. Only runs when relevant files change.
  • Lint.yml: Run the linter and formatter through the command pre-commit run -a.
  • TagBot.yml: Create GitHub releases automatically after your new release is merged on the Registry.
  • For testing, we have
    • ReusableTest.yml: Defines a reusable workflow with the testing.
    • Test.yml: Defines a matrix of tests to be run whenever main is updated or a tag is created. Uses the ReusableTest workflow. If "Simplified PR Test" was not chosen, then this also runs when there are pull requests.
    • TestOnPRs.yml: Defines a test to be run when pull requests are created. Only the latest stable Julia version is tested on a ubuntu-latest image. Uses the ReusableTest workflow. If "Simplified PR Test" was not chosen, then this file does not exist.

Issues and PR templates

We include issues and PR templates for GitHub (see .github/). These provide a starting point to your project management.

Other files

  • .cirrus.yml: For Cirrus CI, which we use solely for FreeBSD testing.
  • CITATION.cff: Instead of the more classic .bib, we use .cff, which serves a better purpose of providing the metadata of the package. CFF files have been adopted by GitHub, so you can generate a BibTeX entry by clicking on "Cite this repository" on the repository's main page. CFF files have also been adopted by Zenodo to provide the metadata of your deposition.
  • CODE_OF_CONDUCT.md: A code of conduct file from Contributor Covenant.
+Explanation · BestieTemplate.jl

Explanation

In this section, we hope to explain the motivation for the package, and what is inside the template. Some things might have been obvious when creating the package and not at the moment, so feel free to create issues to ask, or suggest, clarifications.

Tip

If something is missing or not explained enough, please open an issue.

The engine, the project generator, and the template

Let me start by marking some names clearer.

  • The template is the collection of files and folders written with some placeholders. For instance, the link to a GitHub project will be something like https://github.com/{{ PackageOwner }}/{{ PackageName }}.jl.
  • The engine is the tool that converts the template into the end result, by changing the placeholders into the actual values that we want.
  • The project generator is the tool that interacts with the user to get the placeholder values and give to the engine.

Comparison with existing solutions

Julia has a very good package generator called PkgTemplates.jl, so why did we create another one?

The short answer is that we want a more streamlined development experience, a template more focused on best practices, and the ability to keep reusing the template whenever new tools and ideas are implemented.

In more details, first, see the differences in the parts of the project in the table below:

BestieTemplate.jlPkgTemplates.jl
TemplatePart of the packagePart of the package
EngineJinjaMustache
Project generatorcopier, with some wrappers in the packagePart of the package

Now, we can split this into three comparisons.

Template differences

The template differences are mostly due to opinion and contributions and it should be easy to translate files from one template to the other. We are heavily inspired by PkgTemplates.jl, as we used it for many years, but we made some changes in the hopes of improving software sustainability, package maintainability and code quality (which we just overtly simplify as best practices). As such, our current differences (as of the time of writing) are:

  • We have more best practices tools, such as pre-commit, configuration for linters and formatters for Julia, Markdown, TOML, YAML and JSON, CITATION.cff, Lint GitHub workflow, .editorconfig file, issues and pull requests templates, etc.
  • We focus on the main use cases (GitHub and GitHub actions), so we have much less options.

Engine differences

We can't say much about these, since we don't know or care in details.

Project generator differences

PkgTemplates.jl is a project generator. This means that if you want to programmatically create templates inside Julia, this is the best solution. The questions (user interface) are implemented by the package, which then translates that into the answers for the engine. Disclaimer: We haven't worked on the package, this information is based on the docs.

We use copier as project generator. It is an external Python tool, so we also include some wrappers in the package to use it from Julia without the need to explicitly install it. Copier has many features, so we recommend that you check their comparisons pages for more information.

Most notably, the feature that made us choose copier in the first place has the ability to applied and reapplied to existing projects. This means that existing packages can benefit from all best practices that we provide. Furthermore, they can keep reaping benefits when we create new versions of the template.

Template details

Let's dive into the details of the template now.

Basic package structure

This is the basic structure of a package:

  • PackageName.jl/
    • src/
      • PackageName.jl
    • test/
      • Project.toml
      • runtests.jl
    • LICENSE.md
    • Project.toml
    • README.md

With the exception of test/Project.toml, all other files are requirements to register a package.

Documentation

On top of the basic structure, we add some Documenter.jl structure.

  • docs/
    • src/
      • 90-contributing.md
      • 91-developer.md
      • 95-reference.md
      • index.md
    • make.jl
    • Project.toml

Brief explanation of the details:

  • The Project.toml, make.jl and src/index.md are the basic structure.
  • docs/src/90-contributing.md: Sometimes added as CONTRIBUTING.md, it explains how contributors can get involved in the project.
  • docs/src/91-developer.md: Sometimes added as README.dev.md or DEVELOPER.md, it explains how to setup your local environment and other information relevant for developers only.
  • docs/src/95-reference.md is the API reference page, which include an @autodocs.

One noteworthy aspect of our make.jl, is that we include some code to automatically generate the list of pages. Create a file in the form ##-name.md, where ## is a two-digit number, and it will be automatically added to the pages list.

index.md

You might have noticed that index.md is not numbered, and that is because Documenter.jl checks for that files specifically to define the landing page. Instead, we explicitly add "Home" => "index." to make.jl.

Linting and Formatting

The most important file related to linting and formatting is .pre-commit-config.yaml, which is the configuration for pre-commit. It defines a list of linters and formatters for Julia, Markdown, TOML, YAML, and JSON.

It requires installing pre-commit (I recommend installing it globally with pipx). Installing pre-commit (pre-commit install) will make sure that it runs the relevant hooks before committing. Furthermore, if you run pre-commit run -a, it runs all hooks.

Some hooks in the .pre-commit-config.yaml file have configuration files of their own: .JuliaFormatter.toml, .markdownlint.json, lychee.toml, and .yamllint.yml.

Also slightly related, is the .editorconfig file, which tells your editor, if you install the correct plugin, how to format some things.

GitHub Workflows

We have a few workflows, with plans to expand in the future:

  • CompatHelper.yml: Should be well known by now. It checks that your Project.toml compat entries are up-to-date.
  • Copier.yml: This will periodically check the template for updates. If there are updates, this action creates a pull request updating your repo.
  • Docs.yml: Build the docs. Only runs when relevant files change.
  • Lint.yml: Run the linter and formatter through the command pre-commit run -a.
  • TagBot.yml: Create GitHub releases automatically after your new release is merged on the Registry.
  • For testing, we have
    • ReusableTest.yml: Defines a reusable workflow with the testing.
    • Test.yml: Defines a matrix of tests to be run whenever main is updated or a tag is created. Uses the ReusableTest workflow. If "Simplified PR Test" was not chosen, then this also runs when there are pull requests.
    • TestOnPRs.yml: Defines a test to be run when pull requests are created. Only the latest stable Julia version is tested on a ubuntu-latest image. Uses the ReusableTest workflow. If "Simplified PR Test" was not chosen, then this file does not exist.

Issues and PR templates

We include issues and PR templates for GitHub (see .github/). These provide a starting point to your project management.

Other files

  • .cirrus.yml: For Cirrus CI, which we use solely for FreeBSD testing.
  • CITATION.cff: Instead of the more classic .bib, we use .cff, which serves a better purpose of providing the metadata of the package. CFF files have been adopted by GitHub, so you can generate a BibTeX entry by clicking on "Cite this repository" on the repository's main page. CFF files have also been adopted by Zenodo to provide the metadata of your deposition.
  • CODE_OF_CONDUCT.md: A code of conduct file from Contributor Covenant.
diff --git a/dev/90-contributing/index.html b/dev/90-contributing/index.html index 7f97c84e..eb1d7d55 100644 --- a/dev/90-contributing/index.html +++ b/dev/90-contributing/index.html @@ -1,2 +1,2 @@ -Contributing · BestieTemplate.jl

Contributing guidelines

First of all, thanks for the interest!

We welcome all kinds of contribution, including, but not limited to code, documentation, examples, configuration, issue creating, etc.

Be polite and respectful, and follow the code of conduct.

Bug reports and discussions

If you think you found a bug, feel free to open an issue. Focused suggestions and requests can also be opened as issues. Before opening a pull request, start an issue or a discussion on the topic, please.

Working on an issue

If you found an issue that interests you, comment on that issue what your plans are. If the solution to the issue is clear, you can immediately create a pull request (see below). Otherwise, say what your proposed solution is and wait for a discussion around it.

Tip

Feel free to ping us after a few days if there are no responses.

If your solution involves code (or something that requires running the package locally), check the developer documentation. Otherwise, you can use the GitHub interface directly to create your pull request.

Additions and modifications to the template

If you have any new idea or think the template needs to be updated or fixed, please search our issues and if there isn't anything relevant, open a new issue.

+Contributing · BestieTemplate.jl

Contributing guidelines

First of all, thanks for the interest!

We welcome all kinds of contribution, including, but not limited to code, documentation, examples, configuration, issue creating, etc.

Be polite and respectful, and follow the code of conduct.

Bug reports and discussions

If you think you found a bug, feel free to open an issue. Focused suggestions and requests can also be opened as issues. Before opening a pull request, start an issue or a discussion on the topic, please.

Working on an issue

If you found an issue that interests you, comment on that issue what your plans are. If the solution to the issue is clear, you can immediately create a pull request (see below). Otherwise, say what your proposed solution is and wait for a discussion around it.

Tip

Feel free to ping us after a few days if there are no responses.

If your solution involves code (or something that requires running the package locally), check the developer documentation. Otherwise, you can use the GitHub interface directly to create your pull request.

Additions and modifications to the template

If you have any new idea or think the template needs to be updated or fixed, please search our issues and if there isn't anything relevant, open a new issue.

diff --git a/dev/91-developer/index.html b/dev/91-developer/index.html index 09ddb66d..eeb32c52 100644 --- a/dev/91-developer/index.html +++ b/dev/91-developer/index.html @@ -19,4 +19,4 @@ - Alice {% if AddBob %}- Bob{% endif} - Carlos -- Diana

Dependent files and directories

To make a file depend on a variable, you can change the name of the file to include the conditional and the .jinja extension.

{% if AddSomeFile %}some-file.txt{% endif %}.jinja

If AddSomeFile, then some-file.txt will exist.

For directories, you do the same, except that you don't add the .jinja extension.

{% if AddGitHubTemplates %}ISSUE_TEMPLATE{% endif %}

Using answers

To use the answers of a question outside of a conditional, you can use {{ SomeValue }}. This will translate to the value of SomeValue as answered by the user. For instance

whoami() = "Hi, I'm package {{ PackageName }}.jl"

This also works on file names and in the copier.yml file.

Raw tag and avoiding clashes in GitHub workflow files

Since the GitHub workflow also uses { and } for their commands, we want to enclose them using the {% raw %}...{% endraw %} tag:

os: {% raw %}%{{ matrix.os }}{% endraw %}
+- Diana

Dependent files and directories

To make a file depend on a variable, you can change the name of the file to include the conditional and the .jinja extension.

{% if AddSomeFile %}some-file.txt{% endif %}.jinja

If AddSomeFile, then some-file.txt will exist.

For directories, you do the same, except that you don't add the .jinja extension.

{% if AddGitHubTemplates %}ISSUE_TEMPLATE{% endif %}

Using answers

To use the answers of a question outside of a conditional, you can use {{ SomeValue }}. This will translate to the value of SomeValue as answered by the user. For instance

whoami() = "Hi, I'm package {{ PackageName }}.jl"

This also works on file names and in the copier.yml file.

Raw tag and avoiding clashes in GitHub workflow files

Since the GitHub workflow also uses { and } for their commands, we want to enclose them using the {% raw %}...{% endraw %} tag:

os: {% raw %}%{{ matrix.os }}{% endraw %}
diff --git a/dev/95-reference/index.html b/dev/95-reference/index.html index 9b049b0d..4e17ac9d 100644 --- a/dev/95-reference/index.html +++ b/dev/95-reference/index.html @@ -1,6 +1,6 @@ -Reference · BestieTemplate.jl

Reference

Contents

Index

BestieTemplate._copyMethod
_copy(src_path, dst_path, data; kwargs...)

Internal function to run common code for new or existing packages.

source
BestieTemplate._sanitize_package_nameMethod
package_name = _sanitize_package_name(path)

Sanitize the path to guess the package_name by looking at the base name and removing an extension. If the result is not a valid identifier, returns "".

source
BestieTemplate.applyFunction
apply(dst_path[, data]; kwargs...)
-apply(src_path, dst_path[, data]; true, kwargs...)

Applies the template to an existing project at path $dst_path$. If the dst_path does not exist, this will throw an error. For new packages, use BestieTemplate.generate instead.

Runs the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.

The data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.

Keyword arguments

  • warn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run apply and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.

The other keyword arguments are passed directly to the internal Copier.copy.

source
BestieTemplate.generateFunction
generate(dst_path[, data]; kwargs...)
-generate(src_path, dst_path[, data]; true, kwargs...)

Generates a new project at the path dst_path using the template. If the dst_path already exists, this will throw an error, unless dst_path = ".". For existing packages, use BestieTemplate.apply instead.

Runs the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.

The data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.

Keyword arguments

  • warn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run generate and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.

The other keyword arguments are passed directly to the internal Copier.copy.

source
BestieTemplate.updateFunction
update([data]; kwargs...)
-update(dst_path[, data]; kwargs...)

Run the update command of copier, updating the dst_path (or the current path if omitted) with a new version of the template with a new version of the template.

The data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.

Keyword arguments

The keyword arguments are passed directly to the internal Copier.update.

source
Base.copyFunction
copy(dst_path[, data]; kwargs...)
-copy(src_path, dst_path[, data]; kwargs...)

Wrapper around copier.run_copy.

This is an internal function, if BestieTemplate's main API is not sufficient, open an issue.

source
+Reference · BestieTemplate.jl

Reference

Contents

Index

BestieTemplate._copyMethod
_copy(src_path, dst_path, data; kwargs...)

Internal function to run common code for new or existing packages.

source
BestieTemplate._sanitize_package_nameMethod
package_name = _sanitize_package_name(path)

Sanitize the path to guess the package_name by looking at the base name and removing an extension. If the result is not a valid identifier, returns "".

source
BestieTemplate.applyFunction
apply(dst_path[, data]; kwargs...)
+apply(src_path, dst_path[, data]; true, kwargs...)

Applies the template to an existing project at path $dst_path$. If the dst_path does not exist, this will throw an error. For new packages, use BestieTemplate.generate instead.

Runs the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.

The data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.

Keyword arguments

  • warn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run apply and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.

The other keyword arguments are passed directly to the internal Copier.copy.

source
BestieTemplate.generateFunction
generate(dst_path[, data]; kwargs...)
+generate(src_path, dst_path[, data]; true, kwargs...)

Generates a new project at the path dst_path using the template. If the dst_path already exists, this will throw an error, unless dst_path = ".". For existing packages, use BestieTemplate.apply instead.

Runs the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.

The data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.

Keyword arguments

  • warn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run generate and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.

The other keyword arguments are passed directly to the internal Copier.copy.

source
BestieTemplate.updateFunction
update([data]; kwargs...)
+update(dst_path[, data]; kwargs...)

Run the update command of copier, updating the dst_path (or the current path if omitted) with a new version of the template with a new version of the template.

The data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.

Keyword arguments

The keyword arguments are passed directly to the internal Copier.update.

source
Base.copyFunction
copy(dst_path[, data]; kwargs...)
+copy(src_path, dst_path[, data]; kwargs...)

Wrapper around copier.run_copy.

This is an internal function, if BestieTemplate's main API is not sufficient, open an issue.

source
diff --git a/dev/index.html b/dev/index.html index 28ac217a..604c47e5 100644 --- a/dev/index.html +++ b/dev/index.html @@ -31,4 +31,4 @@ - + diff --git a/dev/search_index.js b/dev/search_index.js index 56d9a78a..b704d533 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"20-explanation/#explanation","page":"Explanation","title":"Explanation","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"In this section, we hope to explain the motivation for the package, and what is inside the template. Some things might have been obvious when creating the package and not at the moment, so feel free to create issues to ask, or suggest, clarifications.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"tip: Tip\nIf something is missing or not explained enough, please open an issue.","category":"page"},{"location":"20-explanation/#The-engine,-the-project-generator,-and-the-template","page":"Explanation","title":"The engine, the project generator, and the template","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Let me start by marking some names clearer.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The template is the collection of files and folders written with some placeholders. For instance, the link to a GitHub project will be something like https://github.com/{{ PackageOwner }}/{{ PackageName }}.jl.\nThe engine is the tool that converts the template into the end result, by changing the placeholders into the actual values that we want.\nThe project generator is the tool that interacts with the user to get the placeholder values and give to the engine.","category":"page"},{"location":"20-explanation/#Comparison-with-existing-solutions","page":"Explanation","title":"Comparison with existing solutions","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Julia has a very good package generator called PkgTemplates.jl, so why did we create another one?","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The short answer is that we want a more streamlined development experience, a template more focused on best practices, and the ability to keep reusing the template whenever new tools and ideas are implemented.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"In more details, first, see the differences in the parts of the project in the table below:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":" BestieTemplate.jl PkgTemplates.jl\nTemplate Part of the package Part of the package\nEngine Jinja Mustache\nProject generator copier, with some wrappers in the package Part of the package","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Now, we can split this into three comparisons.","category":"page"},{"location":"20-explanation/#Template-differences","page":"Explanation","title":"Template differences","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The template differences are mostly due to opinion and contributions and it should be easy to translate files from one template to the other. We are heavily inspired by PkgTemplates.jl, as we used it for many years, but we made some changes in the hopes of improving software sustainability, package maintainability and code quality (which we just overtly simplify as best practices). As such, our current differences (as of the time of writing) are:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We have more best practices tools, such as pre-commit, configuration for linters and formatters for Julia, Markdown, TOML, YAML and JSON, CITATION.cff, Lint GitHub workflow, .editorconfig file, issues and pull requests templates, etc.\nWe focus on the main use cases (GitHub and GitHub actions), so we have much less options.","category":"page"},{"location":"20-explanation/#Engine-differences","page":"Explanation","title":"Engine differences","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We can't say much about these, since we don't know or care in details.","category":"page"},{"location":"20-explanation/#Project-generator-differences","page":"Explanation","title":"Project generator differences","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"PkgTemplates.jl is a project generator. This means that if you want to programmatically create templates inside Julia, this is the best solution. The questions (user interface) are implemented by the package, which then translates that into the answers for the engine. Disclaimer: We haven't worked on the package, this information is based on the docs.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We use copier as project generator. It is an external Python tool, so we also include some wrappers in the package to use it from Julia without the need to explicitly install it. Copier has many features, so we recommend that you check their comparisons pages for more information.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Most notably, the feature that made us choose copier in the first place has the ability to applied and reapplied to existing projects. This means that existing packages can benefit from all best practices that we provide. Furthermore, they can keep reaping benefits when we create new versions of the template.","category":"page"},{"location":"20-explanation/#Template-details","page":"Explanation","title":"Template details","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Let's dive into the details of the template now.","category":"page"},{"location":"20-explanation/#Basic-package-structure","page":"Explanation","title":"Basic package structure","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"This is the basic structure of a package:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"PackageName.jl/\nsrc/\nPackageName.jl\ntest/\nProject.toml\nruntests.jl\nLICENSE.md\nProject.toml\nREADME.md","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"With the exception of test/Project.toml, all other files are requirements to register a package.","category":"page"},{"location":"20-explanation/#Documentation","page":"Explanation","title":"Documentation","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"On top of the basic structure, we add some Documenter.jl structure.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"docs/\nsrc/\n90-contributing.md\n91-developer.md\n95-reference.md\nindex.md\nmake.jl\nProject.toml","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Brief explanation of the details:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The Project.toml, make.jl and src/index.md are the basic structure.\ndocs/src/90-contributing.md: Sometimes added as CONTRIBUTING.md, it explains how contributors can get involved in the project.\ndocs/src/91-developer.md: Sometimes added as README.dev.md or DEVELOPER.md, it explains how to setup your local environment and other information relevant for developers only.\ndocs/src/95-reference.md is the API reference page, which include an @autodocs.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"One noteworthy aspect of our make.jl, is that we include some code to automatically generate the list of pages. Create a file in the form ##-name.md, where ## is a two-digit number, and it will be automatically added to the pages list.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"info: index.md\nYou might have noticed that index.md is not numbered, and that is because Documenter.jl checks for that files specifically to define the landing page. Instead, we explicitly add \"Home\" => \"index.\" to make.jl.","category":"page"},{"location":"20-explanation/#Linting-and-Formatting","page":"Explanation","title":"Linting and Formatting","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The most important file related to linting and formatting is .pre-commit-config.yaml, which is the configuration for pre-commit. It defines a list of linters and formatters for Julia, Markdown, TOML, YAML, and JSON.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"It requires installing pre-commit (I recommend installing it globally with pipx). Installing pre-commit (pre-commit install) will make sure that it runs the relevant hooks before committing. Furthermore, if you run pre-commit run -a, it runs all hooks.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Some hooks in the .pre-commit-config.yaml file have configuration files of their own: .JuliaFormatter.toml, .markdownlint.json, lychee.toml, and .yamllint.yml.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Also slightly related, is the .editorconfig file, which tells your editor, if you install the correct plugin, how to format some things.","category":"page"},{"location":"20-explanation/#GitHub-Workflows","page":"Explanation","title":"GitHub Workflows","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We have a few workflows, with plans to expand in the future:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"CompatHelper.yml: Should be well known by now. It checks that your Project.toml compat entries are up-to-date.\nCopier.yml: This will periodically check the template for updates. If there are updates, this action creates a pull request updating your repo.\nDocs.yml: Build the docs. Only runs when relevant files change.\nLint.yml: Run the linter and formatter through the command pre-commit run -a.\nTagBot.yml: Create GitHub releases automatically after your new release is merged on the Registry.\nFor testing, we have\nReusableTest.yml: Defines a reusable workflow with the testing.\nTest.yml: Defines a matrix of tests to be run whenever main is updated or a tag is created. Uses the ReusableTest workflow. If \"Simplified PR Test\" was not chosen, then this also runs when there are pull requests.\nTestOnPRs.yml: Defines a test to be run when pull requests are created. Only the latest stable Julia version is tested on a ubuntu-latest image. Uses the ReusableTest workflow. If \"Simplified PR Test\" was not chosen, then this file does not exist.","category":"page"},{"location":"20-explanation/#Issues-and-PR-templates","page":"Explanation","title":"Issues and PR templates","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We include issues and PR templates for GitHub (see .github/). These provide a starting point to your project management.","category":"page"},{"location":"20-explanation/#Other-files","page":"Explanation","title":"Other files","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":".cirrus.yml: For Cirrus CI, which we use solely for FreeBSD testing.\nCITATION.cff: Instead of the more classic .bib, we use .cff, which serves a better purpose of providing the metadata of the package. CFF files have been adopted by GitHub, so you can generate a BibTeX entry by clicking on \"Cite this repository\" on the repository's main page. CFF files have also been adopted by Zenodo to provide the metadata of your deposition.\nCODE_OF_CONDUCT.md: A code of conduct file from Contributor Covenant.","category":"page"},{"location":"91-developer/#dev_docs","page":"Developer docs","title":"Developer documentation","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"note: Contributing guidelines\nIf you haven't, please read the Contributing guidelines first.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If you want to make contributions to this package that involves code, then this guide is for you.","category":"page"},{"location":"91-developer/#First-time-clone","page":"Developer docs","title":"First time clone","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"tip: If you have writing rights\nIf you have writing rights, you don't have to fork. Instead, simply clone and skip ahead. Whenever upstream is mentioned, use origin instead.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If this is the first time you work with this repository, follow the instructions below to clone the repository.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Fork this repo\nClone your repo (this will create a git remote called origin)\nAdd this repo as a remote:\ngit remote add upstream https://github.com/abelsiqueira/BestieTemplate.jl","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"This will ensure that you have two remotes in your git: origin and upstream. You will create branches and push to origin, and you will fetch and update your local main branch from upstream.","category":"page"},{"location":"91-developer/#Linting-and-formatting","page":"Developer docs","title":"Linting and formatting","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Install a plugin on your editor to use EditorConfig. This will ensure that your editor is configured with important formatting settings.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"We use https://pre-commit.com to run the linters and formatters. In particular, the Julia code is formatted using JuliaFormatter.jl, so please install it globally first:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"julia> # Press ]\npkg> activate\npkg> add JuliaFormatter","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To install pre-commit, we recommend using pipx as follows:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"# Install pipx following the link\npipx install pre-commit","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"With pre-commit installed, activate it as a pre-commit hook:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"pre-commit install","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To run the linting and formatting manually, enter the command below:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"pre-commit run -a","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Now, you can only commit if all the pre-commit tests pass.","category":"page"},{"location":"91-developer/#Testing","page":"Developer docs","title":"Testing","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"As with most Julia packages, you can just open Julia in the repository folder, activate the environment, and run test:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"julia> # press ]\npkg> activate .\npkg> test","category":"page"},{"location":"91-developer/#Testing-local-changes-to-the-template","page":"Developer docs","title":"Testing local changes to the template","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"I recommend installing copier, although it is possible to test the template using only Julia, it becomes more complicated, and cumbersome. Using pipx (as above), you can just run","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"pipx install copier","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To test your local modifications, you can run copier with the --vcs-ref HEAD flag and point to your local clone. This will use the latest changes, including uncommitted modifications (i.e., the dirty state). What I normally do is this:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"cd $(mktemp -d) # Go to a tmp folder\ncopier copy --vcs-ref HEAD /path/to/clone/ pkg # Clone dirty clone into pkg","category":"page"},{"location":"91-developer/#Working-on-a-new-issue","page":"Developer docs","title":"Working on a new issue","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"We try to keep a linear history in this repo, so it is important to keep your branches up-to-date.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Fetch from the remote and fast-forward your local main\ngit fetch upstream\ngit switch main\ngit merge --ff-only upstream/main\nBranch from main to address the issue (see below for naming)\ngit switch -c 42-add-answer-universe\nPush the new local branch to your personal remote repository\ngit push -u origin 42-add-answer-universe\nCreate a pull request to merge your remote branch into the org main.","category":"page"},{"location":"91-developer/#Branch-naming","page":"Developer docs","title":"Branch naming","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If there is an associated issue, add the issue number.\nIf there is no associated issue, and the changes are small, add a prefix such as \"typo\", \"hotfix\", \"small-refactor\", according to the type of update.\nIf the changes are not small and there is no associated issue, then create the issue first, so we can properly discuss the changes.\nUse dash separated imperative wording related to the issue (e.g., 14-add-tests, 15-fix-model, 16-remove-obsolete-files).","category":"page"},{"location":"91-developer/#Commit-message","page":"Developer docs","title":"Commit message","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Use imperative or present tense, for instance: Add feature or Fix bug.\nHave informative titles.\nWhen necessary, add a body with details.\nIf there are breaking changes, add the information to the commit message.","category":"page"},{"location":"91-developer/#Before-creating-a-pull-request","page":"Developer docs","title":"Before creating a pull request","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"tip: Atomic git commits\nTry to create \"atomic git commits\" (recommended reading: The Utopic Git History).","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Make sure the tests pass.\nMake sure the pre-commit tests pass.\nFetch any main updates from upstream and rebase your branch, if necessary:\ngit fetch upstream\ngit rebase upstream/main BRANCH_NAME\nThen you can open a pull request and work with the reviewer to address any issues.","category":"page"},{"location":"91-developer/#Building-and-viewing-the-documentation-locally","page":"Developer docs","title":"Building and viewing the documentation locally","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Following the latest suggestions, we recommend using LiveServer to build the documentation. Here is how you do it:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Run julia --project=docs to open Julia in the environment of the docs.\nIf this is the first time building the docs\nPress ] to enter pkg mode\nRun pkg> dev . to use the development version of your package\nPress backspace to leave pkg mode\nRun julia> using LiveServer\nRun julia> servedocs()","category":"page"},{"location":"91-developer/#Making-a-new-release","page":"Developer docs","title":"Making a new release","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To create a new release, you can follow these simple steps:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Create a branch release-x.y.z\nUpdate version in Project.toml\nUpdate the CHANGELOG.md:\nRename the section \"Unreleased\" to \"[x.y.z] - yyyy-mm-dd\" (i.e., version under brackets, dash, and date in ISO format)\nAdd a new section on top of it named \"Unreleased\"\nAdd a new link in the bottom for version \"x.y.z\"\nChange the \"[unreleased]\" link to use the latest version - end of line, vx.y.z ... HEAD.\nCreate a commit \"Release vx.y.z\", push, create a PR, wait for it to pass, merge the PR.\nGo back to main screen and click on the latest commit (link: https://github.com/abelsiqueira/BestieTemplate.jl/commit/main)\nAt the bottom, write @JuliaRegistrator register","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"After that, you only need to wait and verify:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Wait for the bot to comment (should take < 1m) with a link to a RP to the registry\nFollow the link and wait for a comment on the auto-merge\nThe comment should said all is well and auto-merge should occur shortly\nAfter the merge happens, TagBot will trigger and create a new GitHub tag. Check on https://github.com/abelsiqueira/BestieTemplate.jl/releases\nAfter the release is create, a \"docs\" GitHub action will start for the tag.\nAfter it passes, a deploy action will run.\nAfter that runs, the stable docs should be updated. Check them and look for the version number.","category":"page"},{"location":"91-developer/#Additions-to-the-templates","page":"Developer docs","title":"Additions to the templates","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"info: Suggestions are not here\nThis section is aimed at the developer working on a new question, if you have any new idea or think the template needs to be updated or fixed, please search our issues and if there isn't anything relevant, open a new issue.","category":"page"},{"location":"91-developer/#Creating-a-new-question","page":"Developer docs","title":"Creating a new question","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To create a new question, you have to open the file copier.yml in the root. Find an appropriate place to add the question. Comments help identify the optional sections in the file.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Follow the other questions style and syntax. The gist of it is that you need:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"A CamelCase name.\nwhen: \"{{ AnswerStrategy == 'ask' }}\" if the question is optional.\nA type.\nA help: Short description or title (Longer description and details).\nA default, if the question is optional.\nTo default to true if \"Recommended\" or false for \"Minimum\", use {{ AnswerStrategy != 'minimum' }}.","category":"page"},{"location":"91-developer/#Dependent-sections-in-a-file","page":"Developer docs","title":"Dependent sections in a file","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To create a section in a file that depends on a variable, first add .jinja to the end of the file name and use something like","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"{% if AddSomeStuff %}\n...\n{% endif %}","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"AddSomeStuff is assumed to be boolean here, but you can use other conditions, such as {% if PackageName == 'Pkg' %}.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Notice that the empty spaces are included as well, so in some situation you might need to make it less readable. For instance, the code below will correctly parse into a list of three elements if AddBob is false.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"# Good\n\n- Alice{% if AddBob %}\n- Bob{% endif}\n- Carlos\n- Diana","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"While the code below will parse into two lists of one and two elements, respectively:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"# Bad\n- Alice\n{% if AddBob %}- Bob{% endif}\n- Carlos\n- Diana","category":"page"},{"location":"91-developer/#Dependent-files-and-directories","page":"Developer docs","title":"Dependent files and directories","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To make a file depend on a variable, you can change the name of the file to include the conditional and the .jinja extension.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"{% if AddSomeFile %}some-file.txt{% endif %}.jinja","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If AddSomeFile, then some-file.txt will exist.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"For directories, you do the same, except that you don't add the .jinja extension.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"{% if AddGitHubTemplates %}ISSUE_TEMPLATE{% endif %}","category":"page"},{"location":"91-developer/#Using-answers","page":"Developer docs","title":"Using answers","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To use the answers of a question outside of a conditional, you can use {{ SomeValue }}. This will translate to the value of SomeValue as answered by the user. For instance","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"whoami() = \"Hi, I'm package {{ PackageName }}.jl\"","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"This also works on file names and in the copier.yml file.","category":"page"},{"location":"91-developer/#Raw-tag-and-avoiding-clashes-in-GitHub-workflow-files","page":"Developer docs","title":"Raw tag and avoiding clashes in GitHub workflow files","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Since the GitHub workflow also uses { and } for their commands, we want to enclose them using the {% raw %}...{% endraw %} tag:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"os: {% raw %}%{{ matrix.os }}{% endraw %}","category":"page"},{"location":"95-reference/#reference","page":"Reference","title":"Reference","text":"","category":"section"},{"location":"95-reference/#Contents","page":"Reference","title":"Contents","text":"","category":"section"},{"location":"95-reference/","page":"Reference","title":"Reference","text":"Pages = [\"95-reference.md\"]","category":"page"},{"location":"95-reference/#Index","page":"Reference","title":"Index","text":"","category":"section"},{"location":"95-reference/","page":"Reference","title":"Reference","text":"Pages = [\"95-reference.md\"]","category":"page"},{"location":"95-reference/","page":"Reference","title":"Reference","text":"Modules = [BestieTemplate, BestieTemplate.Copier]","category":"page"},{"location":"95-reference/#BestieTemplate.BestieTemplate","page":"Reference","title":"BestieTemplate.BestieTemplate","text":"BestieTemplate.jl\n\nThis package defines a copier template for Julia packages and a basic user interface aroud copier to use it from Julia.\n\nThe main functions are: generate, apply, and update.\n\n\n\n\n\n","category":"module"},{"location":"95-reference/#BestieTemplate._copy-Tuple{Any, Any, Any}","page":"Reference","title":"BestieTemplate._copy","text":"_copy(src_path, dst_path, data; kwargs...)\n\nInternal function to run common code for new or existing packages.\n\n\n\n\n\n","category":"method"},{"location":"95-reference/#BestieTemplate._read_data_from_existing_path-Tuple{Any}","page":"Reference","title":"BestieTemplate._read_data_from_existing_path","text":"data = _read_data_from_existing_path(dst_path)\n\nReads the destination folder to figure out some answers.\n\n\n\n\n\n","category":"method"},{"location":"95-reference/#BestieTemplate._sanitize_package_name-Tuple{Any}","page":"Reference","title":"BestieTemplate._sanitize_package_name","text":"package_name = _sanitize_package_name(path)\n\nSanitize the path to guess the package_name by looking at the base name and removing an extension. If the result is not a valid identifier, returns \"\".\n\n\n\n\n\n","category":"method"},{"location":"95-reference/#BestieTemplate.apply","page":"Reference","title":"BestieTemplate.apply","text":"apply(dst_path[, data]; kwargs...)\napply(src_path, dst_path[, data]; true, kwargs...)\n\nApplies the template to an existing project at path dst_path. If the dst_path does not exist, this will throw an error. For new packages, use BestieTemplate.generate instead.\n\nRuns the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.\n\nThe data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.\n\nKeyword arguments\n\nwarn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run apply and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.\n\nThe other keyword arguments are passed directly to the internal Copier.copy.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.generate","page":"Reference","title":"BestieTemplate.generate","text":"generate(dst_path[, data]; kwargs...)\ngenerate(src_path, dst_path[, data]; true, kwargs...)\n\nGenerates a new project at the path dst_path using the template. If the dst_path already exists, this will throw an error, unless dst_path = \".\". For existing packages, use BestieTemplate.apply instead.\n\nRuns the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.\n\nThe data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.\n\nKeyword arguments\n\nwarn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run generate and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.\n\nThe other keyword arguments are passed directly to the internal Copier.copy.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.update","page":"Reference","title":"BestieTemplate.update","text":"update([data]; kwargs...)\nupdate(dst_path[, data]; kwargs...)\n\nRun the update command of copier, updating the dst_path (or the current path if omitted) with a new version of the template with a new version of the template.\n\nThe data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.\n\nKeyword arguments\n\nThe keyword arguments are passed directly to the internal Copier.update.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.Copier","page":"Reference","title":"BestieTemplate.Copier","text":"Wrapper around copier.\n\nThere are three functions in this module:\n\ncopy\nrecopy\nupdate\n\n\n\n\n\n","category":"module"},{"location":"95-reference/#Base.copy","page":"Reference","title":"Base.copy","text":"copy(dst_path[, data]; kwargs...)\ncopy(src_path, dst_path[, data]; kwargs...)\n\nWrapper around copier.run_copy.\n\nThis is an internal function, if BestieTemplate's main API is not sufficient, open an issue.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.Copier.recopy","page":"Reference","title":"BestieTemplate.Copier.recopy","text":"recopy(dst_path[, data]; kwargs...)\n\nWrapper around copier.run_recopy.\n\nThis is an internal function, if BestieTemplate's main API is not sufficient, open an issue.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.Copier.update","page":"Reference","title":"BestieTemplate.Copier.update","text":"update(dst_path[, data]; kwargs...)\n\nWrapper around copier.run_update.\n\nThis is an internal function, if BestieTemplate's main API is not sufficient, open an issue.\n\n\n\n\n\n","category":"function"},{"location":"90-contributing/#contributing","page":"Contributing","title":"Contributing guidelines","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"First of all, thanks for the interest!","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"We welcome all kinds of contribution, including, but not limited to code, documentation, examples, configuration, issue creating, etc.","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"Be polite and respectful, and follow the code of conduct.","category":"page"},{"location":"90-contributing/#Bug-reports-and-discussions","page":"Contributing","title":"Bug reports and discussions","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If you think you found a bug, feel free to open an issue. Focused suggestions and requests can also be opened as issues. Before opening a pull request, start an issue or a discussion on the topic, please.","category":"page"},{"location":"90-contributing/#Working-on-an-issue","page":"Contributing","title":"Working on an issue","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If you found an issue that interests you, comment on that issue what your plans are. If the solution to the issue is clear, you can immediately create a pull request (see below). Otherwise, say what your proposed solution is and wait for a discussion around it.","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"tip: Tip\nFeel free to ping us after a few days if there are no responses.","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If your solution involves code (or something that requires running the package locally), check the developer documentation. Otherwise, you can use the GitHub interface directly to create your pull request.","category":"page"},{"location":"90-contributing/#Additions-and-modifications-to-the-template","page":"Contributing","title":"Additions and modifications to the template","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If you have any new idea or think the template needs to be updated or fixed, please search our issues and if there isn't anything relevant, open a new issue.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = BestieTemplate","category":"page"},{"location":"#BestieTemplate-Your-best-practices-friend","page":"Home","title":"BestieTemplate - Your best practices friend","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"(Image: BestieTemplate.jl)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Welcome to the documentation of BestieTemplate.jl. This package provides a template in the copier engine for a Julia package. Furthermore, it provides a wrapper around convenience calls to that package.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main features of this package/template are:","category":"page"},{"location":"","page":"Home","title":"Home","text":"It provides a curated (opinionated) list of tools and best practices for Julia package development;\nIt can be applied and reapplied to existing packages, allowing the updates in the template to be imported into the package;","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: asciicast)","category":"page"},{"location":"#Using","page":"Home","title":"Using","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To fully benefit from the template, there are some steps to be done before and after you generate your package. Check the full guide for more details.","category":"page"},{"location":"","page":"Home","title":"Home","text":"However, if you kinda know what you need to do, this is the TL;DR:","category":"page"},{"location":"","page":"Home","title":"Home","text":"using> # press ]\npkg> add BestieTemplate\njulia> using BestieTemplate\njulia> BestieTemplate.generate(\"path/to/YourNewPackage.jl\")\njulia> # or BestieTemplate.apply(\"path/to/YourExistingPackage.jl\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"I really recommend checking the full guide, though.","category":"page"},{"location":"","page":"Home","title":"Home","text":"To understand more about our motivation and what the template provides, check the explanation page.","category":"page"},{"location":"#Getting-and-providing-help","page":"Home","title":"Getting and providing help","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"I hope you find this package useful. If you have any questions, requests, or comments, check the issues and discussion pages.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you would like to get involved in the BestieTemplate growth, please check our contributing guide. We welcome contributions of many types, including coding, reviewing, creating issues, creating tutorials, interacting with users, etc. Make sure to follow our code of conduct.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If your interest is in developing the package, check the development guide as well.","category":"page"},{"location":"#References","page":"Home","title":"References","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Here is a list of links/repos that include content that we have used for inspiration, or used directly. This is most likely not a complete list, since many of the things included here were based on existing packages and knowledge that we brought from other projects. This also doesn't explain where each file came from or why they are here. You can find some of that information in the Explanation section of the docs.","category":"page"},{"location":"","page":"Home","title":"Home","text":"PkgTemplates.jl, naturally. We used it for many years, and in particular for the initial TulipaEnergyModel.jl commit (see below).\nNetherlands eScience Center's python template includes many of the best practices that we apply here. We used many of the ideas there in a Julia context, and took many non-Julia specific ideas from there.\nTulipaEnergyModel.jl was the project that motivated this version of a template. From the start we decide to implement many best practices and so we started from a PkgTemplates.jl template and started adding parts of the python template that made sense.\nThe Julia Smooth Optimizers package ecosystem was one of the main motivations to look for a solution that could be applied and reapplied to existing packages, in particular to help maintainers.","category":"page"},{"location":"#Contributors","page":"Home","title":"Contributors","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"\n\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\"Abel
Abel Soares Siqueira

💻 📆 📖 🚧
\"Tangi
Tangi Migot

💻 📖 👀
\"Pablo
Pablo Rodríguez-Sánchez

📖 🤔
\"Olga
Olga Lyashevska

💻 📖 🤔
\"Luisa
Luisa Orozco

💻 📖 🤔
\"Netherlands
Netherlands eScience Center

💵
\"Suvayu
Suvayu Ali

🐛 👀 💻
\"Stefan
Stefan Verhoeven

💻 🤔
\"Dominique\"/
Dominique

🤔 💻
\"fdiblen\"/
fdiblen

💻 👀
\"Greg
Greg Neustroev

💻
\n\n\n\n\n\n","category":"page"},{"location":"10-full-guide/#full_guide","page":"Full Guide","title":"Full guide","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Welcome to full usage guide of BestieTemplate.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Pages = [\"10-full-guide.md\"]\nDepth = 2:3","category":"page"},{"location":"10-full-guide/#Before-installing","page":"Full Guide","title":"Before installing","text":"","category":"section"},{"location":"10-full-guide/#Things-to-know","page":"Full Guide","title":"Things to know","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"This template is an attempt to provide many best practices to package development. This can be overwhelming, so you might prefer to take it easy at first and install only the fewest amount of new things possible.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Thinking of you, the first optional question in the template is how to deal with the optional questions:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The \"Recommended\" option lets us select the best practices that we like the most. This means \"yes\" to most of the optional answers.\nThe \"Minimum\" option does not add any optional feature. Your package will still be a valid Julia package with a few things that we deem essential (such as online testing, documentation, and CITATION.CFF).","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The \"Minimum\" option is still a step above the bare minimum for a Julia package, so you will still benefit from the template. The \"Recommended\" option adds many features that package maintainers might find useful in the long run, but might be too much at once. Check the Explanation page for more information.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you decide to gradually adopt, do this:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Follow the relevant application section for New or Existing.\nRemember to select the \"Minimum\" optional questions.\nFollow the Update section, change your answer from \"Minimum\" to \"Recommended\" or \"Ask me\".","category":"page"},{"location":"10-full-guide/#Things-to-install","page":"Full Guide","title":"Things to install","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Install a plugin on your editor to use EditorConfig. This will ensure that your editor is configured with important formatting settings.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"We use https://pre-commit.com to run the linters and formatters. In particular, the Julia code is formatted using JuliaFormatter.jl, so please install it globally first:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> # Press ]\npkg> activate\npkg> add JuliaFormatter","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To install pre-commit, we recommend using pipx as follows:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"# Install pipx following the link\npipx install pre-commit","category":"page"},{"location":"10-full-guide/#Install-BestieTemplate-(or-copier)","page":"Full Guide","title":"Install BestieTemplate (or copier)","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To use the template, we recommend installing the package BestieTemplate.jl globally:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> # press ]\npkg> activate\npkg> add BestieTemplate","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The BestieTemplate package wraps copier and adds some lightweight checks and parameters to make your user experience better.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Alternative\nAlternatively, you can use copier directly, in which case you will have the pure template generation experience. If that is the case, I will assume that you know what you are doing and won't show the full command here to avoid confusing new users.","category":"page"},{"location":"10-full-guide/#Using-the-template","page":"Full Guide","title":"Using the template","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"There are three use cases on using the template:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You are using the template to start a new package.\nYou already have a Julia project and you want to apply the template to your project.\nYou already uses the template and you want to update to get the latest changes.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The three cases are listed below.","category":"page"},{"location":"10-full-guide/#new_package","page":"Full Guide","title":"New package","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Simply run","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> using BestieTemplate\njulia> BestieTemplate.generate(\"full/path/to/YourPackage.jl\")","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"This will create the folder at the given path and create a package named YourPackage using the latest release of the BestieTemplate. You will be prompted with many questions, some required and some with our recommended choices.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You can give more options to the generate function, including the source of the template, pre-filled data, and options passed to the underlying project generator copier. See the full docstring for BestieTemplate.generate for more information.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The resulting folder will not be a git package yet (to avoid trust issues), so you need to handle that yourself. You should see a short guide on screen, but here it is again:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"cd full/path/to/YourPackage.jl\ngit init\ngit add .\npre-commit run -a # Try to fix possible pre-commit issues (failures are expected)\ngit add .\ngit commit -m \"First commit\"\npre-commit install # Future commits can't be directly to main unless you use -n","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Now, create a new repository on GitHub and push your code. We won't give you details on how to do this, but you can check The Turing Way.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"After that, jump on to Setting up your package.","category":"page"},{"location":"10-full-guide/#existing_package","page":"Full Guide","title":"Applying to an existing package","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To apply the template to an existing package, you can do the following:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: git\nThis assumes that you already use git on that package and the your working directory is clean. It will fail otherwise.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> using BestieTemplate\njulia> BestieTemplate.apply(\"full/path/to/YourPackage.jl\")","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"This will look for a file Project.toml at the root of the given path and use the information there to guess some of the answers. Currently, we guess the PackageName, PackageUUID from the name and uuid fields, and try to guess the AuthorName and AuthorEmail from the authors field by looking at the first match.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"tip: Overwrite\nYou will be asked whether to overwrite existing files or not. Since you are using git, you can try it out and reset if you don't like the result.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you don't like the result, or want to override the answers, you can run the apply function with additional arguments:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> data = Dict(\"AuthorName\" => \"Bob\", \"AuthorEmail\" => \"bob@bob.br\")\njulia> BestieTemplate.apply(\"full/path/to/YourPackage.jl\", data)","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"See the full docstring for BestieTemplate.apply for more information.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You will most likely have conflicts when you apply the template. Whenever a conflict appears, you will need to decide on whether to accept or reject the new changes. Unfortunately, they are not shown to you when the conflict appears, so the best solution is to just accept all of them and then fix the conflicts using git.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Review the changes\nDon't just add the changes blindly, because some of your files can and will be overwritten.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: README.md conflicts\nWe really can't avoid some conflicts, and although some file can be skipped if existing (such as CITATION.cff), some can't. For instance, README.md will most likely be wrong when you apply the template, but the badges (for instance), need to be included in your project. This means that README.md cannot be skipped, and you will have to accept the overwrite and manually fix your README.md.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"tip: Formatting\nYou might most likely see changes in the formatting. So if you have are a formatter, it might be best to run it before reviewing the changes. If you have chosen the \"Recommended\" answers, or explicitly chose to add pre-commit, then you should use it now (see below).","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you need some help with undoing some of these changes, I recommend using a graphical interface. After the template is applied and you are happy with the conflict resolution, enable pre-commit and push your code.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"git add .\npre-commit run -a # Try to fix possible pre-commit issues (failures are expected)\npre-commit install # All commits will run pre-commit now\ngit add .\ngit commit -m \"Apply BestieTemplate vx.y.z\"","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Push your code to GitHub and head to Setting up your package for information on what to do next.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Now, go to Setting up your package to check what you still need to configure for your package.","category":"page"},{"location":"10-full-guide/#updating_package","page":"Full Guide","title":"Updating","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To update the package, simply call","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> BestieTemplate.update()","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You will be asked the relevant questions of the package as if you had applied it. The big differences are:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"It will only apply the things that are new since you last applied/updated\nIt will remember previous answer.\nIt will overwrite without asking.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"tip: Change previous answers\nYou can change your previous answers. In other words, if you though something was not mature enough in the past, but you are more confident in that now, you can adopt it now. This works even if the template was not updated itself.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"As with the first application, you need to run pre-commit run -a to fix the unavoidable linting and formatting issues. Check the modifications in the relevant linter and formatting files, if you changed them manually, before doing it, though.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"pre-commit run -a","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The underlying package copier will use git to apply the differences and it will overwrite whatever files it finds in the way. Since git is mandatory, the changes will be left for you to review.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Review the changes\nI repeat, the changes will be left for you to review. Don't just add them blindly, because some of your modifications can and will be overwritten.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you need some help with undoing some of these changes, I recommend using a graphical interface.","category":"page"},{"location":"10-full-guide/#Setting-up-your-package","page":"Full Guide","title":"Setting up your package","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"There are various steps to setting up your package on GitHub. Some are important now, and some will be relevant when you try to make your first release.","category":"page"},{"location":"10-full-guide/#Add-to-GitHub","page":"Full Guide","title":"Add to GitHub","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you haven't yet, create a repo on GitHub and push your code to it.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"info: Info\nThe actions will run and you will see errors in the documentation and linting. Do not despair.","category":"page"},{"location":"10-full-guide/#Documentation","page":"Full Guide","title":"Documentation","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Go to your package setting on Github and find the \"Actions\" tab, the \"General\" link. On that page, find the \"Workflow permissions\" and change the selection to \"Read and write permissions\", and enable \"Allow GitHub Actions can create and approve pull requests\". This will allow the documentation workflow to work for development.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Go to the Actions page, click the failing Docs workflow and click on \"re-run all jobs\". It should pass now.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Now, go to your package setting on GitHub and find the \"Pages\" link. You should see an option to set the Source to \"Deploy from a branch\", and select the branch to be \"gh-pages\" and to deploy from the \"/ (root)\".","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"After circa 1 minute, you can check that the documentation was built properly.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"info: Info\nAt this point, you should have passing workflows.Tests should have been passing from the start.\nLint was fixed when we pushed the code to GitHub.\nDocs was fixed with the permissions change.","category":"page"},{"location":"10-full-guide/#Documentation-for-releases","page":"Full Guide","title":"Documentation for releases","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"info: Info\nThis section is only relevant when making your first release, but it might be better to get it out of the way now.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You need to set a DOCUMENTER_KEY to build the documentation from the tags automatically when using TagBot (which we do by default). Do the following:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"pkg> activate --temp\npkg> add DocumenterTools\njulia> using DocumenterTools\njulia> DocumenterTools.genkeys(user=\"UserName\", repo=\"PackageName.jl\")","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Follow the instruction in the terminal.","category":"page"},{"location":"10-full-guide/#Enable-Codecov-for-code-coverage","page":"Full Guide","title":"Enable Codecov for code coverage","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you don't have a Codecov account, go to https://codecov.io and create one now. After creating an account and logging in, you will see your main page with a list of your packages. Select the one that you are creating, it will open a configuration page.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"On the configuration page, select \"Using GitHub Actions\" as your CI. The first step in the list given you the CODECOV_TOKEN. Click on the \"repository secret\" link on that page. It should lead you to the GitHub settings > secrets and variables > actions, under a \"New secret\" screen. Write CODECOV_TOKEN on the \"Name\" field and paste the token that you see on codecov on the \"Secret\" field. Click \"Add secret\".","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Step 2 is not necessary because it is already present in the template.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The next time that the tests are run, the coverage page will be updated, and the badge will be fixed.","category":"page"},{"location":"10-full-guide/#Add-key-for-Copier.yml-workflow","page":"Full Guide","title":"Add key for Copier.yml workflow","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Copier.yml is work in progress\nThis option is not selected by default because it is a work in progress. If you want to use it, you have to pass the key \"AddCopierCI\" => true to the data argument of generate or apply, or select \"Ask me\" when deciding how to answer the optional questions.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You can reapply the template in the future. This is normally a manual job, specially because normally there are conflicts. That being said, we are experimenting with having a workflow that automatically checks whether there are updates to the template and reapplies it. A Pull Request is created with the result.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Warning\nThis is optional, and in development, so you might want to delete the workflow instead.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you decide to use, here are the steps to set it up:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Create a Personal Access Token to be used by the Copier workflow.\nGo to https://github.com/settings/tokens.\nCreate a token with \"Content\", \"Pull-request\", and \"Workflows\" permissions.\nCopy the Token.\nGo to your YOUR_PACKAGE_URL/settings/secrets/actions.\nCreate a \"New repository secret\" named COPIER_PAT.","category":"page"},{"location":"10-full-guide/#CITATION.cff-and-Zenodo-deposition","page":"Full Guide","title":"CITATION.cff and Zenodo deposition","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Update your CITATION.cff file with correct information. You can use cffinit to generate it easily.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Before releasing, enable Zenodo integration at https://zenodo.org/account/settings/github/ to automatically generate a deposition of your package, i.e., archive a version on Zenodo and generate a DOI.","category":"page"},{"location":"10-full-guide/#Update-README.md","page":"Full Guide","title":"Update README.md","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Update the badges\nAdd a description","category":"page"},{"location":"10-full-guide/#Enable-discussions","page":"Full Guide","title":"Enable discussions","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Enable GitHub discussions.","category":"page"},{"location":"10-full-guide/#First-release","page":"Full Guide","title":"First release","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"When you are ready to make your first release, enable the Julia Registrator bot. Make sure that you haven't skipped these sections:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Documentation for releases\nCITATION.cff and Zenodo deposition","category":"page"}] +[{"location":"20-explanation/#explanation","page":"Explanation","title":"Explanation","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"In this section, we hope to explain the motivation for the package, and what is inside the template. Some things might have been obvious when creating the package and not at the moment, so feel free to create issues to ask, or suggest, clarifications.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"tip: Tip\nIf something is missing or not explained enough, please open an issue.","category":"page"},{"location":"20-explanation/#The-engine,-the-project-generator,-and-the-template","page":"Explanation","title":"The engine, the project generator, and the template","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Let me start by marking some names clearer.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The template is the collection of files and folders written with some placeholders. For instance, the link to a GitHub project will be something like https://github.com/{{ PackageOwner }}/{{ PackageName }}.jl.\nThe engine is the tool that converts the template into the end result, by changing the placeholders into the actual values that we want.\nThe project generator is the tool that interacts with the user to get the placeholder values and give to the engine.","category":"page"},{"location":"20-explanation/#Comparison-with-existing-solutions","page":"Explanation","title":"Comparison with existing solutions","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Julia has a very good package generator called PkgTemplates.jl, so why did we create another one?","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The short answer is that we want a more streamlined development experience, a template more focused on best practices, and the ability to keep reusing the template whenever new tools and ideas are implemented.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"In more details, first, see the differences in the parts of the project in the table below:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":" BestieTemplate.jl PkgTemplates.jl\nTemplate Part of the package Part of the package\nEngine Jinja Mustache\nProject generator copier, with some wrappers in the package Part of the package","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Now, we can split this into three comparisons.","category":"page"},{"location":"20-explanation/#Template-differences","page":"Explanation","title":"Template differences","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The template differences are mostly due to opinion and contributions and it should be easy to translate files from one template to the other. We are heavily inspired by PkgTemplates.jl, as we used it for many years, but we made some changes in the hopes of improving software sustainability, package maintainability and code quality (which we just overtly simplify as best practices). As such, our current differences (as of the time of writing) are:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We have more best practices tools, such as pre-commit, configuration for linters and formatters for Julia, Markdown, TOML, YAML and JSON, CITATION.cff, Lint GitHub workflow, .editorconfig file, issues and pull requests templates, etc.\nWe focus on the main use cases (GitHub and GitHub actions), so we have much less options.","category":"page"},{"location":"20-explanation/#Engine-differences","page":"Explanation","title":"Engine differences","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We can't say much about these, since we don't know or care in details.","category":"page"},{"location":"20-explanation/#Project-generator-differences","page":"Explanation","title":"Project generator differences","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"PkgTemplates.jl is a project generator. This means that if you want to programmatically create templates inside Julia, this is the best solution. The questions (user interface) are implemented by the package, which then translates that into the answers for the engine. Disclaimer: We haven't worked on the package, this information is based on the docs.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We use copier as project generator. It is an external Python tool, so we also include some wrappers in the package to use it from Julia without the need to explicitly install it. Copier has many features, so we recommend that you check their comparisons pages for more information.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Most notably, the feature that made us choose copier in the first place has the ability to applied and reapplied to existing projects. This means that existing packages can benefit from all best practices that we provide. Furthermore, they can keep reaping benefits when we create new versions of the template.","category":"page"},{"location":"20-explanation/#Template-details","page":"Explanation","title":"Template details","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Let's dive into the details of the template now.","category":"page"},{"location":"20-explanation/#Basic-package-structure","page":"Explanation","title":"Basic package structure","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"This is the basic structure of a package:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"PackageName.jl/\nsrc/\nPackageName.jl\ntest/\nProject.toml\nruntests.jl\nLICENSE.md\nProject.toml\nREADME.md","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"With the exception of test/Project.toml, all other files are requirements to register a package.","category":"page"},{"location":"20-explanation/#Documentation","page":"Explanation","title":"Documentation","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"On top of the basic structure, we add some Documenter.jl structure.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"docs/\nsrc/\n90-contributing.md\n91-developer.md\n95-reference.md\nindex.md\nmake.jl\nProject.toml","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Brief explanation of the details:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The Project.toml, make.jl and src/index.md are the basic structure.\ndocs/src/90-contributing.md: Sometimes added as CONTRIBUTING.md, it explains how contributors can get involved in the project.\ndocs/src/91-developer.md: Sometimes added as README.dev.md or DEVELOPER.md, it explains how to setup your local environment and other information relevant for developers only.\ndocs/src/95-reference.md is the API reference page, which include an @autodocs.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"One noteworthy aspect of our make.jl, is that we include some code to automatically generate the list of pages. Create a file in the form ##-name.md, where ## is a two-digit number, and it will be automatically added to the pages list.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"info: index.md\nYou might have noticed that index.md is not numbered, and that is because Documenter.jl checks for that files specifically to define the landing page. Instead, we explicitly add \"Home\" => \"index.\" to make.jl.","category":"page"},{"location":"20-explanation/#Linting-and-Formatting","page":"Explanation","title":"Linting and Formatting","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"The most important file related to linting and formatting is .pre-commit-config.yaml, which is the configuration for pre-commit. It defines a list of linters and formatters for Julia, Markdown, TOML, YAML, and JSON.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"It requires installing pre-commit (I recommend installing it globally with pipx). Installing pre-commit (pre-commit install) will make sure that it runs the relevant hooks before committing. Furthermore, if you run pre-commit run -a, it runs all hooks.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Some hooks in the .pre-commit-config.yaml file have configuration files of their own: .JuliaFormatter.toml, .markdownlint.json, lychee.toml, and .yamllint.yml.","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"Also slightly related, is the .editorconfig file, which tells your editor, if you install the correct plugin, how to format some things.","category":"page"},{"location":"20-explanation/#GitHub-Workflows","page":"Explanation","title":"GitHub Workflows","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We have a few workflows, with plans to expand in the future:","category":"page"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"CompatHelper.yml: Should be well known by now. It checks that your Project.toml compat entries are up-to-date.\nCopier.yml: This will periodically check the template for updates. If there are updates, this action creates a pull request updating your repo.\nDocs.yml: Build the docs. Only runs when relevant files change.\nLint.yml: Run the linter and formatter through the command pre-commit run -a.\nTagBot.yml: Create GitHub releases automatically after your new release is merged on the Registry.\nFor testing, we have\nReusableTest.yml: Defines a reusable workflow with the testing.\nTest.yml: Defines a matrix of tests to be run whenever main is updated or a tag is created. Uses the ReusableTest workflow. If \"Simplified PR Test\" was not chosen, then this also runs when there are pull requests.\nTestOnPRs.yml: Defines a test to be run when pull requests are created. Only the latest stable Julia version is tested on a ubuntu-latest image. Uses the ReusableTest workflow. If \"Simplified PR Test\" was not chosen, then this file does not exist.","category":"page"},{"location":"20-explanation/#Issues-and-PR-templates","page":"Explanation","title":"Issues and PR templates","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":"We include issues and PR templates for GitHub (see .github/). These provide a starting point to your project management.","category":"page"},{"location":"20-explanation/#Other-files","page":"Explanation","title":"Other files","text":"","category":"section"},{"location":"20-explanation/","page":"Explanation","title":"Explanation","text":".cirrus.yml: For Cirrus CI, which we use solely for FreeBSD testing.\nCITATION.cff: Instead of the more classic .bib, we use .cff, which serves a better purpose of providing the metadata of the package. CFF files have been adopted by GitHub, so you can generate a BibTeX entry by clicking on \"Cite this repository\" on the repository's main page. CFF files have also been adopted by Zenodo to provide the metadata of your deposition.\nCODE_OF_CONDUCT.md: A code of conduct file from Contributor Covenant.","category":"page"},{"location":"91-developer/#dev_docs","page":"Developer docs","title":"Developer documentation","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"note: Contributing guidelines\nIf you haven't, please read the Contributing guidelines first.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If you want to make contributions to this package that involves code, then this guide is for you.","category":"page"},{"location":"91-developer/#First-time-clone","page":"Developer docs","title":"First time clone","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"tip: If you have writing rights\nIf you have writing rights, you don't have to fork. Instead, simply clone and skip ahead. Whenever upstream is mentioned, use origin instead.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If this is the first time you work with this repository, follow the instructions below to clone the repository.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Fork this repo\nClone your repo (this will create a git remote called origin)\nAdd this repo as a remote:\ngit remote add upstream https://github.com/abelsiqueira/BestieTemplate.jl","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"This will ensure that you have two remotes in your git: origin and upstream. You will create branches and push to origin, and you will fetch and update your local main branch from upstream.","category":"page"},{"location":"91-developer/#Linting-and-formatting","page":"Developer docs","title":"Linting and formatting","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Install a plugin on your editor to use EditorConfig. This will ensure that your editor is configured with important formatting settings.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"We use https://pre-commit.com to run the linters and formatters. In particular, the Julia code is formatted using JuliaFormatter.jl, so please install it globally first:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"julia> # Press ]\npkg> activate\npkg> add JuliaFormatter","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To install pre-commit, we recommend using pipx as follows:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"# Install pipx following the link\npipx install pre-commit","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"With pre-commit installed, activate it as a pre-commit hook:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"pre-commit install","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To run the linting and formatting manually, enter the command below:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"pre-commit run -a","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Now, you can only commit if all the pre-commit tests pass.","category":"page"},{"location":"91-developer/#Testing","page":"Developer docs","title":"Testing","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"As with most Julia packages, you can just open Julia in the repository folder, activate the environment, and run test:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"julia> # press ]\npkg> activate .\npkg> test","category":"page"},{"location":"91-developer/#Testing-local-changes-to-the-template","page":"Developer docs","title":"Testing local changes to the template","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"I recommend installing copier, although it is possible to test the template using only Julia, it becomes more complicated, and cumbersome. Using pipx (as above), you can just run","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"pipx install copier","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To test your local modifications, you can run copier with the --vcs-ref HEAD flag and point to your local clone. This will use the latest changes, including uncommitted modifications (i.e., the dirty state). What I normally do is this:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"cd $(mktemp -d) # Go to a tmp folder\ncopier copy --vcs-ref HEAD /path/to/clone/ pkg # Clone dirty clone into pkg","category":"page"},{"location":"91-developer/#Working-on-a-new-issue","page":"Developer docs","title":"Working on a new issue","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"We try to keep a linear history in this repo, so it is important to keep your branches up-to-date.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Fetch from the remote and fast-forward your local main\ngit fetch upstream\ngit switch main\ngit merge --ff-only upstream/main\nBranch from main to address the issue (see below for naming)\ngit switch -c 42-add-answer-universe\nPush the new local branch to your personal remote repository\ngit push -u origin 42-add-answer-universe\nCreate a pull request to merge your remote branch into the org main.","category":"page"},{"location":"91-developer/#Branch-naming","page":"Developer docs","title":"Branch naming","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If there is an associated issue, add the issue number.\nIf there is no associated issue, and the changes are small, add a prefix such as \"typo\", \"hotfix\", \"small-refactor\", according to the type of update.\nIf the changes are not small and there is no associated issue, then create the issue first, so we can properly discuss the changes.\nUse dash separated imperative wording related to the issue (e.g., 14-add-tests, 15-fix-model, 16-remove-obsolete-files).","category":"page"},{"location":"91-developer/#Commit-message","page":"Developer docs","title":"Commit message","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Use imperative or present tense, for instance: Add feature or Fix bug.\nHave informative titles.\nWhen necessary, add a body with details.\nIf there are breaking changes, add the information to the commit message.","category":"page"},{"location":"91-developer/#Before-creating-a-pull-request","page":"Developer docs","title":"Before creating a pull request","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"tip: Atomic git commits\nTry to create \"atomic git commits\" (recommended reading: The Utopic Git History).","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Make sure the tests pass.\nMake sure the pre-commit tests pass.\nFetch any main updates from upstream and rebase your branch, if necessary:\ngit fetch upstream\ngit rebase upstream/main BRANCH_NAME\nThen you can open a pull request and work with the reviewer to address any issues.","category":"page"},{"location":"91-developer/#Building-and-viewing-the-documentation-locally","page":"Developer docs","title":"Building and viewing the documentation locally","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Following the latest suggestions, we recommend using LiveServer to build the documentation. Here is how you do it:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Run julia --project=docs to open Julia in the environment of the docs.\nIf this is the first time building the docs\nPress ] to enter pkg mode\nRun pkg> dev . to use the development version of your package\nPress backspace to leave pkg mode\nRun julia> using LiveServer\nRun julia> servedocs()","category":"page"},{"location":"91-developer/#Making-a-new-release","page":"Developer docs","title":"Making a new release","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To create a new release, you can follow these simple steps:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Create a branch release-x.y.z\nUpdate version in Project.toml\nUpdate the CHANGELOG.md:\nRename the section \"Unreleased\" to \"[x.y.z] - yyyy-mm-dd\" (i.e., version under brackets, dash, and date in ISO format)\nAdd a new section on top of it named \"Unreleased\"\nAdd a new link in the bottom for version \"x.y.z\"\nChange the \"[unreleased]\" link to use the latest version - end of line, vx.y.z ... HEAD.\nCreate a commit \"Release vx.y.z\", push, create a PR, wait for it to pass, merge the PR.\nGo back to main screen and click on the latest commit (link: https://github.com/abelsiqueira/BestieTemplate.jl/commit/main)\nAt the bottom, write @JuliaRegistrator register","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"After that, you only need to wait and verify:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Wait for the bot to comment (should take < 1m) with a link to a RP to the registry\nFollow the link and wait for a comment on the auto-merge\nThe comment should said all is well and auto-merge should occur shortly\nAfter the merge happens, TagBot will trigger and create a new GitHub tag. Check on https://github.com/abelsiqueira/BestieTemplate.jl/releases\nAfter the release is create, a \"docs\" GitHub action will start for the tag.\nAfter it passes, a deploy action will run.\nAfter that runs, the stable docs should be updated. Check them and look for the version number.","category":"page"},{"location":"91-developer/#Additions-to-the-templates","page":"Developer docs","title":"Additions to the templates","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"info: Suggestions are not here\nThis section is aimed at the developer working on a new question, if you have any new idea or think the template needs to be updated or fixed, please search our issues and if there isn't anything relevant, open a new issue.","category":"page"},{"location":"91-developer/#Creating-a-new-question","page":"Developer docs","title":"Creating a new question","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To create a new question, you have to open the file copier.yml in the root. Find an appropriate place to add the question. Comments help identify the optional sections in the file.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Follow the other questions style and syntax. The gist of it is that you need:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"A CamelCase name.\nwhen: \"{{ AnswerStrategy == 'ask' }}\" if the question is optional.\nA type.\nA help: Short description or title (Longer description and details).\nA default, if the question is optional.\nTo default to true if \"Recommended\" or false for \"Minimum\", use {{ AnswerStrategy != 'minimum' }}.","category":"page"},{"location":"91-developer/#Dependent-sections-in-a-file","page":"Developer docs","title":"Dependent sections in a file","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To create a section in a file that depends on a variable, first add .jinja to the end of the file name and use something like","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"{% if AddSomeStuff %}\n...\n{% endif %}","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"AddSomeStuff is assumed to be boolean here, but you can use other conditions, such as {% if PackageName == 'Pkg' %}.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Notice that the empty spaces are included as well, so in some situation you might need to make it less readable. For instance, the code below will correctly parse into a list of three elements if AddBob is false.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"# Good\n\n- Alice{% if AddBob %}\n- Bob{% endif}\n- Carlos\n- Diana","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"While the code below will parse into two lists of one and two elements, respectively:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"# Bad\n- Alice\n{% if AddBob %}- Bob{% endif}\n- Carlos\n- Diana","category":"page"},{"location":"91-developer/#Dependent-files-and-directories","page":"Developer docs","title":"Dependent files and directories","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To make a file depend on a variable, you can change the name of the file to include the conditional and the .jinja extension.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"{% if AddSomeFile %}some-file.txt{% endif %}.jinja","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"If AddSomeFile, then some-file.txt will exist.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"For directories, you do the same, except that you don't add the .jinja extension.","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"{% if AddGitHubTemplates %}ISSUE_TEMPLATE{% endif %}","category":"page"},{"location":"91-developer/#Using-answers","page":"Developer docs","title":"Using answers","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"To use the answers of a question outside of a conditional, you can use {{ SomeValue }}. This will translate to the value of SomeValue as answered by the user. For instance","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"whoami() = \"Hi, I'm package {{ PackageName }}.jl\"","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"This also works on file names and in the copier.yml file.","category":"page"},{"location":"91-developer/#Raw-tag-and-avoiding-clashes-in-GitHub-workflow-files","page":"Developer docs","title":"Raw tag and avoiding clashes in GitHub workflow files","text":"","category":"section"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"Since the GitHub workflow also uses { and } for their commands, we want to enclose them using the {% raw %}...{% endraw %} tag:","category":"page"},{"location":"91-developer/","page":"Developer docs","title":"Developer docs","text":"os: {% raw %}%{{ matrix.os }}{% endraw %}","category":"page"},{"location":"95-reference/#reference","page":"Reference","title":"Reference","text":"","category":"section"},{"location":"95-reference/#Contents","page":"Reference","title":"Contents","text":"","category":"section"},{"location":"95-reference/","page":"Reference","title":"Reference","text":"Pages = [\"95-reference.md\"]","category":"page"},{"location":"95-reference/#Index","page":"Reference","title":"Index","text":"","category":"section"},{"location":"95-reference/","page":"Reference","title":"Reference","text":"Pages = [\"95-reference.md\"]","category":"page"},{"location":"95-reference/","page":"Reference","title":"Reference","text":"Modules = [BestieTemplate, BestieTemplate.Copier]","category":"page"},{"location":"95-reference/#BestieTemplate.BestieTemplate","page":"Reference","title":"BestieTemplate.BestieTemplate","text":"BestieTemplate.jl\n\nThis package defines a copier template for Julia packages and a basic user interface aroud copier to use it from Julia.\n\nThe main functions are: generate, apply, and update.\n\n\n\n\n\n","category":"module"},{"location":"95-reference/#BestieTemplate._copy-Tuple{Any, Any, Any}","page":"Reference","title":"BestieTemplate._copy","text":"_copy(src_path, dst_path, data; kwargs...)\n\nInternal function to run common code for new or existing packages.\n\n\n\n\n\n","category":"method"},{"location":"95-reference/#BestieTemplate._read_data_from_existing_path-Tuple{Any}","page":"Reference","title":"BestieTemplate._read_data_from_existing_path","text":"data = _read_data_from_existing_path(dst_path)\n\nReads the destination folder to figure out some answers.\n\n\n\n\n\n","category":"method"},{"location":"95-reference/#BestieTemplate._sanitize_package_name-Tuple{Any}","page":"Reference","title":"BestieTemplate._sanitize_package_name","text":"package_name = _sanitize_package_name(path)\n\nSanitize the path to guess the package_name by looking at the base name and removing an extension. If the result is not a valid identifier, returns \"\".\n\n\n\n\n\n","category":"method"},{"location":"95-reference/#BestieTemplate.apply","page":"Reference","title":"BestieTemplate.apply","text":"apply(dst_path[, data]; kwargs...)\napply(src_path, dst_path[, data]; true, kwargs...)\n\nApplies the template to an existing project at path dst_path. If the dst_path does not exist, this will throw an error. For new packages, use BestieTemplate.generate instead.\n\nRuns the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.\n\nThe data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.\n\nKeyword arguments\n\nwarn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run apply and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.\n\nThe other keyword arguments are passed directly to the internal Copier.copy.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.generate","page":"Reference","title":"BestieTemplate.generate","text":"generate(dst_path[, data]; kwargs...)\ngenerate(src_path, dst_path[, data]; true, kwargs...)\n\nGenerates a new project at the path dst_path using the template. If the dst_path already exists, this will throw an error, unless dst_path = \".\". For existing packages, use BestieTemplate.apply instead.\n\nRuns the copy command of copier with the BestieTemplate template. If src_path is not informed, the GitHub URL of BestieTemplate.jl is used.\n\nThe data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.\n\nKeyword arguments\n\nwarn_existing_pkg::Boolean = true: Whether to check if you actually meant update. If you run generate and the dst_path contains a .copier-answers.yml, it means that the copy was already made, so you might have means update instead. When true, a warning is shown and execution is stopped.\n\nThe other keyword arguments are passed directly to the internal Copier.copy.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.update","page":"Reference","title":"BestieTemplate.update","text":"update([data]; kwargs...)\nupdate(dst_path[, data]; kwargs...)\n\nRun the update command of copier, updating the dst_path (or the current path if omitted) with a new version of the template with a new version of the template.\n\nThe data argument is a dictionary of answers (values) to questions (keys) that can be used to bypass some of the interactive questions.\n\nKeyword arguments\n\nThe keyword arguments are passed directly to the internal Copier.update.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.Copier","page":"Reference","title":"BestieTemplate.Copier","text":"Wrapper around copier.\n\nThere are three functions in this module:\n\ncopy\nrecopy\nupdate\n\n\n\n\n\n","category":"module"},{"location":"95-reference/#Base.copy","page":"Reference","title":"Base.copy","text":"copy(dst_path[, data]; kwargs...)\ncopy(src_path, dst_path[, data]; kwargs...)\n\nWrapper around copier.run_copy.\n\nThis is an internal function, if BestieTemplate's main API is not sufficient, open an issue.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.Copier.recopy","page":"Reference","title":"BestieTemplate.Copier.recopy","text":"recopy(dst_path[, data]; kwargs...)\n\nWrapper around copier.run_recopy.\n\nThis is an internal function, if BestieTemplate's main API is not sufficient, open an issue.\n\n\n\n\n\n","category":"function"},{"location":"95-reference/#BestieTemplate.Copier.update","page":"Reference","title":"BestieTemplate.Copier.update","text":"update(dst_path[, data]; kwargs...)\n\nWrapper around copier.run_update.\n\nThis is an internal function, if BestieTemplate's main API is not sufficient, open an issue.\n\n\n\n\n\n","category":"function"},{"location":"90-contributing/#contributing","page":"Contributing","title":"Contributing guidelines","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"First of all, thanks for the interest!","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"We welcome all kinds of contribution, including, but not limited to code, documentation, examples, configuration, issue creating, etc.","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"Be polite and respectful, and follow the code of conduct.","category":"page"},{"location":"90-contributing/#Bug-reports-and-discussions","page":"Contributing","title":"Bug reports and discussions","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If you think you found a bug, feel free to open an issue. Focused suggestions and requests can also be opened as issues. Before opening a pull request, start an issue or a discussion on the topic, please.","category":"page"},{"location":"90-contributing/#Working-on-an-issue","page":"Contributing","title":"Working on an issue","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If you found an issue that interests you, comment on that issue what your plans are. If the solution to the issue is clear, you can immediately create a pull request (see below). Otherwise, say what your proposed solution is and wait for a discussion around it.","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"tip: Tip\nFeel free to ping us after a few days if there are no responses.","category":"page"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If your solution involves code (or something that requires running the package locally), check the developer documentation. Otherwise, you can use the GitHub interface directly to create your pull request.","category":"page"},{"location":"90-contributing/#Additions-and-modifications-to-the-template","page":"Contributing","title":"Additions and modifications to the template","text":"","category":"section"},{"location":"90-contributing/","page":"Contributing","title":"Contributing","text":"If you have any new idea or think the template needs to be updated or fixed, please search our issues and if there isn't anything relevant, open a new issue.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = BestieTemplate","category":"page"},{"location":"#BestieTemplate-Your-best-practices-friend","page":"Home","title":"BestieTemplate - Your best practices friend","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"(Image: BestieTemplate.jl)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Welcome to the documentation of BestieTemplate.jl. This package provides a template in the copier engine for a Julia package. Furthermore, it provides a wrapper around convenience calls to that package.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main features of this package/template are:","category":"page"},{"location":"","page":"Home","title":"Home","text":"It provides a curated (opinionated) list of tools and best practices for Julia package development;\nIt can be applied and reapplied to existing packages, allowing the updates in the template to be imported into the package;","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: asciicast)","category":"page"},{"location":"#Using","page":"Home","title":"Using","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To fully benefit from the template, there are some steps to be done before and after you generate your package. Check the full guide for more details.","category":"page"},{"location":"","page":"Home","title":"Home","text":"However, if you kinda know what you need to do, this is the TL;DR:","category":"page"},{"location":"","page":"Home","title":"Home","text":"using> # press ]\npkg> add BestieTemplate\njulia> using BestieTemplate\njulia> BestieTemplate.generate(\"path/to/YourNewPackage.jl\")\njulia> # or BestieTemplate.apply(\"path/to/YourExistingPackage.jl\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"I really recommend checking the full guide, though.","category":"page"},{"location":"","page":"Home","title":"Home","text":"To understand more about our motivation and what the template provides, check the explanation page.","category":"page"},{"location":"#Getting-and-providing-help","page":"Home","title":"Getting and providing help","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"I hope you find this package useful. If you have any questions, requests, or comments, check the issues and discussion pages.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you would like to get involved in the BestieTemplate growth, please check our contributing guide. We welcome contributions of many types, including coding, reviewing, creating issues, creating tutorials, interacting with users, etc. Make sure to follow our code of conduct.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If your interest is in developing the package, check the development guide as well.","category":"page"},{"location":"#References","page":"Home","title":"References","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Here is a list of links/repos that include content that we have used for inspiration, or used directly. This is most likely not a complete list, since many of the things included here were based on existing packages and knowledge that we brought from other projects. This also doesn't explain where each file came from or why they are here. You can find some of that information in the Explanation section of the docs.","category":"page"},{"location":"","page":"Home","title":"Home","text":"PkgTemplates.jl, naturally. We used it for many years, and in particular for the initial TulipaEnergyModel.jl commit (see below).\nNetherlands eScience Center's python template includes many of the best practices that we apply here. We used many of the ideas there in a Julia context, and took many non-Julia specific ideas from there.\nTulipaEnergyModel.jl was the project that motivated this version of a template. From the start we decide to implement many best practices and so we started from a PkgTemplates.jl template and started adding parts of the python template that made sense.\nThe Julia Smooth Optimizers package ecosystem was one of the main motivations to look for a solution that could be applied and reapplied to existing packages, in particular to help maintainers.","category":"page"},{"location":"#Contributors","page":"Home","title":"Contributors","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"\n\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\"Abel
Abel Soares Siqueira

💻 📆 📖 🚧
\"Tangi
Tangi Migot

💻 📖 👀
\"Pablo
Pablo Rodríguez-Sánchez

📖 🤔
\"Olga
Olga Lyashevska

💻 📖 🤔
\"Luisa
Luisa Orozco

💻 📖 🤔
\"Netherlands
Netherlands eScience Center

💵
\"Suvayu
Suvayu Ali

🐛 👀 💻
\"Stefan
Stefan Verhoeven

💻 🤔
\"Dominique\"/
Dominique

🤔 💻
\"fdiblen\"/
fdiblen

💻 👀
\"Greg
Greg Neustroev

💻
\n\n\n\n\n\n","category":"page"},{"location":"10-full-guide/#full_guide","page":"Full Guide","title":"Full guide","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Welcome to full usage guide of BestieTemplate.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Pages = [\"10-full-guide.md\"]\nDepth = 2:3","category":"page"},{"location":"10-full-guide/#Before-installing","page":"Full Guide","title":"Before installing","text":"","category":"section"},{"location":"10-full-guide/#Things-to-know","page":"Full Guide","title":"Things to know","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"This template is an attempt to provide many best practices to package development. This can be overwhelming, so you might prefer to take it easy at first and install only the fewest amount of new things possible.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Thinking of you, the first optional question in the template is how to deal with the optional questions:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The \"Recommended\" option lets us select the best practices that we like the most. This means \"yes\" to most of the optional answers.\nThe \"Minimum\" option does not add any optional feature. Your package will still be a valid Julia package with a few things that we deem essential (such as online testing, documentation, and CITATION.CFF).","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The \"Minimum\" option is still a step above the bare minimum for a Julia package, so you will still benefit from the template. The \"Recommended\" option adds many features that package maintainers might find useful in the long run, but might be too much at once. Check the Explanation page for more information.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you decide to gradually adopt, do this:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Follow the relevant application section for New or Existing.\nRemember to select the \"Minimum\" optional questions.\nFollow the Update section, change your answer from \"Minimum\" to \"Recommended\" or \"Ask me\".","category":"page"},{"location":"10-full-guide/#Things-to-install","page":"Full Guide","title":"Things to install","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Install a plugin on your editor to use EditorConfig. This will ensure that your editor is configured with important formatting settings.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"We recommend using https://pre-commit.com to run linters and formatters. If you select the \"recommended\" options later on, you will need pre-commit installed. To install pre-commit, we recommend using pipx as follows:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"# Install pipx following the link\npipx install pre-commit","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"In particular, the Julia code is formatted using JuliaFormatter.jl, so please install it globally first:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> # Press ]\npkg> activate\npkg> add JuliaFormatter","category":"page"},{"location":"10-full-guide/#Install-BestieTemplate-(or-copier)","page":"Full Guide","title":"Install BestieTemplate (or copier)","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To use the template, we recommend installing the package BestieTemplate.jl globally:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> # press ]\npkg> activate\npkg> add BestieTemplate","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The BestieTemplate package wraps copier and adds some lightweight checks and parameters to make your user experience better.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Alternative\nAlternatively, you can use copier directly, in which case you will have the pure template generation experience. If that is the case, I will assume that you know what you are doing and won't show the full command here to avoid confusing new users.","category":"page"},{"location":"10-full-guide/#Using-the-template","page":"Full Guide","title":"Using the template","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"There are three use cases on using the template:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You are using the template to start a new package.\nYou already have a Julia project and you want to apply the template to your project.\nYou already uses the template and you want to update to get the latest changes.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The three cases are listed below.","category":"page"},{"location":"10-full-guide/#new_package","page":"Full Guide","title":"New package","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Simply run","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> using BestieTemplate\njulia> BestieTemplate.generate(\"full/path/to/YourPackage.jl\")","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"This will create the folder at the given path and create a package named YourPackage using the latest release of the BestieTemplate. You will be prompted with many questions, some required and some with our recommended choices.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You can give more options to the generate function, including the source of the template, pre-filled data, and options passed to the underlying project generator copier. See the full docstring for BestieTemplate.generate for more information.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The resulting folder will not be a git package yet (to avoid trust issues), so you need to handle that yourself. You should see a short guide on screen, but here it is again:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"cd full/path/to/YourPackage.jl\ngit init\ngit add .\npre-commit run -a # Try to fix possible pre-commit issues (failures are expected)\ngit add .\ngit commit -m \"First commit\"\npre-commit install # Future commits can't be directly to main unless you use -n","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Now, create a new repository on GitHub and push your code. We won't give you details on how to do this, but you can check The Turing Way.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"After that, jump on to Setting up your package.","category":"page"},{"location":"10-full-guide/#existing_package","page":"Full Guide","title":"Applying to an existing package","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To apply the template to an existing package, you can do the following:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: git\nThis assumes that you already use git on that package and the your working directory is clean. It will fail otherwise.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> using BestieTemplate\njulia> BestieTemplate.apply(\"full/path/to/YourPackage.jl\")","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"This will look for a file Project.toml at the root of the given path and use the information there to guess some of the answers. Currently, we guess the PackageName, PackageUUID from the name and uuid fields, and try to guess the AuthorName and AuthorEmail from the authors field by looking at the first match.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"tip: Overwrite\nYou will be asked whether to overwrite existing files or not. Since you are using git, you can try it out and reset if you don't like the result.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you don't like the result, or want to override the answers, you can run the apply function with additional arguments:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> data = Dict(\"AuthorName\" => \"Bob\", \"AuthorEmail\" => \"bob@bob.br\")\njulia> BestieTemplate.apply(\"full/path/to/YourPackage.jl\", data)","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"See the full docstring for BestieTemplate.apply for more information.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You will most likely have conflicts when you apply the template. Whenever a conflict appears, you will need to decide on whether to accept or reject the new changes. Unfortunately, they are not shown to you when the conflict appears, so the best solution is to just accept all of them and then fix the conflicts using git.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Review the changes\nDon't just add the changes blindly, because some of your files can and will be overwritten.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: README.md conflicts\nWe really can't avoid some conflicts, and although some file can be skipped if existing (such as CITATION.cff), some can't. For instance, README.md will most likely be wrong when you apply the template, but the badges (for instance), need to be included in your project. This means that README.md cannot be skipped, and you will have to accept the overwrite and manually fix your README.md.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"tip: Formatting\nYou might most likely see changes in the formatting. So if you have are a formatter, it might be best to run it before reviewing the changes. If you have chosen the \"Recommended\" answers, or explicitly chose to add pre-commit, then you should use it now (see below).","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you need some help with undoing some of these changes, I recommend using a graphical interface. After the template is applied and you are happy with the conflict resolution, enable pre-commit and push your code.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"git add .\npre-commit run -a # Try to fix possible pre-commit issues (failures are expected)\npre-commit install # All commits will run pre-commit now\ngit add .\ngit commit -m \"Apply BestieTemplate vx.y.z\"","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Push your code to GitHub and head to Setting up your package for information on what to do next.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Now, go to Setting up your package to check what you still need to configure for your package.","category":"page"},{"location":"10-full-guide/#updating_package","page":"Full Guide","title":"Updating","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"To update the package, simply call","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"julia> BestieTemplate.update()","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You will be asked the relevant questions of the package as if you had applied it. The big differences are:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"It will only apply the things that are new since you last applied/updated\nIt will remember previous answer.\nIt will overwrite without asking.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"tip: Change previous answers\nYou can change your previous answers. In other words, if you though something was not mature enough in the past, but you are more confident in that now, you can adopt it now. This works even if the template was not updated itself.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"As with the first application, you need to run pre-commit run -a to fix the unavoidable linting and formatting issues. Check the modifications in the relevant linter and formatting files, if you changed them manually, before doing it, though.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"pre-commit run -a","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The underlying package copier will use git to apply the differences and it will overwrite whatever files it finds in the way. Since git is mandatory, the changes will be left for you to review.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Review the changes\nI repeat, the changes will be left for you to review. Don't just add them blindly, because some of your modifications can and will be overwritten.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you need some help with undoing some of these changes, I recommend using a graphical interface.","category":"page"},{"location":"10-full-guide/#Setting-up-your-package","page":"Full Guide","title":"Setting up your package","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"There are various steps to setting up your package on GitHub. Some are important now, and some will be relevant when you try to make your first release.","category":"page"},{"location":"10-full-guide/#Add-to-GitHub","page":"Full Guide","title":"Add to GitHub","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you haven't yet, create a repo on GitHub and push your code to it.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"info: Info\nThe actions will run and you will see errors in the documentation and linting. Do not despair.","category":"page"},{"location":"10-full-guide/#Documentation","page":"Full Guide","title":"Documentation","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Go to your package setting on Github and find the \"Actions\" tab, the \"General\" link. On that page, find the \"Workflow permissions\" and change the selection to \"Read and write permissions\", and enable \"Allow GitHub Actions can create and approve pull requests\". This will allow the documentation workflow to work for development.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Go to the Actions page, click the failing Docs workflow and click on \"re-run all jobs\". It should pass now.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Now, go to your package setting on GitHub and find the \"Pages\" link. You should see an option to set the Source to \"Deploy from a branch\", and select the branch to be \"gh-pages\" and to deploy from the \"/ (root)\".","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"After circa 1 minute, you can check that the documentation was built properly.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"info: Info\nAt this point, you should have passing workflows.Tests should have been passing from the start.\nLint was fixed when we pushed the code to GitHub.\nDocs was fixed with the permissions change.","category":"page"},{"location":"10-full-guide/#Documentation-for-releases","page":"Full Guide","title":"Documentation for releases","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"info: Info\nThis section is only relevant when making your first release, but it might be better to get it out of the way now.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You need to set a DOCUMENTER_KEY to build the documentation from the tags automatically when using TagBot (which we do by default). Do the following:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"pkg> activate --temp\npkg> add DocumenterTools\njulia> using DocumenterTools\njulia> DocumenterTools.genkeys(user=\"UserName\", repo=\"PackageName.jl\")","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Follow the instruction in the terminal.","category":"page"},{"location":"10-full-guide/#Enable-Codecov-for-code-coverage","page":"Full Guide","title":"Enable Codecov for code coverage","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you don't have a Codecov account, go to https://codecov.io and create one now. After creating an account and logging in, you will see your main page with a list of your packages. Select the one that you are creating, it will open a configuration page.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"On the configuration page, select \"Using GitHub Actions\" as your CI. The first step in the list given you the CODECOV_TOKEN. Click on the \"repository secret\" link on that page. It should lead you to the GitHub settings > secrets and variables > actions, under a \"New secret\" screen. Write CODECOV_TOKEN on the \"Name\" field and paste the token that you see on codecov on the \"Secret\" field. Click \"Add secret\".","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Step 2 is not necessary because it is already present in the template.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"The next time that the tests are run, the coverage page will be updated, and the badge will be fixed.","category":"page"},{"location":"10-full-guide/#Add-key-for-Copier.yml-workflow","page":"Full Guide","title":"Add key for Copier.yml workflow","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Copier.yml is work in progress\nThis option is not selected by default because it is a work in progress. If you want to use it, you have to pass the key \"AddCopierCI\" => true to the data argument of generate or apply, or select \"Ask me\" when deciding how to answer the optional questions.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"You can reapply the template in the future. This is normally a manual job, specially because normally there are conflicts. That being said, we are experimenting with having a workflow that automatically checks whether there are updates to the template and reapplies it. A Pull Request is created with the result.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"warning: Warning\nThis is optional, and in development, so you might want to delete the workflow instead.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"If you decide to use, here are the steps to set it up:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Create a Personal Access Token to be used by the Copier workflow.\nGo to https://github.com/settings/tokens.\nCreate a token with \"Content\", \"Pull-request\", and \"Workflows\" permissions.\nCopy the Token.\nGo to your YOUR_PACKAGE_URL/settings/secrets/actions.\nCreate a \"New repository secret\" named COPIER_PAT.","category":"page"},{"location":"10-full-guide/#CITATION.cff-and-Zenodo-deposition","page":"Full Guide","title":"CITATION.cff and Zenodo deposition","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Update your CITATION.cff file with correct information. You can use cffinit to generate it easily.","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Before releasing, enable Zenodo integration at https://zenodo.org/account/settings/github/ to automatically generate a deposition of your package, i.e., archive a version on Zenodo and generate a DOI.","category":"page"},{"location":"10-full-guide/#Update-README.md","page":"Full Guide","title":"Update README.md","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Update the badges\nAdd a description","category":"page"},{"location":"10-full-guide/#Enable-discussions","page":"Full Guide","title":"Enable discussions","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Enable GitHub discussions.","category":"page"},{"location":"10-full-guide/#First-release","page":"Full Guide","title":"First release","text":"","category":"section"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"When you are ready to make your first release, enable the Julia Registrator bot. Make sure that you haven't skipped these sections:","category":"page"},{"location":"10-full-guide/","page":"Full Guide","title":"Full Guide","text":"Documentation for releases\nCITATION.cff and Zenodo deposition","category":"page"}] }