Git Product home page Git Product logo

gvm's Introduction

gvm

gvm is a Go version manager. gvm installs a Go version and prints the commands to configure your environment to use it. gvm can install Go binary versions from https://storage.googleapis.com/golang or build it from source. Below are examples for common shells.

bash:

eval "$(gvm 1.22.2)"

cmd.exe (for batch scripts %i should be substituted with %%i):

FOR /f "tokens=*" %i IN ('"gvm.exe" 1.22.2') DO %i

powershell:

gvm --format=powershell 1.22.2 | Invoke-Expression

gvm flags can be set via environment variables by setting GVM_<flag>. For example --http-timeout can be set via GVM_HTTP_TIMEOUT=10m.

Installation

You can download a binary release of gvm for your specific platform from the releases page. Then just put the binary in your PATH and mark it as executable (chmod +x gvm).

You must adjust the version and platform info in URLs accordingly.

Linux (amd64):

# Linux Example (assumes ~/bin is in PATH).
curl -sL -o ~/bin/gvm https://github.com/andrewkroh/gvm/releases/download/v0.5.2/gvm-linux-amd64
chmod +x ~/bin/gvm
eval "$(gvm 1.22.2)"
go version

Linux (arm64):

# Linux Example (assumes ~/bin is in PATH).
curl -sL -o ~/bin/gvm https://github.com/andrewkroh/gvm/releases/download/v0.5.2/gvm-linux-arm64
chmod +x ~/bin/gvm
eval "$(gvm 1.22.2)"
go version

macOS (universal):

# macOS Example
curl -sL -o /usr/local/bin/gvm https://github.com/andrewkroh/gvm/releases/download/v0.5.2/gvm-darwin-all
chmod +x /usr/local/bin/gvm
eval "$(gvm 1.22.2)"
go version

Windows (PowerShell):

[Net.ServicePointManager]::SecurityProtocol = "tls12"
Invoke-WebRequest -URI https://github.com/andrewkroh/gvm/releases/download/v0.5.2/gvm-windows-amd64.exe -Outfile C:\Windows\System32\gvm.exe
gvm --format=powershell 1.22.2 | Invoke-Expression
go version

Fish Shell:

Use gvm with fish shell by executing gvm 1.22.2 | source in lieu of using eval.

For existing Go users:

go install github.com/andrewkroh/gvm/cmd/[email protected]

gvm's People

Contributors

andrewkroh avatar andrewvc avatar dependabot[bot] avatar dliappis avatar graphaelli avatar keetraxx avatar ph avatar watson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

gvm's Issues

Cannot use gvm in Ubuntu 20 in Google Cloud

Hi! ๐Ÿ‘‹ I'm not able to use GVM in Ubuntu-20.04 running on GCE

Steps to reproduce

Create a Ubuntu-20.04 instance on Google Cloud, then use the install scripts provided in README

export GVM_VERSION=0.3.2
mkdir -p ~/bin
curl -sL -o ~/bin/gvm https://github.com/andrewkroh/gvm/releases/download/v${GVM_VERSION}/gvm-linux-amd64
chmod +x ~/bin/gvm
PATH="$PATH:~/bin"
gvm v1.17
gvm: error: strconv.ParseBool: parsing "0.3.2": invalid syntax
gvm v1.17.6
gvm: error: strconv.ParseBool: parsing "0.3.2": invalid syntax
gvm 1.17.6
gvm: error: strconv.ParseBool: parsing "0.3.2": invalid syntax

Expected behaviour: GVM installs Go without errors
Current behaviour: GVM fails with a ParseBool error

Add newer versions of Go (e.g. 1.17.2, 1.16.9)

I am still using Go 1.16.6 since this seems to be the newest stable Go release available via gvm.
I would love to switch to a more recent (and more secure) version.
For me this is the main reason to use a tool like gvm at all.

build failing

I can do go get -u github.com/andrewkroh/gvm/cmd/gvm and it works.

