Say Hello To Snug
Chapter 12

Managing Your Snug Project

As your project grows, keep its packaging files together in a predictable place. A simple convention is to create a snug directory at the root of your project:

.\snug\

A typical project might look like this (the built JAR is generated by your Java build tool and is not shown here):

01

02

03

04

05

06

07

08

09

10

my-application\

  ├── build.gradle / build.gradle.kts / pom.xml

  ├── snug.options

  ├── src\

  ├── ...

  └── snug\

    ├── snug.exe

    ├── icon.png

    ├── splash.png

    └── localisations\

Keeping these files together separates your application's source and Snug packaging resources from generated output. The built JAR may be produced in build\libs\ (Gradle) or target\ (Maven); point Snug at its actual location using --input or a positional JAR argument.

What Should Go in the snug Directory?

Typical contents include:

  • snug.exe - the Snug builder
  • icon.png - the application icon, if you use one
  • splash.png - the Snug splash screen, if you use one
  • localisations\ - translated launcher messages, if you use localisation
  • other packaging resources, such as a custom Windows manifest

Keep snug.options and any snug.windows.options overrides in the project root. Open a terminal there and run .\snug\snug.exe: the executable is in the snug subdirectory, but the current working directory remains the project root. Snug looks for its options files and resolves relative paths from that working directory, not from the executable's location. Running Snug elsewhere will not automatically load this project's options files.

The exact filenames are up to you; the important part is consistency.

What Should Be Saved with the Project?

Some files describe how your application should be built and packaged; others are tools or generated output.

Keep the Java source, build instructions, Snug configuration, and project-specific assets with the project. For packaging, this includes snug.options, any snug.windows.options overrides, icons, splash screens, localisation files, and manifests.

If you are using Git, these files should normally be committed to the repository so that the Snug setup is preserved alongside the application source code. Generated JARs, build folders, and finished Windows executables normally do not need to be committed; distribute the finished executable separately, for example through a GitHub release.

Using Git

Git is a version-control system used to keep a history of changes to a project. You do not need Git in order to use Snug, but if you are already using it as part of a larger application project, a useful rule is to keep the files needed to recreate the project rather than every file it produces.

For Snug, this usually means keeping the configuration and assets in Git while making a deliberate choice about the snug.exe binary itself.

Should snug.exe Be Committed?

There are two reasonable approaches, depending on how self-contained you want the project to be.

Keep snug.exe Outside Git

Keep snug.exe locally in the snug directory and exclude it from Git. Add this entry to .gitignore:

/snug/snug.exe

This avoids storing a new copy of the binary in the repository each time Snug is upgraded.

Keep snug.exe in Git

For a small project, committing the exact snug.exe makes it more self-contained: someone cloning it can use the same Snug version without a separate download.

The trade-off is repository size: Git retains historical copies of the binary when it changes.

Neither approach is inherently wrong; the important thing is to know which version of Snug the project expects.

A Practical Starting Point

Use the directory layout above as a starting point: keep the options files and packaging assets with the project, and decide whether to commit snug.exe or download the recorded version when needed.

This preserves the Snug setup without requiring every project-management decision at once.

Reproducible Builds

As a project becomes more important, it helps to be able to recreate a working executable months later. Keep the Java source, build instructions, Snug configuration, assets, and the versions of your build tools together. Here, reproducibility means being able to repeat the build reliably - not a guarantee that two executables will be byte-for-byte identical.

In a short build-notes file, record the exact Snug release, JDK version, and Gradle or Maven version, plus the commands used to build the JAR and run Snug from the project root. Keep build.gradle, build.gradle.kts, or pom.xml, as appropriate, and any build-tool wrapper files with the project. Record where to obtain the chosen Snug binary if it is excluded from Git. Note the expected JAR path and preserve the options files and assets used for each release.

Automating the Build

Once you can repeat the local build from those instructions, you can optionally automate the same steps. You may encounter the term CI/CD: an automated system runs build or release steps for you. Services such as GitHub Actions can run them when a project changes or a release is created.

Snug does not require CI/CD; a normal local build is perfectly valid.

If you do automate a Snug build, use a specific Snug version rather than automatically downloading whatever happens to be the latest release. This helps ensure that the same source and configuration continue to produce predictable results.

A good automated process might:

  • obtain a known version of Snug,
  • build the Java application,
  • run Snug with the project's saved configuration,
  • and keep the resulting executable as a build or release artefact.

The important principle is the same whether the build is manual or automated: keep the instructions for creating the application with the project, and make the versions of the tools deliberate rather than accidental.

Tip: Before you finish, save the source, build instructions, options files, packaging assets, and tool versions. Check that you can rebuild the JAR and run .\snug\snug.exe from the project root. Distribute the finished executable separately; Git and automation remain optional.