---
title: "Hello world!"
linkTitle: "Hello world!"
weight: 1
date: 2017-01-04
description: >
  Everything starts from an "Hello!"
---

This article will guide you to build your first package with Luet! 
For this purpose, we have picked a real-world example: [gogs](https://github.com/gogs/gogs) which is a "painless self-hosted Git service", an open-source alternative to Github.

Gogs is written in Golang, and we need a working Golang version in order to build it.

Here you can see a live recorded session of this tutorial:
<script id="asciicast-388348" src="https://asciinema.org/a/388348.js" data-autoplay="true" data-size="small" data-cols="120" data-rows="40" async></script>


# Define a Luet tree

Everything starts from a Luet tree. A Luet tree is just a directory containing one (or more) Luet specfile, here on we assume that you are working in a dedicated folder (e.g. `~/demo`) in your system.

Let's create then a package that will be our base to build other packages from now on, we have picked `busybox` here - it is really small and enough for our purpose.

## busybox

```bash
mkdir busybox
```

Let's now write the build specification, which is just containing the image tag that we are referencing to

```bash
cat <<EOF > busybox/build.yaml
image: "busybox:{{.Values.version}}-glibc"
EOF
```

Now, lets write the `definition.yaml`, which contains the metadata information about our package ( e.g. how we refer to it with luet, the version, and so on )

```bash
cat <<EOF > busybox/definition.yaml
category: "distro"
name: "busybox"
version: "1.33.0"
EOF
```

## golang

We need now golang in order to build `gogs`. Let's declare then a golang package:

```bash
mkdir golang
```

And a build specfile, which is simply fetch golang from https://golang.org and installing it in the busybox container:
```bash
cat <<EOF > golang/build.yaml
requires:
- category: "distro"
  name: "busybox"
  version: ">=0"

prelude:
- wget https://golang.org/dl/go{{.Values.version}}.linux-{{.Values.arch}}.tar.gz -O golang.tar.gz
- mkdir /usr/local
steps:
- tar -C /usr/local -xzf golang.tar.gz
EOF
```

Note how we `require` busybox. The Golang container will now be based from busybox, and the `prelude` and `steps` fields will be executed in that context.

And finally let's write the golang metadata files, so we can refer to it from other packages
```bash
cat <<EOF > golang/definition.yaml
name: "go"
category: "dev-lang"
version: "1.15.6"
arch: "amd64"
EOF
```

## gogs

Finally we can write the gogs package definition!

```bash
mkdir gogs
```

The build specfile, will just fetch the `gogs` sources at a given version (specified in the `definition.yaml`) and build the sources with go:

```bash
cat <<'EOF' > gogs/build.yaml
requires:
- category: "dev-lang"
  name: "go"
  version: ">=0"
env:
- GOPATH="/go"
- GOGSPATH="$GOPATH/src/github.com/gogs/gogs"
- PATH=$PATH:/usr/local/go/bin
- CGO_ENABLED=0
prelude:
- mkdir -p $GOPATH/src/github.com/gogs
- wget https://github.com/gogs/gogs/archive/v{{.Values.version}}.tar.gz -O - | tar -xzf - -C ./  && mv gogs-{{.Values.version}} $GOGSPATH
steps:
- mkdir /usr/bin
- cd $GOGSPATH && go build && mv gogs /usr/bin/gogs
excludes:
# Cache generated by Golang
- ^/root
EOF
```

And the metadata, in this way we can refer to gogs in a Luet tree:
```bash
cat <<EOF > gogs/definition.yaml
category: "dev-vcs"
name: "gogs"
version: "0.11.91"
EOF
```

# Build packages

The simplest and mostly immediate way to build packages, is running `luet build <packagename>` in the same folder you have your Luet tree.

In this case, to build gogs and its deps, we can do:

```bash
luet build dev-vcs/gogs
```

And that's it! you will find the package archives in `build/` in the same folder where you started the command.

You will see that Luet generates not only archives with the file resulting to your builds, but it will also generate metadata files (ending with `.metadata.yaml`) that contains additional metadata information about your build and the package itself (e.g. checksums).

You can use tools like [yq](https://github.com/mikefarah/yq) to inspect those:

```bash
yq r build/gogs-dev-vcs-0.11.91.metadata.yaml checksums
```

Now if you want to consume the artifacts just built with `luet install`, you can create a repository with `luet create-repo`.