GO111MODULE=on go get -u github.com/andrewkroh/gvm/cmd/gvm
go: finding github.com/andrewkroh/gvm/cmd/gvm latest
go: finding github.com/andrewkroh/gvm/cmd latest
go: finding github.com/alecthomas/template latest
go: finding github.com/alecthomas/units latest
go: finding golang.org/x/sys latest
go: downloading github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4
go: downloading github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
go: extracting github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4
go: extracting github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751

But i cant do a build the normal way, it fails to see the Commands at compile time. Any ideas ?

cd /Users/apple/workspace/go/src/github.com/andrewkroh/gvm && GO111MODULE=on go build -o /Users/apple/workspace/go/bin/gvm /Users/apple/workspace/go/src/github.com/andrewkroh/gvm/cmd/gvm/gvm.go
# command-line-arguments
cmd/gvm/gvm.go:57:10: undefined: useCommand
cmd/gvm/gvm.go:59:10: undefined: initCommand
cmd/gvm/gvm.go:60:10: undefined: installCommand
cmd/gvm/gvm.go:61:10: undefined: availCommand
cmd/gvm/gvm.go:62:10: undefined: listCommand
cmd/gvm/gvm.go:63:10: undefined: removeCommand
cmd/gvm/gvm.go:64:10: undefined: purgeCommand

Default path for .go-version file

Currently to select a go version defined in a file, the following command is needed: gvm use $(cat .go-version). This might not necessarily work on all OS. It would be convenient to have something similar to nvm use which automatically picks a version on a predefined file name.

I was initially thinking of going with .go-version but as there might be other gvm configs in the future, perhaps .gvm would be better. An inside it could be yaml and something like:

version: 1.11.3

GOROOT is not required after Go 1.9

The command does not need to output the GOROOT environment variable when working with Go 1.9 and later.

This could probably be safely removed. But if users switch between from a pre-Go 1.9 version to a post 1.9 version, then the shell output would need to unset GOROOT.

GVM cannot install 1.21

Go version 1.21 has been released, but unlike previous versions the file that needs to be downloaded is 1.21.0. This means both gvm install 1.21 and gvm install 1.21.0 fail for different reasons; the former due to no file being found and the latter due to it being an invalid version.

A workaround is to manually perform the following:

cd ~/.gvm/versions
curl https://storage.googleapis.com/golang/go1.21.0.darwin-arm64.tar.gz
tar -xzf go1.21.0.darwin-arm64.tar.gz
# note this is 1.21 NOT 1.21.0 in this spot
mv go go1.21.darwin.arm64

A good fix might be, in the case of minor releases, to check both x.y and x.y.0 as downloads to be robust against future changes either way from the go team.

Ability to permanently set environment variables

As far as I can tell based off of usage, this application does not permanently set environment variables after exiting shell environment - on Windows, anyways. I suggest using penv for this. Specifically, in use.go, we could modify lines 68-70 to include SetEnv from penv. I'm struggling to understand the entirety of the use.go file (new to go) but if I knew how to build, I think I could write a prototype for code review.

A few suggestions...

Hi, I'm using gvm for Windows, so, not sure how you will deal with the differences between OS's...
But, may I suggest a different approach for this tool?

Here: https://github.com/coreybutler/nvm-windows#whats-the-big-difference

They use a symlink to change the version of node "on the fly", so you don't need to restart your program to change the environment variables. Just change the symlink and done!

Also, there are some commands that may be helpful, like the "nvm use"...
Which I think you can bring to here, it will be really interesting.

This should be interesting too:
coreybutler/nvm-windows#214

I think you can grab a lot of good ideas from here too:
https://github.com/danielkermode/gvm

As I said, those are just a few suggestions.

[]'s

Unable to install Go 1.21.0 with gvm

Go 1.21.0 was released earlier this week.

I'm having issues installing it with gvm.

$ sw_vers
ProductName:	macOS
ProductVersion:	12.6.8
BuildVersion:	21G725
$ gvm --version
v0.5.0
$ eval $(gvm 1.21.0)
gvm: error: unknown version 1.21

