What i love about Go from a user of some of the open source apps like Gogs, is that its so easy to get the application running.
A single binary with zero dependancies is so awesome. With a ruby on rails app I need to worry about ruby version, ruby implementation, gem versions, compilation of C based gems, etc etc. With Go i simply copy up the binary and run it.
To be fair (and I am a Go fan) it is the same with Java and Scala. That's the main reason I switched from gitlab to gitbucket. Also with Java and Scala you can have all the resources inside your jar file. With Go you need a directory structure to store your templates, CSS, etc.
The second reason I switched was RAM consumption and here Go shines compared to Java, although I'll have to let Gogs run for a few days to see what happens.
I gave it a spin and it looks nice. I can see migrating from gitbucket to gogs, mainly for being able to run it on a small VPS. One thing that I didn't like was that the source version can only run from the source code directory.
If I copy public and templates directories it should run from anywhere.
It is possible to pack static assets directly inside go binaries using statik[0] or rice[2]. I've been using then for small webapps and they both work very well.
In addition to the bundle-the-jre option (which is extremely workable), you can also feed java bytecode into robovm [1], which spins it through LLVM and produces native binaries for any platform you can go with LLVM. (Most of the documentation emphasizes IOS, but speaking from experience, yes, you absolutely can make mac desktop and linux native binaries as well.)
What robovm can do is a great example of the joys of toolchains with a well-defined stable intermediate representation. (Or one of the joys, I should say -- the flowering of languages on top of the jvm is another.)
Go's first-class AST work is excellent stuff, but I'd love it even more if they fleshed out a well-defined, stable, portable intermediate format like LLVM's IR and java's bytecode. Making a release of software and knowing it can run on architectures you haven't even thought of yet is liberating. Sure, architectures don't come along "very often" (but they're starting to happen more often!), and sure, you can use a full vm at the bottom layer (but it's slow! It can't do a fraction of the optimizations possible with an IR/bytecode), and sure, you can just pretend the source is an IR (but if some library you use chooses a different build tool chain than you, you're going to have a bad time -- don't laugh, golang is too young to have bifurcated much yet, but give it time, and look at what happened around the go-get mess already; or, consider what happens when someone just adds more tooling like source generation, which has also already happened)... Taking the long view, I think an intermediate representation has proven incredibly useful for the jvm as a platform, and I hope golang also grows to offer such a route sometime in the future.
That is the greatest possible defence of golang's current course and heading, and god knows I want as much of my world to build from source as possible, but
> sure, you can just pretend the source is an IR (but if some library you use chooses a different build tool chain than you, you're going to have a bad time
In the jvm world right now, for example, I won't touch maven with a ten foot poll. And yet I regularly use libraries produced by people who do. The portable, stable bytecode is a boundary between me and them where the buck stops. Anyone can use any build toolchain they like, and the interface for collaboration is well-defined.
Don't get me wrong, there are many things to love about golang, and there are many things to love about building from source. But I do think it's worth pausing to consider the flexibility that an intermediate representation can unlock.
Which is a security risk in that the jre can't be updated without an update to your product. Granted the same applies to go since it statically links to its runtime.
Not really a security risk if you think of it like an embedded library in your software. A JRE vulnerability is then just like a vulnerability in the app itself and the vendor needs to update it.
The majority of JRE vulnerabilities are also not really relevant to a local app in the first place. They're sandbox vulnerabilities that let carefully crafted applets break out of the sandbox and execute arbitrary code. But regularly installed desktop/server software doesn't run in the applet sandbox, and is already assumed to be able to execute arbitrary code.
I've been experimenting with it as well and it looks like you have to copy several directories to get it to work out of the box - templates, public, custom, log, and data.
But I'm inclined to agree that this is one area Go projects have a hard time with. The portability of the executable is great, but if you're doing anything that requires static assets, configuration, or data outside the context of the runtime, you can easily end up with a tough-to-manage mess of configuration.
What we've done for our internal Go projects is wrap them up with an .rpm installer that handles the creation of directories throughout the system, drops init scripts where they're appropriate, and sets up necessary cron jobs and logrotate rules. I don't think this is the best approach, but at the same time I'm not familiar with any good alternatives.
> But I'm inclined to agree that this is one area Go projects have a hard time with. The portability of the executable is great, but if you're doing anything that requires static assets, configuration, or data outside the context of the runtime, you can easily end up with a tough-to-manage mess of configuration.
This is mostly a sysadmin/devops issue, since all languages have the same issue.
I solve it through a CM tool (Ansible, in my case) that sets up my directories, rsyncs my templates and TOML config, and uploads my binary. Not having to worry the server running the same env as my dev environment removes a whole class of bugs/frustration.
> This is mostly a sysadmin/devops issue, since all languages have the same issue.
You're kidding right? I thought that whole "devops" movement (call it what you like) was to get rid of the attitude of "other people's problem".
I live in environments that are (for the most part) regulated and demand by law that there is a strict separation between the people running and developing software, often open to interpretation is the 3rd role of people configuring the software.
The problem is that "I solve it..." just doesn't work. Either people solve it by working cooperatively together or it simply won't ever be deployed.
There's no such thing as a sysadmin problem, devops problem, developer problem. (No go downvote me for the tone of the next sentence) -- For me it's either get your ass moving, stand up, walk over to people and talk to them or get lost!
I missed this at the time, but I think you read past what I said: I used "devops" in the tools sense, not the people sense. A programming language (the syntax, the compiler, the linter) can't be everything to everyone, and therefore most don't attempt to shoehorn in things like static asset bundling, etc.
That's why frameworks exist, or packages like go-bindata or rakyll/statik (https://github.com/rakyll/statik), or CM tools that can wrap it all together.
If the project permits it (size, complexity, what kind of bugs I expect to encounter) I like to have my static assets in a separate git repository.
System configuration I think is a problem independent of the programming language and anything you try will feel as hack. As long as it works, it is ok. :)
> With Go you need a directory structure to store your templates, CSS, etc.
Is there anything stopping one from appending a zip archive to the go binary, and having the binary open the executable as a zip file to get at the static assets ?
Glibc does not properly support static binaries, you need libc around even for static binaries mostly (eg dns resolution). Its annoying. You can make real static binaries with Musl libc though, or on the BSDs.
Well currently this applies to Go as well: when linking to the "net" package it links to the system libc shared library for the same reason.
You can build your binary with the netgo build tag, but you must take into consideration that your binary might not behave correctly when running on systems with customised name resolution (NSS) settings, such as nss-ldap etc.
It's not about what those languages allow, it's about how developers use them. You very rarely see C software distributed this way.
Go developers only distribute their open source software in a way that you only have to take the source, compile it, and run it, without having to worry about dependencies.
I agree, that is one of my most favorite aspects of Go.
go get -u github.com/go/project
If you're writing native Go code, it doesn't matter if there's 0 or 1000+ dependencies, that one command will take care of everything. So there's no need to fear having extra dependencies, and you are welcome to reuse more code.
Go takes the common parts of writing software and abstracts them away. Take any two distinct Go projects, and the only difference will be:
- Import Path
- Actual Code
Everything else works exactly the same no matter what project it is (assuming it follows idiomatic Go package conventions). Docs via godoc.org, standard testing, go vet, http://go-lint.appspot.com/, http://gocover.io/
No need to figure out how to install that particular project/library, how to get docs, how to run tests, etc.
You mean like `bundle install` or `pip install -r requirements.txt` or `npm install package.json`? I mean, it's great that Go has something similar, but it's not like other languages are missing dependency managment...
Mind you that these are compile time dependencies. Go produces static binaries that can run as standalone apps. So only the developer has to install them.
Ruby, nodejs and python have runtime dependencies, thus the user has to install them too (or use the bundled ones if they exist).
Also their package managers have many issues you don't see with go (because go doesn't have a package manager, rather a source code dependency manager).
For example python and ruby have many versions and not everything is available in all versions. What a user will do if he want to run a 2.7 and a 3.x python app?
Sometimes they use the system compiler to produce binaries. I have seen it fail occasionally; for example charlock_holmes on a gentoo hardened system. Npm just floods your filesystem with npm_modules directories. I use a package manager so I won't have to install the same thing multiple times at multiple locations. Also it is very difficult to understand its directory structure. I searched the docs for hours in order to find where it stores the programs I install as a user (its path). Go is difficult to understand too in that aspect but it has all this info in one online document. You read it until you understand it.
Finally there are always the questions; should I use pip or easy_install? What does rvm, what gem and what bundle(r)? Why should users learn them? How may I update my current gems and remove old versions? Where is gruntjs and how do I run it?
Probably many more. If `go get` was good enough as you intended to say why do we have `godep, godeps, gom, gondler, goop, vendorize, party, gpm` and many more? Which one should I pick? It's better do GOPATH="_vendor:$GOPATH" go install or use one of them? Also, should I install go with apt/brew/pac or use gvm?
I like go, I use it for fun and work, but really, is getting annoying seeing all this `gophers` totally out of reality.
There are third party tools for every language.
With go until now I haven't need any of them, so I don't know them. I read go's docs and I do fine with the official tool when I want to compile an app from source.
On the other hand, there isn't a way to not learn about gem, bundle, pip, easy_install, npm when you try to install apps written in their languages. Some times it is easy, as “gem install gollum” and some times it is difficult, as trying to install gitlab.
Haskell I really don't know because any haskell app I ever needed was in my distro's repositories. To be fair most Python packages are too.
The reason that Go can't handle dynamic library dependencies, for the most part, isn't a strength--it's a weakness. I guarantee you that if it could call out to C efficiently, it would. Part of the price it pays for its goroutines is that its relocatable stacks do not play nicely with C calling conventions, meaning it can be extremely expensive to call out to a C routine. For that reason, Go essentially reimplements libc in its own standard library. All the other languages you named don't do that, because they don't have to.
Anyway, Go can't produce dynamically linked libraries yet even for Go applications. It really has no choice but to bundle them into one application.
I agree that this limits Go's use scope. But when you accept that Go is most suited for web apps and some console tools, it is nice and works well for the users and the application packager.
The only package manager (pm) I like, is the pm of the distro I am using. If I am on Fedora, I like yum. When I am on Gentoo I like portage etc.
The problem with most web apps is that they have dependencies that don't exist in your distro's pm. I'll take a static binary over a 3rd party pm any day. Let's not forget that one of the most important reasons for the existence of docker is to not have to set up an app in many different systems.
Go's goroutines as I understand are the same or very similar to Lua's coroutines and WinAPI's Fibers. Right?
For the later two can calling C functions is cheap. I would assume if you run Go with its default one thread option, it's cheap too. (Switching threads or even processes means context switching is what is usually expensive).
No, Go routines are not the same as coroutines in other languages.
In order to provide efficient lightweight threads, Go allocates only a small amount of memory for each stack, growing it as function calls require it by appending another segment in a linked list. This makes thread creation very cheap.
The problem with segmented stacks is that they can cause "stack thrashing." Suppose a goroutine is right at the boundary between two stacks. It calls a function that exhausts the available segment, forcing the allocation of a new segment, which is then added to the linked list. The function runs, and then frees the segment upon return. If this boundary happens to fall within a tight loop, you'll see a severe drop in performance, to the point that it's completely unacceptable.
Recognizing this, Go relatively recently switched away from segmented stacks. It now uses a strategy called relocatable stacks, or contiguous stacks. See https://docs.google.com/document/d/1wAaf1rYoM4S4gtnPh0zOlGzW... for details. Similar concerns prompted Rust to move away from segmented stacks, but as relocatable stacks require a garbage collector that was not a viable way forward for Rust, so it just dropped the idea completely.
The problem with both approaches is that C has no knowledge or support of either segmented or relocatable stacks. This means that calling out to C in Go involves a completely different calling convention that involves switching to a larger stack, running there, and then switching back--which is very expensive, especially compared to languages like Lua where the C FFI is basically free. That's why Go reimplements glibc by performing its own system calls--to avoid the C FFI.
In conclusion, every language feature--no matter how enticing--has a cost.
Unlike Go, many projects (particularly web based) written in these languages have native dependencies (for databases etc.) and it's uncommon for installation to be as simple as you say.
Ruby's Nokogiri for example is very very common and I've never found it simple to install.
Python has psycopg, numpy and a variety of others that are often very complex to install.
Node at least differentiates itself in that most of the database drivers have pure JS fallback implementations, so they'll work without the relevant libraries installed, just not as fast.
I've had issues with installing those libraries involving C-language dependencies that were failing compiling (this was mainly due to the recent Xcode tool update that makes llvm barf sometimes).
It's not going to get simpler than a single executable.
Easier than some other languages, but you still need something to run what's in your jar. Being able to deploy executables eliminates a whole layer of dependencies, which ends up being really handy.
I definitely agree! Statically linked binaries are my favourite part of Go, and one of the reasons why I've started moving towards it at work for some projects. Really takes a lot of hassle out of it all.
This is why I prefer static binaries and preferably "crunched" binaries.
Same goes for the use of "read-only" mounts and "RAM disks" as opposed to dependence on other, less reliable media.
I hope your comment continues to be upvoted; usually I see downvotes at any mention of static linking. Why, I can never be sure. If static binaries make some power user's life easier why should anyone else care? With reasonably-sized, well-written programs (or the use of a system like Go's), compilation can be quite fast. And easy enough for anyone to do if and when libraries change.
Thanks for your work on Gogs! looks forward to seeing it grow. Would love to help out on the front end - let me know if you are needing any contributors.
Indeed. Gitlab is a similar software that I absolutely love, but the setup process is quite lengthy (though straightforward) and updating to new versions can be a considerable effort. I'll definitely be giving this a try, especially since the design is of a similar quality to gitlab.
The new Omnibus installer (which is basically a nice wrapper around Chef) makes the install process much simpler, FYI; it was released sometime late in the 6.x era.
GitLab B.V. CEO here, thanks for mentioning the Omnibus installer packages, they indeed make the installation much faster (2 minutes total) and updates are simple as well.
Right now I still have a very basic git server for personal use with a bunch of bare repos and no UI, but I'm sorely tempted to start using Gogs or GitLab. GitLab wins for polish so far, but Gogs has caught up very quickly, and feels slightly faster.
GitLab is great, I've run it since version 3, but I am about to switch to Gogs. The reasoning is that GitLab is pretty painful to deploy, and frustrating to update to newer versions from older ones. Gogs seems a lot faster too, and it has every feature I need. GitLab comes into its own if you've got a large team however, but in that case I'd probably use Phabricator instead :)
GitLab B.V. CEO here, thanks for using GitLab since version 3. We know that there have been some painful upgrades. Since we have packages the upgrades have been much easier. Please consider switching to a package install.
That's where I find GitLab super useful. My use-case however is just me, a single user, on a tiny VPS so GitLab is overkill. Awesome software though, and I'm a massive fan
Wow, I don't know how something like Phabricator slipped under may radar, that looks amazing. Many props to their copy writer(s), seemed every page was fun to read.
As a person who recently discovered gitlab and has been trying to push it (make it popular at work, and possibly use it to replace github, and encourage people to use it), this is amazing.
Installing Gitlab was definitely one of the painpoints, having an executable that just works is amazing
What are people's thoughts on open software projects like this eating into github licensing money? I feel guilty sometimes pushing gitlab since I really like github as a company (and want them to thrive)
Github is a great example of a company that built closed source tools on top of open source ones and made money. They are not a non profit and aren't contributing a lot back to the tools they make money off of so it makes no sense to feel bad.
GitLab B.V. CEO here, thanks for promoting GitLab at work. I'm sorry to hear the installation was a painpoint. Have you tried our packages? It is a single file that installs in two minutes.
I recently installed the CE package and it was a good experience overall. I had put it in a VM though, because it didn't like my postgresql installation ( https://wiki.postgresql.org/wiki/Apt ).
I absolutely love the product. The install guide is fantastic, I don't know if that can be any better than it already is. The thing is, I'm a little paranoid about downloading & installing random binaries on our computers at work (I work in a very IP-sensitive company), so I generally go for source-builds.
I've actually been writing a fabric script to automate the entire install, believe it or not (the whole thing might be an exercise in futility, since people could just download the package), and I've installed gitlab enough times that I'm not really worried about it -- so at this point it's not a huge problem.
Installing Gitlab was definitely one of the painpoints, having an executable that just works is amazing
There were already other options that were very simple to install and upgrade, such as Gitblit and Gitbucket. At work we are using Gitblit. It provides all the functionality you'd expect, and one of the nice advantages is that it can store tickets in an orphan branch, so that you have these in git too.
I know this is silly and probably more than a little undeserved, but I stay away from java, JARs and WARs like the plague. I barely use Java for anything anymore, and I know 8 is great, but I'm just not comfortable running that/taking care of it.
I've actually rolled up my sleeves and written some login adapters (for internal use) in gitlab, and I'm much more comfortable writing ruby in rails than I would ever be writing Java. Again, this is probably a stupid opinion, but until I see the Java light, I don't think I'll be back to it.
Also, gitblit looks nowhere as good as gitlab (or even gitorious) does. Neither does gitbucket -- they don't have the polish that I see on other solutions... Yeah it's a really fickle point, but I want to reward groups that also prioritize design/visuals in their projects.
When considering a github-like service for my company, there were two main candidates, gogs and gitlab.
I favoured gogs because of the ease of deployment. What killed it was the fact that forking public repositories and creating pull requests is not implemented yet.
Since the ease of deployment for gitlab was drastically reduced lately, we settled for gitlab.
This is terrific. Other than the java implementation, is this the only alternate git implementation that doesn't use the core c git code under the hood? That's a pretty important accomplishment.
So many things you could build with a git-like data store...
Gogs uses a mix of GoGits, a partially Go implementation of git, and the traditional git binary via os/exec. A quick scan shows that it relies on the binary for perhaps the majority of tasks.
Another project I'm aware of that aims to re-implement git in go is https://github.com/kourge/ggit, which looks promising but has been slowing down, activity-wise.
bup, the deduplicating backup software, uses the git pack format for storing its data (because the tree structure of git matches really well the tree structure of how bup operates). They have written their own implementation of pack writers and readers [0]; the writers are pure-git, the readers call the git binary.
Tried to visit gogs demo page, but "502 Bad Gateway", so I'll stay with Gitlab for quite a while.
A lot of people mentioned that Gitlab installation is painful, but for me it was rather simple albeit a bit long. Probably the "IKEA effect" makes me love this awesome project even more.
Ok, since my GitLab testinstall is hosed anyway...
How does this compare feature-wise to GitLab? How does this compare to GitLab regarding updates, i.e. how easy and seamless will update be and how often are they available?
Would be nice if someone could post some first-hand experience :)
Does this implement a git engine like Gerrit? Its worth looking at their design - they can do so much cool stuff (like rejecting badly formatted commits) because they have their own server (IIRC).
"System Requirements
A cheap Raspberry Pi is powerful enough to match the minimal requirement.
4 CPU Cores and 1GB RAM would be the baseline for teamwork."
GitLab B.V. CEO here. We know that our manual installation is pretty involved (10 pages) so we recently made packages that you can install in 2 minutes.
It's for ZeroClipboard (http://zeroclipboard.org/), which is widely used (GitHub switched to it in early 2013). Unfortunately Flash is still the only reliable way to programmatically copy content to a user's clipboard in the browser.
No matter what I do, I never seem to come below -1 points for a comment. Isn't it un-hip enough to not be a git fan? What else do I have to do to really piss you off?
A single binary with zero dependancies is so awesome. With a ruby on rails app I need to worry about ruby version, ruby implementation, gem versions, compilation of C based gems, etc etc. With Go i simply copy up the binary and run it.