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

Support build under wasm and/or js #304

Closed
wants to merge 1 commit into from

Conversation

paralin
Copy link

@paralin paralin commented Apr 19, 2021

Fixes the following build error under GOOS=js GOARCH=wasm go build -v:

package github.com/go-git/go-git/v5        
        imports github.com/go-git/go-billy/v5/osfs
        imports golang.org/x/sys/unix: build constraints exclude all Go files in /home/paralin/go/pkg/mod/golang.org/x/sys@v0.0.0-20200302150141-5c8b2ff67527/unix

Signed-off-by: Christian Stewart <christian@paral.in>
@paralin
Copy link
Author

paralin commented Apr 19, 2021

image

@mcuadros
Copy link
Member

Will be better if you submit the fix to go-billy instead of replace it with your fork.

@paralin
Copy link
Author

paralin commented Apr 19, 2021

@mcuadros go-git/go-billy#15

The line can be deleted once this is merged

@mcuadros
Copy link
Member

After an intensive reach, sadly is not just easy as replace one package to make work properly go-git with wasm. Maybe clone works, but many other functionally doesn't. The current results of running the root package test suites are:

OOPS: 136 passed, 135 FAILED, 1 PANICKED, 11 MISSED

I am working on this branch to try to get go-git fully compatible with wasm:
https://github.com/go-git/go-git/tree/wasm

@paralin
Copy link
Author

paralin commented Apr 26, 2021

@mcuadros Thanks for looking into this. What is it about wasm that is causing the difference in behavior?

@mcuadros
Copy link
Member

In your example, you execute a very small part of the go-git dataset. The tests are using os.Mkdir and some other not implemented functions. As well some parts of the code are using call directly to some not implemented functions. So I am fixing every test and functionality. Anyways its good to have better test suites, so...

BTW is a pitty goland doesn't use wasi.

@paralin
Copy link
Author

paralin commented Apr 26, 2021

So, the tests are broken, but the actual go-git functionality might not be?

Which calls are making to not implemented funcs in non test code?

I'm interested to see what the differences are here with webassembly. Yes, if the tests call os.mkdir it won't work. But which part of the non-test code is broken?

@mcuadros
Copy link
Member

mcuadros commented Apr 26, 2021

Many changes are required and the transports are really limited.
BTW can you share the code that generated the output you pasted?

@paralin
Copy link
Author

paralin commented Apr 26, 2021

@mcuadros The transport limit makes sense, but what other changes are required to get it to work? I'm just wondering what it is about webassembly that would cause things to not work.

The only issue I saw was the CORS issue - GitHub doesn't set cross-origin headers, so it was necessary to clone from a localhost IP address with CORS set.

// RunCloneExample attempts to perform a clone demo into the given interfaces.
func RunCloneExample(
	ctx context.Context,
	le *logrus.Entry,
	url string,
	storage storage.Storer,
	worktree billy.Filesystem,
) error {
	cloneOpts := &git.CloneOptions{
		// The (possibly remote) repository URL to clone from.
		URL: url,
		// Auth credentials, if required, to use with the remote repository.
		// Auth transport.AuthMethod
		// Name of the remote to be added, by default `origin`.
		// RemoteName string
		// Remote branch to clone.
		// ReferenceName plumbing.ReferenceName
		// Fetch only ReferenceName if true.
		// SingleBranch bool
		// No checkout of HEAD after clone if true.
		// NoCheckout bool
		// Limit fetching to the specified number of commits.
		// Depth int
		// RecurseSubmodules after the clone is created, initialize all submodules
		// within, using their default settings. This option is ignored if the
		// cloned repository does not have a worktree.
		// RecurseSubmodules SubmoduleRescursivity
		// Progress is where the human readable information sent by the server is
		// stored, if nil nothing is stored and the capability (if supported)
		// no-progress, is sent to the server to avoid send this information.
		Progress: os.Stdout,
		// Tags describe how the tags will be fetched from the remote repository,
		// by default is AllTags.
		// Tags TagMode
	}
	repo, err := git.CloneContext(
		ctx,
		storage,
		worktree,
		cloneOpts,
	)
	if err != nil {
		return err
	}
	le.Info("cloned")
	_ = repo

	files, err := worktree.ReadDir("")
	if err != nil {
		return err
	}
	for _, f := range files {
		le.Debugf(
			"%v %s",
			f.Mode().String(),
			f.Name(),
		)
	}
	return nil
}

I can make a full reproduction if it would be helpful.

@mcuadros
Copy link
Member

Ohh, I see, that's why didn't work for me. Because of the CORS, this is a problem.

As I said the changes are mainly on the test, but for example, some packages are using user.Current for get the home or using or accessing config files without billy.

https://github.com/go-git/go-git/commits/wasm

@mcuadros
Copy link
Member

I was able to clone a repository using this script as a proxy:

http://localhost:8081/?https://github.com/go-git/go-git.git

package main

import (
	"io"
	"net/http"
	"net/url"

	"github.com/rs/cors"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		url, err := url.Parse(r.URL.RawQuery)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		req := &http.Request{
			URL:    url,
			Method: r.Method,
			Body:   r.Body,
			Header: r.Header,
		}

		resp, err := http.DefaultTransport.RoundTrip(req)
		if err != nil {
			http.Error(w, err.Error(), http.StatusServiceUnavailable)
			return
		}

		defer resp.Body.Close()

		w.WriteHeader(resp.StatusCode)
		io.Copy(w, resp.Body)
	})

	handler := cors.New(cors.Options{
		AllowedOrigins: []string{"*"},
		AllowedHeaders: []string{"*"},
		Debug:          true,
	}).Handler(mux)
	http.ListenAndServe(":8081", handler)
}

@paralin
Copy link
Author

paralin commented Apr 27, 2021

Nice, yeah, it seems to work. Have you tried the other functionality like checkouts and merges? I'm pretty sure it should work fine. Of course, the test suite is important too.

@paralin
Copy link
Author

paralin commented Apr 28, 2021

@mcuadros Discovered this parallel effort in js today: https://github.com/isomorphic-git/isomorphic-git - they also mention the same CORS issue with GitHub and are trying to campaign them to add the headers.

@mcuadros
Copy link
Member

mcuadros commented May 4, 2021

With the latest changes on master your test code should run without any problems. I will work to create an example to document the usage under wasm to complete this effort.

@mcuadros mcuadros closed this May 4, 2021
@paralin
Copy link
Author

paralin commented May 5, 2021

@mcuadros Thanks for that!

@SaicharanKandukuri
Copy link

SaicharanKandukuri commented Mar 4, 2023

@mcuadros / @paralin trying to test out git-go in wasm

where can i find an wasm example for a simple clone

With the latest changes on master your test code should run without any problems. I will work to create an example to document the usage under wasm to complete this effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants