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

Added WAPM integration into upm #22

Open
wants to merge 6 commits into
base: main
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
/packaging/aur/pkg/
/packaging/aur/src/
*.gen.go

wapm_packages
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ machine-parseable specfile and lockfile listing.
| ruby-bundler | yes | yes | |
| elisp-cask | yes | yes | yes |
| dart-pub.dev | yes | yes | |
| wasm-wapm | yes | yes | |

## Installation

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ require (
github.com/BurntSushi/toml v0.3.1
github.com/hashicorp/go-version v1.2.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/machinebox/graphql v0.2.2
github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc
github.com/pkg/errors v0.8.1 // indirect
github.com/rakyll/statik v0.1.6
github.com/spf13/cobra v0.0.5
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo=
github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
Expand All @@ -25,6 +27,8 @@ github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc h1:7xGrl4tTpBQu5Z
github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc/go.mod h1:1rLVY/DWf3U6vSZgH16S7pymfrhK2lcUlXjgGglw/lY=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rakyll/statik v0.1.6 h1:uICcfUXpgqtw2VopbIncslhAmE5hwc4g20TEyEENBNs=
github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
Expand Down
2 changes: 2 additions & 0 deletions internal/backends/backends.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/replit/upm/internal/backends/nodejs"
"github.com/replit/upm/internal/backends/python"
"github.com/replit/upm/internal/backends/ruby"
"github.com/replit/upm/internal/backends/wasm"
"github.com/replit/upm/internal/util"
)

Expand All @@ -27,6 +28,7 @@ var languageBackends = []api.LanguageBackend{
ruby.RubyBackend,
elisp.ElispBackend,
dart.DartPubBackend,
wasm.WasmBackend,
}

// matchesLanguage checks if a language backend matches a value for
Expand Down
221 changes: 221 additions & 0 deletions internal/backends/wasm/wasm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// Package wasm provides a backend for Wasm using wapm.
package wasm

import (
"context"
"strings"

"github.com/BurntSushi/toml"
graphql "github.com/machinebox/graphql"
"github.com/replit/upm/internal/api"
"github.com/replit/upm/internal/util"
)

type wapmPackage struct {
Name string `json:"name"`
}

type wapmUser struct {
Username string `json:"username"`
}

type wapmPackageVersion struct {
Version string `json:"version"`
Description string `json:"description"`
Homepage string `json:"homepage"`
Repository string `json:"repository"`
License string `json:"license"`
PublishedBy wapmUser `json:"publishedBy"`
Package wapmPackage `json:"package"`
}

type infoQuery struct {
PackageVersion wapmPackageVersion `json:"packageVersion"`
}

type searchQuery struct {
Search struct {
Edges []struct {
Node wapmPackageVersion `json:"node"`
} `json:"edges"`
} `json:"search"`
}

// wapmTOML represents the relevant parts of a wapm.toml
// file.
type wapmTOML struct {
Package struct {
Name string `json:"name"`
} `json:"package"`
Dependencies map[string]string `json:"dependencies"`
}

// wapmLock represents the relevant parts of a wapm.lock file, in
// TOML format.
type wapmLock struct {
Modules map[string]map[string]interface{} `json:"modules"`
// ^ package ^ version
}

