Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: loon nix build #54

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ jobs:
uses: cachix/install-nix-action@v10
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Install Cachix
uses: cachix/cachix-action@v6
with:
name: loon
- name: Checkout code
uses: actions/checkout@v2
- name: Build Loon
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/populate-cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
on: [push, pull_request]
name: Populate Cache
jobs:
populate:
name: "${{ matrix.dependency }} (${{ matrix.platform }})"
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest, macos-latest]
dependency: [crystal, golang, memcached, mysql, node, postgresql, redis, ruby]
runs-on: ${{ matrix.platform }}
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.14.x
- name: Install Nix
uses: cachix/install-nix-action@v10
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Install Cachix
uses: cachix/cachix-action@v6
with:
name: loon
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Checkout code
uses: actions/checkout@v2
- name: Build Loon
run: go build
- name: Build dependencies
run: ./loon nix build --all ${{ matrix.dependency }}
20 changes: 10 additions & 10 deletions internal/catalog/bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions internal/catalog/data/mysql/8.0.21.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ loon-mysql-8_0_21 = pkgs.mysql80.overrideAttrs(attrs: {
url = "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.21.tar.gz";
sha256 = "0d00k55rkzdgn5wj32vxankjk5x3ywfqw62zxzg3m503xrg56mmd";
};
patches = [];
buildInputs = [pkgs.boost172] ++ attrs.buildInputs;
});
#{{ end }}

Expand Down
9 changes: 6 additions & 3 deletions internal/catalog/data/ruby/2.6.6.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ loon-ruby-2_6_6 = pkgs.ruby.overrideAttrs(attrs: {
url = "https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz";
sha256 = "364b143def360bac1b74eb56ed60b1a0dca6439b00157ae11ff77d5cd2e92291";
};

buildInputs = attrs.buildInputs ++ [
pkgs.libiconv
pkgs.openssl
pkgs.zlib
];
});
#{{ end }}

#{{ define "packages" }}
loon-ruby-2_6_6
pkgs.libiconv
pkgs.openssl
pkgs.zlib
#{{ end }}
9 changes: 6 additions & 3 deletions internal/catalog/data/ruby/2.7.1.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ loon-ruby-2_7_1 = pkgs.ruby_2_7.overrideAttrs(attrs: {
url = "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.gz";
sha256 = "d418483bdd0000576c1370571121a6eb24582116db0b7bb2005e90e250eae418";
};

buildInputs = attrs.buildInputs ++ [
pkgs.libiconv
pkgs.openssl
pkgs.zlib
];
});
#{{ end }}

#{{ define "packages" }}
loon-ruby-2_7_1
pkgs.libiconv
pkgs.openssl
pkgs.zlib
#{{ end }}
59 changes: 59 additions & 0 deletions internal/cli/nix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package cli

import (
"errors"

"github.com/andremedeiros/loon/internal/nix"
"github.com/urfave/cli/v2"
)

var buildCmd = &cli.Command{
Name: "build",
Usage: "Builds a dependency",
Flags: []cli.Flag{
&cli.BoolFlag{Name: "all", Usage: "Builds all versions of a dependency"},
},
Action: func(c *cli.Context) error {
all := c.Bool("all")
if c.NArg() == 0 {
return errors.New("specify a dependency name")
}
dep := c.Args().Get(0)

if all {
if _, err := nix.PackageFor(dep, "default"); err != nil {
return err
}
for _, pkg := range nix.Packages() {
if pkg.Name != dep {
continue
}

if err := pkg.Build(); err != nil {
return err
}
}
} else {
ver := c.Args().Get(1)
if ver == "" {
ver = "default"
}
pkg, err := nix.PackageFor(dep, ver)
if err != nil {
return err
}
return pkg.Build()
}
return nil
},
}

var nixCmd = &cli.Command{
Name: "nix",
Usage: "Nix toolbox",
Subcommands: []*cli.Command{buildCmd},
}

func init() {
appendCommand(nixCmd)
}
4 changes: 2 additions & 2 deletions internal/nix/derivation.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (d *Derivation) Execute(args []string, opts ...executor.Option) error {
return executor.Execute(cmd, opts...)
}

func (d *Derivation) generate() {
func (d *Derivation) generateShell() {
tmpl := `
{ pkgs ? import <nixpkgs> { } }:
let
Expand Down Expand Up @@ -72,7 +72,7 @@ func (d *Derivation) NeedsUpdate(payloadModified time.Time) bool {
}

func (d *Derivation) Install() error {
d.generate()
d.generateShell()
if err := executor.Execute([]string{"nix-instantiate", d.NixPath, "--indirect", "--add-root", d.DrvPath}); err != nil {
return err
}
Expand Down
37 changes: 37 additions & 0 deletions internal/nix/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package nix
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"text/template"

"github.com/andremedeiros/loon/internal/catalog"
"github.com/andremedeiros/loon/internal/executor"
)

type Package struct {
Expand All @@ -32,6 +35,40 @@ func (p Package) DerivationPackages() string {
return buf.String()
}

func (p Package) Build() error {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The derivation struct uses a pointer receiver. Using the pointer receiver here would be my expectation so you are working with the current value at the address p instead of a copy, particularly since it is used in the file creation.

However, there are caveats to the value of using a pointer which may outweigh its benefit. Here's a good piece by Dave Cheney for deeper insight: https://dave.cheney.net/tag/receivers

Image of Denis R Denis R

tmpl := `
{ pkgs ? import <nixpkgs> { } }:
let
inherit (pkgs) stdenv fetchurl mkShell;
{{ .Derivation }}
in rec {
package =
{{ .DerivationPackages }}
;
}`
buf := bytes.NewBuffer([]byte{})
t, err := template.New("nix").Parse(tmpl)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the current approach using template.Must would be appropriate. As follows:

var t = template.Must(template.New("nix").Parse(tmpl))

Image of Denis R Denis R

if err != nil {
// TODO(andremedeiros): figure out a better way
panic(err)
}
t.Execute(buf, p)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A file is an io.Writer, which you have on the line below. Your code would work as intended without the Buffer, I beleive, if you run t.Execute(f, p)

Image of Denis R Denis R

f, _ := ioutil.TempFile("", "default.nix")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You definitely want to check for an error here, per the documentation: https://golang.org/src/io/ioutil/tempfile.go?h=TempFile#L50

Image of Denis R Denis R

f.Write(buf.Bytes())
f.Close()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ISSUE: G104 (Severity: Medium)
Errors unhandled.

Remediation:
It is expected to check for errors and in this case there is still the matter of execution which happens in the stanza below. If there is an error, should this code attempt to execute?

🤖 powered by PullRequest Automation 👋 verified by Denis R


return executor.Execute([]string{
"nix-build",
f.Name(),
"-A",
"package",
"--no-out-link",
},
executor.WithStdout(os.Stdout),
executor.WithStderr(os.Stderr),
)
}

func PackageFor(name string, version string) (Package, error) {
for _, p := range Packages() {
if p.Name == name && p.Version == version {
Expand Down