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

Standarized Makefile for go projects #276

Closed
victorb opened this issue Nov 27, 2017 · 13 comments
Closed

Standarized Makefile for go projects #276

victorb opened this issue Nov 27, 2017 · 13 comments

Comments

@victorb
Copy link
Member

victorb commented Nov 27, 2017

When starting to work on adding golang support for Jenkins, I quickly noticed the lack of standardization of a Makefile between go projects. In JS land, we have aegir that gives us the same commands for all repositories where it's being used, which means it's very easy to have a standardized pipeline that works everywhere. Would be very nice to have the same thing across go repositories.

We can add a standard Makefile for ipfs/ci-sync to sync across all go repositories.

Commands I had in mind that are missing to be standardized:

  • make deps (installs gx and dependencies)
  • make install (runs make build and installs resulting binary(ies))
  • make check (runs go fmt and possibly go vet)
  • make test (runs go test)
  • make sharness (runs the sharness tests if available, otherwise exists with 0)
  • make build (builds a binary if possible, otherwise exists with 0)

/cc @whyrusleeping @Stebalien @Kubuxu

@Kubuxu
Copy link
Member

Kubuxu commented Nov 27, 2017

@kevina was doing something around this with Travis.

@kevina
Copy link

kevina commented Nov 28, 2017

@Kubuxu I was mainly installing this minimal Makefile if one does not already exist:

gx:
        go get github.com/whyrusleeping/gx
        go get github.com/whyrusleeping/gx-go

deps: gx
        gx --verbose install --global
        gx-go rewrite

publish:
        gx-go rewrite --undo

@kevina
Copy link

kevina commented Nov 28, 2017

@victorbjelkholm disagree on what the proposed install target should do. install should install the binary as it does in go-ipfs not install the deps. We use the deps target for that. Note that not all projects have something that can be installed so this target doesn't always make sense.

@victorb
Copy link
Member Author

victorb commented Nov 28, 2017

@kevina ah, yeah, that makes much more sense indeed, especially since the usual way of building + installing things is running make && make install in unix land. Thanks.

deps does indeed sound better.

so this target doesn't always make sense

Yeah, mentioned this in the original comment. As long as the target still exists, can be called and exists with 0, that's ok.

@Kubuxu
Copy link
Member

Kubuxu commented Nov 28, 2017

I would add make coverage-reports that would create directory coverage-reports and run coverage and collect all of the reports there (in go it is easier to have multiple reports as we would need additional tool to converge them into one).

@hsanjuan
Copy link
Contributor

We have many projects, many of them small. The cost of maintaining a tightly standarized Makefile among all is too big or too tedious (see how it went with standarized readmes, standarized badges and so on...).

Just run a sensible default (like golang() does now), or otherwise let users define what custom stuff to run with a repo-provided script that does whatever needs to be done (like a .travis.yml does). I understand Jenkinsfile does exactly that already?

@victorb
Copy link
Member Author

victorb commented Dec 5, 2017

@hsanjuan I think readme's and badges can be standarized as long as we have proper tooling, but readmes are way different than how software builds and is tested.

I think the time required for maintaining custom processes for building and testing each one of our repository is way higher than making everything follow one process.

@hsanjuan
Copy link
Contributor

hsanjuan commented Dec 6, 2017

But it's not a custom process, it's just providing the user an entrypoint to run whatever they need to when there is no make test to be found, and avoid implementing a catch-all solution that fits every project. This is usually takes the form of a jenkins.sh in the repo that just gets run.

The most "proper tooling" you need to develop, the most you'll need to maintain. We have proper tooling for standard readmes, like we have sprint issue bots and already-forgotten project health dashboards. All this things end up depending on an individual, eventually break, get outdated and there's no one around to fix them, or it takes forever. Most projects don't even need jenkins. Travis comes for free, is maintained for free, and does just fine for the scope of the project.

So my point is: avoid as much as possible custom centralized tooling and standards and take the stupidest solution which gives every project flexibility to use jenkins in the way they need.

@victorb
Copy link
Member Author

victorb commented Dec 6, 2017

But it's not a custom process, it's just providing the user an entrypoint to run whatever they need to when there is no make test to be found, and avoid implementing a catch-all solution that fits every project. This is usually takes the form of a jenkins.sh in the repo that just gets run.

Yes, it's about providing an entrypoint that works the same for similar projects, so you don't have to learn each projects own steps, when they are the same but names differ slightly. As proposed in the opening of this message, it would take the form of max 6 targets in a Makefile. We already have this working in JavaScript land (with aegir) where any project you open up, same commands are being used for installing dependencies, testing and more.

Keep in mind, we're doing all this work already, as it becomes necessary to keep repositories up-to-date with each other, the only point I want to bring forward in this issue is to make it official rather than impromptu. Here is a couple of examples of this happening already:

All of these PRs (unofficially) converges on a common way to run the tests and how to use the project. I don't see why we can't agree to apply the same process, on all repositories where possible.

Most projects don't even need jenkins. Travis comes for free, is maintained for free, and does just fine for the scope of the project

I disagree and it also departs from what we've initially agreed on. Jenkins will be used for all repositories and replace TravisCI and CircleCI, so we don't have to spend any time waiting on CI anymore and having a more flexible environment. Also, having all projects in Jenkins gives us the benefit of starting to be able to cross-test things when dependencies of projects updates, but that's more a thing for the future.

My point being: let's please make our development environments as nice as we can, for long-term contributors but also first time contributors. Having things work the same across repositories is vital to making the development process more user friendly.

When I see that things are working exactly the same in X number of repositories, but in slightly different ways, I cannot understand why we wouldn't want it to work the same way. What snowflake golang-projects do we really have under any organization that would not benefit from the targets I've suggested in the opening issue?

@hsanjuan
Copy link
Contributor

hsanjuan commented Dec 6, 2017

Well a few targets is better than many targets.

What I'm just asking is to reduce that list of targets to 1. If my project has just one make jenkins target I just need to look in my project to see what gets run in jenkins, and I just need to update that if my build requirements change and I don't need to know the standard, the code that implements the standard, nor adapt to it, nor to discuss how it is faulty (i.e. make build builds, it should not have to do with producing binary artifacts).

@victorb
Copy link
Member Author

victorb commented Dec 6, 2017

Well a few targets is better than many targets.

Agree, if there is something that doesn't have to be there, it shouldn't be there.

This is in no way specific to jenkins but overall project hygiene, quickly being able to know how to use the project, no matter who started it.

I don't see how it's different when your build requirements change if you're changing a target called jenkins compared to build. The "standard" is only about the interface for installing dependencies et al, not about how that actually happens in the background.

Again, what I'm proposing here is what we're already doing, across multiple repositories. The only goal is to formalize it so it's something that won't change from nowhere.

make build builds, it should not have to do with producing binary artifacts

Slightly off-topic, but what would go build do unless it's about producing a binary? Not a go expert so not sure, but the only cases I've used go build is when I want a binary.

@hsanjuan
Copy link
Contributor

hsanjuan commented Dec 6, 2017

@victorbjelkholm our views are slightly divergent but I acknowledge in any case it's a welcomed improvement. As you say, most projects do already follow a somewhat standard makefile (whenever I create a project I copy/paste it from an existing one at least).

Build:

Build compiles the packages named by the import paths,
along with their dependencies, but it does not install the results.

When there's no binary it just compiles. I use make build to check if my code (without the test parts) compiles.

@daviddias
Copy link
Member

Moved to ipfs-inactive/dev-team-enablement#47

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

No branches or pull requests

5 participants