// WasmBackend is a UPM language backend for Wasm using WAPM.
var WasmBackend = api.LanguageBackend{
Name: "wasm-wapm",
Specfile: "wapm.toml",
Lockfile: "wapm.lock",
FilenamePatterns: []string{"*.wasm"},
Quirks: api.QuirksLockAlsoInstalls,
GetPackageDir: func() string {
path := string(util.GetCmdOutput([]string{"wapm", "bin"}))
path = strings.TrimSuffix(path, "\n")
path = strings.TrimSuffix(path, "/.bin")
if path == "" {
return "wapm_packages"
}
return path
},
Search: func(query string) []api.PkgInfo {
client := graphql.NewClient("https://registry.wapm.io/graphql")
req := graphql.NewRequest(`
query searchPackages($query: String!) {
search(query: $query) {
edges {
node {
...on PackageVersion {
package {
name
}
version
description
homepage
repository
license
publishedBy {
username
}
}
}
}
}
}
`)
// set any variables
req.Var("query", string(query))
ctx := context.Background()

var search searchQuery
if err := client.Run(ctx, req, &search); err != nil {
util.Die("WAPM response: %s", err)
}

results := []api.PkgInfo{}
for _, edge := range search.Search.Edges {
results = append(results, api.PkgInfo{
Name: edge.Node.Package.Name,
Description: edge.Node.Description,
Version: edge.Node.Version,
HomepageURL: edge.Node.Homepage,
Author: edge.Node.PublishedBy.Username,
License: edge.Node.License,
})
}
return results
},
Info: func(name api.PkgName) api.PkgInfo {
client := graphql.NewClient("https://registry.wapm.io/graphql")
req := graphql.NewRequest(`
query getPackage($name: String!) {
packageVersion: getPackageVersion(name: $name) {
package {
name
}
version
description
homepage
repository
license
publishedBy {
username
}
}
}
`)
// set any variables
req.Var("name", string(name))
ctx := context.Background()

var output infoQuery
if err := client.Run(ctx, req, &output); err != nil {
util.Die("WAPM response: %s", err)
}

return api.PkgInfo{
Name: output.PackageVersion.Package.Name,
Description: output.PackageVersion.Description,
Version: output.PackageVersion.Version,
HomepageURL: output.PackageVersion.Homepage,
Author: output.PackageVersion.PublishedBy.Username,
License: output.PackageVersion.License,
}
},
Add: func(pkgs map[api.PkgName]api.PkgSpec) {
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
if !util.Exists("wapm.toml") {
util.RunCmd([]string{"wapm", "init", "-y"})
}
cmd := []string{"wapm", "add"}
for name, spec := range pkgs {
arg := string(name)
if spec != "" {
arg += "@" + string(spec)
}
cmd = append(cmd, arg)
}
util.RunCmd(cmd)
},
Remove: func(pkgs map[api.PkgName]bool) {
cmd := []string{"wapm", "remove"}
for name := range pkgs {
cmd = append(cmd, string(name))
}
util.RunCmd(cmd)
},
Lock: func() {
util.RunCmd([]string{"wapm", "install", "-y"})
},
Install: func() {
util.RunCmd([]string{"wapm", "install", "-y"})
Copy link

Choose a reason for hiding this comment

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

I noticed Lock uses wapm install and Install uses wapm install -y. What's the difference? I don't see it mentioned in the docs.

Copy link
Author

Choose a reason for hiding this comment

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

wapm install -y automatically accepts certificates for signed packages when installing them (and any other input requested from the user).

Copy link

Choose a reason for hiding this comment

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

sounds like we want wapm install -y in both cases then

Copy link
Author

Choose a reason for hiding this comment

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

@turbio sounds good! I just updated the PR :)

},
ListSpecfile: func() map[api.PkgName]api.PkgSpec {
var cfg wapmTOML
if _, err := toml.DecodeFile("wapm.toml", &cfg); err != nil {
util.Die("%s", err.Error())
}
pkgs := map[api.PkgName]api.PkgSpec{}
for nameStr, specStr := range cfg.Dependencies {
if specStr == "" {
continue
}
pkgs[api.PkgName(nameStr)] = api.PkgSpec(specStr)
}

return pkgs
},
ListLockfile: func() map[api.PkgName]api.PkgVersion {
var cfg wapmLock
if _, err := toml.DecodeFile("wapm.lock", &cfg); err != nil {
util.Die("%s", err.Error())
}
pkgs := map[api.PkgName]api.PkgVersion{}
for pkgName, pkgObj := range cfg.Modules {
for pkgVersion := range pkgObj {
name := api.PkgName(pkgName)
version := api.PkgVersion(pkgVersion)
pkgs[name] = version
}
}
return pkgs
},
Guess: func() (map[api.PkgName]bool, bool) {
util.NotImplemented()
panic("unreachable code")
},
}
11 changes: 11 additions & 0 deletions scripts/docker-install-languages.bash
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ pip3 --disable-pip-version-check install poetry
curl -fsSL https://raw.githubusercontent.com/cask/cask/master/go | python3
ln -s "$HOME/.cask/bin/cask" /usr/local/bin/

# Install Wasmer/WAPM
curl https://github.com/wasmerio/wasmer/releases/download/0.10.1/wasmer-linux-amd64.tar.gz -o /tmp/wasmer.tar.gz
mkdir /usr/local/wasmer
tar -xvf /tmp/wasmer.tar.gz -C /usr/local/wasmer --strip-components=1
ln -s /usr/local/wasmer/wasmer /usr/local/bin/wasmer
ln -s /usr/local/wasmer/wapm /usr/local/bin/wapm
rm /tmp/wasmer.tar.gz

ln -s "$HOME/.wasmer/bin/wasmer" /usr/local/bin/
ln -s "$HOME/.wasmer/bin/wapm" /usr/local/bin/

# https://github.com/docker-library/rails/issues/10#issuecomment-169957222
bundle config --global silence_root_warning 1

Expand Down