I'm having a similar issue on Ubuntu 22.04.3.

support use other download url

For some reason I'm not able to reach the default site https://golang.org, but https://golang.google.cn is ok.

 # gvm install go1.14.9
[g] URL "https://golang.org/dl/" is unreachable ==> Get https://golang.org/dl/: EOF

So is it possible to set the download url BEFORE install ?

Exception on Windows when running gvm available or gvm install

Hello,

I am getting this strange error when trying to install new version of go:

OS: Windows
shell: Powerhell 7.0.3 (same issue in powershell 5.1)

> gvm install 1.15.3
Installing go-1.15.3. Please wait...
DEBU[0000] downloading file                              package=common url="https://storage.googleapis.com/golang/go1.15.3.windows-amd64.zip"
Exception 0xc0000005 0x0 0x7fffcd632fff 0x14f0000
PC=0x14f0000

syscall.Syscall6(0x7fffcc645b20, 0x4, 0xc04200a330, 0x0, 0xc04215ff88, 0xc04215fe80, 0x0, 0x0, 0x0, 0x0, ...)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/runtime/syscall_windows.go:184 +0xfc
syscall.GetAddrInfoW(0xc04200a330, 0x0, 0xc04215ff88, 0xc04215fe80, 0x0, 0x0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/syscall/zsyscall_windows.go:1717 +0xc1
net.(*Resolver).lookupIP.func1(0xc042050c20, 0x16, 0xc0420423c0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/lookup_windows.go:96 +0x106
created by net.(*Resolver).lookupIP
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/lookup_windows.go:87 +0x93

goroutine 1 [select]:
net/http.(*Transport).getConn(0xa0e080, 0xc042144360, 0x0, 0xc04207c6c0, 0x5, 0xc042050c20, 0x1a, 0x0, 0x0, 0xc0420712e8)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:962 +0x55f
net/http.(*Transport).RoundTrip(0xa0e080, 0xc04215a100, 0xa0e080, 0xbfdfd069dbc76d64, 0x29ecf2e599)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:409 +0x639
net/http.send(0xc04215a000, 0x8340e0, 0xa0e080, 0xbfdfd069dbc76d64, 0x29ecf2e599, 0xa13b20, 0xc042074250, 0xbfdfd069dbc76d64, 0xc0420715e0, 0x1)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/client.go:252 +0x18c
net/http.(*Client).send(0xc0421441b0, 0xc04215a000, 0xbfdfd069dbc76d64, 0x29ecf2e599, 0xa13b20, 0xc042074250, 0x0, 0x1, 0x4106cf)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/client.go:176 +0x101
net/http.(*Client).Do(0xc0421441b0, 0xc04215a000, 0xc04207c6c0, 0x40, 0x0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/client.go:615 +0x294
net/http.(*Client).Get(0xc0421441b0, 0xc04207c6c0, 0x40, 0xc042158000, 0xaa, 0x6)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/client.go:396 +0xa4
github.com/andrewkroh/gvm/common.downloadFile(0xc04207c6c0, 0x40, 0xc042066140, 0x41, 0x0, 0x0, 0x0, 0x0, 0xa08600)
        /home/travis/gopath/src/github.com/andrewkroh/gvm/common/common.go:36 +0xbe
github.com/andrewkroh/gvm/common.DownloadFile(0xc04207c6c0, 0x40, 0xc042066140, 0x41, 0x5, 0xc04207c6c0, 0x40, 0x0)
        /home/travis/gopath/src/github.com/andrewkroh/gvm/common/common.go:22 +0x23c
github.com/andrewkroh/gvm.(*Manager).installBinary(0xc042122090, 0xc0420eace0, 0x0, 0x0, 0x0, 0x0)
        /home/travis/gopath/src/github.com/andrewkroh/gvm/binrepo.go:35 +0x299
github.com/andrewkroh/gvm.(*Manager).Install(0xc042122090, 0xc0420eace0, 0xc042071c58, 0x1, 0x1, 0x25)
        /home/travis/gopath/src/github.com/andrewkroh/gvm/gvm.go:213 +0x11b
main.installCommand.func1(0xc042122090, 0x0, 0x0)
        /home/travis/gopath/src/github.com/andrewkroh/gvm/cmd/gvm/install.go:40 +0x3e6
main.main()
        /home/travis/gopath/src/github.com/andrewkroh/gvm/cmd/gvm/gvm.go:100 +0xe7a

goroutine 19 [select]:
net/http.setRequestCancel.func3(0x0, 0xc0421442a0, 0xc04209a730, 0xc042052e0c, 0xc042044180)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/client.go:323 +0x101
created by net/http.setRequestCancel
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/client.go:322 +0x2b3

goroutine 20 [select]:
net.(*Resolver).LookupIPAddr(0xa12a70, 0x8377a0, 0xc042042240, 0xc042050c20, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/lookup.go:212 +0x514
net.(*Resolver).internetAddrList(0xa12a70, 0x8377a0, 0xc042042240, 0x7ec3ca, 0x3, 0xc042050c20, 0x1a, 0x0, 0x0, 0x0, ...)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/ipsock.go:293 +0x5cb
net.(*Resolver).resolveAddrList(0xa12a70, 0x8377a0, 0xc042042240, 0x7ec749, 0x4, 0x7ec3ca, 0x3, 0xc042050c20, 0x1a, 0x0, ...)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/dial.go:193 +0x513
net.(*Dialer).DialContext(0xc042100060, 0x837760, 0xc042052098, 0x7ec3ca, 0x3, 0xc042050c20, 0x1a, 0x0, 0x0, 0x0, ...)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/dial.go:375 +0x232
net.(*Dialer).DialContext-fm(0x837760, 0xc042052098, 0x7ec3ca, 0x3, 0xc042050c20, 0x1a, 0x402edd, 0x6121a0, 0xc042052098, 0x784200)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:46 +0x7a
net/http.(*Transport).dial(0xa0e080, 0x837760, 0xc042052098, 0x7ec3ca, 0x3, 0xc042050c20, 0x1a, 0x0, 0x0, 0x0, ...)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:898 +0x214
net/http.(*Transport).dialConn(0xa0e080, 0x837760, 0xc042052098, 0x0, 0xc04207c6c0, 0x5, 0xc042050c20, 0x1a, 0x0, 0x0, ...)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:1143 +0x31e
net/http.(*Transport).getConn.func4(0xa0e080, 0x837760, 0xc042052098, 0xc042144390, 0xc0420441e0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:957 +0x7f
created by net/http.(*Transport).getConn
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/http/transport.go:956 +0x36a

goroutine 5 [select]:
net.(*Resolver).lookupIP(0xa12a70, 0x837720, 0xc04203e080, 0xc042050c20, 0x16, 0x0, 0xc042024a80, 0xc04203e040, 0x0, 0x0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/lookup_windows.go:118 +0x17b
net.(*Resolver).(net.lookupIP)-fm(0x837720, 0xc04203e080, 0xc042050c20, 0x16, 0x429d40, 0x8, 0xc04203e040, 0x0, 0xc042163ea0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/lookup.go:192 +0x5d
net.glob..func10(0x837720, 0xc04203e080, 0xc042036040, 0xc042050c20, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/hook.go:19 +0x59
net.(*Resolver).LookupIPAddr.func1(0x0, 0x0, 0x0, 0x0)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/net/lookup.go:206 +0xdf
internal/singleflight.(*Group).doCall(0xa12a60, 0xc04216a050, 0xc042050c20, 0x16, 0xc042166090)
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/internal/singleflight/singleflight.go:95 +0x35
created by internal/singleflight.(*Group).DoChan
        /home/travis/.gimme/versions/go1.10.8.linux.amd64/src/internal/singleflight/singleflight.go:88 +0x2d7
rax     0x7fffca360b92
rbx     0x7fffca360b90
rcx     0x77
rdi     0xffffffffffbadd11
rsi     0x0
rbp     0x0
rsp     0x38ceae0
r8      0x97c
r9      0x97c
r10     0x97c
r11     0x97c
r12     0xc000007a
r13     0x0
r14     0x7fffca360b92
r15     0x7fffcd430000
rip     0x14f0000
rflags  0x10202
cs      0x33
fs      0x53
gs      0x2b

I am able to switch to version that is already installed on system:

e.g.

> gvm --version
v0.2.2
> gvm list
1.14.3
> gvm --format=powershell 1.14.3
$env:GOROOT = "C:\Users\stefan\.gvm\versions\go1.14.3.windows.amd64"
$env:PATH = "C:\Users\stefan\.gvm\versions\go1.14.3.windows.amd64\bin;$env:PATH"

Cannot build gvm with go 1.18

I cannot build gvm with go 1.18.

$ go version
go version go1.18 darwin/amd64

$ sw_vers
ProductName:	macOS
ProductVersion:	12.3
BuildVersion:	21E230

I get the following errors:

$ go install github.com/andrewkroh/gvm/cmd/gvm@latest
# golang.org/x/sys/unix
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:28:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:43:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:59:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:75:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:90:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:105:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:121:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:136:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:151:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:166:3: //go:linkname must refer to declared function or variable
go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:166:3: too many errors

Fall back to source install only when binary package does not exist (HTTP 404)

When the install from a binary package fails it falls back to installing from source. I think the only case where the fallback should occur is when the server responds with a 404 that no binary package exists. Otherwise it's falling back on various IO or permissions errors like

[2020-11-24T13:07:55.561Z] time="2020-11-24T13:07:54Z" level=warning msg="Failed to install Go from binary package. Trying to install from source." error="rename C:\\Users\\jenkins\\.gvm\\versions\\go1.14.7.windows.amd64.tmp\\go C:\\Users\\jenkins\\.gvm\\versions\\go1.14.7.windows.amd64: Access is denied." version=1.14.7

Default install does not honor GOARCH

I'm trying to install Go on my Macbook Pro M1 with GVM, but it always installs the AMD64 version of Go:

$ eval "$(gvm 1.17.8)"
$ go version
go version go1.17.8 darwin/amd64

It's not until I add the GOARCH variable when it respects the architecture of my machine:

$ GOARCH=arm64 eval "$(gvm 1.17.8)"
$ go version                       
go version go1.17.8 darwin/arm64

Make download timeout configurable

I am behind a corporate proxy, which performs some security scanning on all downloads, especially archives. For archives, it will first download the whole thing, scan it and only then pass it to the client. This is done be just sending the client the first few KB and keeping the connection open until the scanning has been completed. Unfortunately, this can take quite some time, especially for big archives with lots of files (like the Go releases) and therefore, the download hits the 3 minute timeout defined in https://github.com/andrewkroh/gvm/blob/main/common/common.go#L39.

In order for me to be able to use GVM, I would need an option to configure this timeout.

gvm use could return what is used currently

when you have lots of golang versions installed, it would be useful to be abl to find the current one being used.

So was thinking that ''' gvm list ''' could do what it does now but highlight which one is currently used.

The reason is because i am trying to automate the use of gvm for testing and CI.

Sorry about so many issues !! Hope i am not over issuing ?

gvm available - Refresh source repo and always report binary versions

It looks like gvm available does not refresh the git repo when source is present. So there are two code paths:

  • When source code is present in ~/.gvm/cache/go it reads the git tags and then checks if each tag has an available binary by querying the Go download metadata.

  • The other path is when no source is present and it straight returns the Go download metadata.

So there is room for improvement here in the case of source code being present. It should do a better job at merging the results of the Go repo git tags and the available binary versions from the Go website. And it should automatically refresh the git repo if it's more than a day old (that's how other code paths behave that use the source repo).

Relates #38 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.