New to Golang...
I am tinkering with a project that has a dependency I will like to tweak.
So far so good I see that Go uses git directly for dependency management, but I am yet to come across a straight to the point guide on how to handle the case where you want to use a modified version of a dependency.
Googling seems to be a little confusing because I run across methods around dependency management which I believe is no longer recommended, but as a new comer, it is hard to tell which is which.
So would appreciate if someone can help clarify what is the recommended way to manage dependency as at 2020, and how would you go about using a modified dependency in your project.
Pointers to links that answers the following questions is also appreciated
usually i'm using glide, here you can change dependencies for any repo or even commit that you need, and it's easy to maintain.
Related
I have a springboot project that we got going quickly by using the various appropriate spring-boot-starter jars to bring in the appropriate transitive dependencies that we needed. Now, as we get closer to production launch, we are adding code-quality and code-inspection tools to tighten up loose ends. Some of these are tagging the starter jars as problematic, but I am finding inconsistent advice as to how to handle the problem.
Spring.io documentation fails to weigh in on this. Starters are described here: Spring Starters, but it really just says they are used to "get going quickly" but does not indicate that they are intended for use in production. The starters are not listed in the 'production ready' features (which focuses on Actuator). The Packaging for Production makes no mention of starters. From Spring documentation alone, you are encougaged to use the starters (to get going quickly), but are not told to, or told not to, use them in production.
If the spring project adds either gradle-lint plugin, or uses maven-dependency-plugin, use of the starters flags problems. The starters include no code themselves, but they pull in useful transitive dependencies (by design), but that's contra-indicated by the lint plugins. Related incident here
From gradle-lint Generally, applications only use a subset of the libraries included in such families. The unnecessary dependencies included with the family both increase the footprint of the application itself. If the 'application' is actually itself a library, these unnecessary dependencies leak downstream to its users, increasing their footprint and potentially introducing breaking version conflict resolution problems.
Is the "right" answer to remove starter jars before going live? Should starters be used in production? I am sure there are plenty of projects that have gone to production with starters, and probably they have done so successfully. But it looks to me like the authorities differ on what to do, so looking to reconcile them.
I think this is likely to be closed as it's opinion based. Speaking as a member of the Spring Boot team, the starters are absolutely intended for use in production. There's no point in something that gets you going quickly if it then creates more work later on. Some people dislike relying on transitive dependencies indirectly and believe that all dependencies that you require should be declared directly. I think the linting tools you've mentioned are enforcing this opinion. You can either configure the tool to quieten it or manually declare the starters' dependencies. I would do the former.
Gradle is working on new features for sharing dependency versions between projects that will provide central locations (settings.gradle, libs.versions.toml) for declaring common dependencies.
It's already possible (and easy) to share a dependencies block through a plugin, so what is the downside of the plugin approach to sharing dependencies, versus the new version catalogs and dependency bundles? What do these new features improve upon?
This is not a thorough answer. However, let me share what I think makes a difference. We need to keep in mind that Gradle is built around developer productivity and making builds as fast as possible.
Centralizing common dependency declaration makes sense to be supported out of the box. Currently, there is a good chance that when you look at different Gradle projects, each one of them may implement a different approach to this. Cédric Champeau iterates over some existing pattern in this blog. Having a standard solution makes it easier to get started as developer. Cédric further states
Long story short: the presence of a catalog makes discoverability and maintenance easier, but it doesn’t remove any of the flexibility that Gradle offers. We’re thinking about ways to enforce that all direct dependencies are declared via a catalog in the future.
Declaring dependencies in libs.versions.toml allows Gradle to skip build script compilation when dependency versions are changed. This is significantly faster than changing the same in a script plugin. As a side-effect of declaring dependencies in libs.versions.toml, we may see third-party tooling that update dependencies automatically in the future.
All - I want to state this upfront that I am looking at pure technical limitations without going into the opinionated user usage aspects or learning curve requirements. After going through this site requirements, I think it is alright to ask this question.
Everywhere I read only the advantages of Gradle and how it has hit the sweet spots that both Ant and Maven missed. But nowhere I could find clear technical limitations that perhaps makes it difficult to integrate with Gradle. In one of the places it cited about lack of Eclipse integration, but then it turned out that you don't need a maven like plugin for Gradle.
Any inputs in this regard is highly appreciated.
There are a lot of things that people who move over from the Maven world find missing in Gradle. Not really deal-breakers or "disadvantages" but definitely annoyances. Couple of quick things from the top of my head:
Gradle dependency cache is not portable. If you copy it between machines, it will break in most cases.
Gradle does not have a "Provided" dependency configuration This was fixed in v2.12
Per dependency repository configuration is not possible. (However AFAIK, this isn't possible with maven either)
While most proponents would consider gradle's flexibility it's greatest strength (as #CollinD noted in his comments above), it is quite possible to end up with spaghetti hand-to-understand build scripts exactly due to its flexibility. Some have proposed this could be a problem with Gradle.
That said gradle is constantly under active deployment, and there is a good chance these will be resolved in the near future.
I'm a bit surprised at the sheer number of articles / blogs / questions / answers about Clojure mentioning Maven.
In about ten years working as a Java dev, working on both desktop apps and webapps, I've never ever used Maven once (typically --and that's a personal opinion but I know some people do think the same-- the projects I've seen using Maven where including the "kitchen sink" whereas the ones built with a more "controlled" build process where way "cleaner" and producing smaller jars, faster build time, etc.).
Is Maven a requirement when you want to build a Clojure app?
Is Maven mandatory when you want to use Leiningen? For example, can I add external jars as dependencies to a leiningen project "manually", without needing Maven?
I think my question boils down to this: can you, in the Clojure/JVM world get away without ever using Maven, just like you can build, test, package and ship both Java desktop, webapps and Android apps without ever needing Maven?
Short answer: No. Clojure's just a jar and you can use it as "raw" as you like, just like any other Java library.
Longer answer: Maven's not a requirement, but the tooling around Clojure, especially Leiningen, is highly Maven-aligned so your life will be easier if you just submit to Maven's will. But, with a little work, it's not that hard to get along without Maven. At work, I use a mix of Leiningen and our existing Ant/Ivy-based build infrastructure. I use Ant to resolve dependencies (from our curated internal repo) and then use a hack of Leiningen's :resource-paths to get it to pick up the non-Maven jars. At some point I'll make a true plugin to do this stuff, but it's been working fine for me so far.
Also, if you're an Eclipse person and use CounterClockwise, you can treat your project like any other Java project in Eclipse, managing the classpath manually. It just happens that you've got some Clojure code in there as well.
Of course, the drawback in either approach is that if you want to grab something that's available from either Maven central or Clojars, you'll either have to set up some kind of mirror for your infrastructure, or manually pull down the transitive dependencies and add them to your project.
You do not have to use maven, or leiningen, for that matter. You can run the clojure REPL with
java -jar clojure-1.3.0.jar
and it will work just fine. I know where you're coming from, because a year ago, I was in the same boat as you. never used maven, seen a couple of less than great projects that used it poorly, and generally distrusted maven. Ant+ivy works great, who needs maven?
As a result of using leiningen, and starting a new job where we have a very well setup maven config, I've changed my tune completely; I now think maven is great, and far prefer it to ant, which I've used for a long time.
Specifically with clojure, some advantages of leiningen are:
automagic project scaffolding: "lein new" sets up a new project for you. convention is important, it helps other developers understand your project and quickly ramp up on it.
dependency and plugin management. adding a dependency is trivial, and there isn't a great way that I am aware of to do non-maven dependency management that is tightly integrated with clojure.
"lein repl" sets up your classpath and everything correctly, so you don't have to fool with it, you can just start and run a REPL.
artifact creation: building a fat jar (lein uberjar) is straightforward, and already set up for you.
So, while it's definitely possible to use clojure without leiningen, I honestly don't see why you would want to. There are too many niceities for day to day development not to use it, in my opinion.
regarding "Is Maven mandatory when you want to use Leiningen?"
leiningen uses and wraps Maven so you can't truly avoid it, though you don't ever need to touch any XML
Maven is not mandatory for Clojure as others have rightly pointed out.
However, I would like to encourage you to embrace Maven (either directly or via leiningen). It has some big advantages in the Clojure world:
You will be more productive in the long run - once you've got it set up, it is pretty impressive to see a complex build, test and deployment execute in a single command. Do you really want to be manually setting classpaths, downloading dependencies, incrementing version numbers, uploading to FTP sites etc.?
One of the biggest advantages of using Clojure on the JVM is access to the Java library ecosystem. Maven is the tool of choice for automatically managing dependencies on Java libraries. Nearly everything you are likely to need will be in either the Maven Central or Clojars repositories.
Clojure tends to have small focused libraries - this is good because they are "simple" and you can pick and choose the functionality you like. At the same time, it also means that you are likely to have numerically more library dependencies. Hence a build management system is going to be more useful.
You can make Maven builds as "lean" as you like. Obviously you can pull in every dependency under the sun if you like, but you can also create very lean jars by excluding the unnecessary cruft. That's your choice.
It is the de-facto standard in the Clojure world. If nothing else, using it means that you will be able to collaborate with others more easily.
P.S. Like you, I didn't really see the point of Maven 5 years ago. Then I gave it a go and saw how powerful it could be for my workflow. Now I'm a convert :-)
We check all of our source code's dependent third-party JARs into source control along with our source code. When needed, we manually download updates to third party JARs and replace those JARs that are in source control with the newer versions. We haven't felt the need to use Maven yet as this process seems simple enough for us. But are we missing something of great value by not using Maven? Or does our scenario not warrant using Maven?
"JARs dont change much", I hear this all the time.....
Storing jars in the SCM is simple in the beginning of the project. Over time the number of jars gets larger and larger.... Wait 2 or 3 years and nobody remembers where the jars came from, what their licensing terms were and most commonly what versions are being used (important to know when analysing security vulnerabilities).....
The best article I've read recently making the case for a repository manager is:
http://www.sonatype.com/people/2012/07/wait-you-dont-have-a-repository-manager/
A little irreverant, but does make a valid point about the kind of technical inertia one encounters all the time.
Switching a project team from ANT to Maven can be scary.... Maven works quite differently, so I find it is best deployed with greenfield or adventurous project teams. For the old-school ANT users, I recommend using the Apache ivy plugin. Ivy allows such teams to outsource the management of their dependencies but keep the build technology they're comfortable with.
Ultimately the biggest benefit of using Maven are not dependency management. It's the standized build process. I've seen several failed attempts to create a "standard" ANT build process. Problem every build engineer has his opinion on what the standard should be.... Maven's approach of forcing users to write build plugins may appear restrictive in the beginning, but just like the iPhone eventually developers discover "there's a Maven plugin for that" :-)
When it comes to dependency management Maven really can be quite valuable. As Mark O'Connor suggests, running a local repository manager would likely be better than checking the artifacts into source control.
There are many tools (like m2e in eclipse) that can help with dependency management and provide valuable feedback on which modules or dependencies require which other dependencies. Maven will also make sure to get the appropriate version of a dependency even if different modules depend on different versions of a given library. That will help prevent duplicate versions of the same jar showing up in your deployed project as long as they have the same group and artifact id.
Even for a very simple project I don't think I would resort to checking dependencies into the source control system.
It's not only about 3rd Party Libraries. Mostly if you have multiple repositories. In our case, we had four repositories with lots of inter- and intra-dependencies.
Actually I started this answer and then I had to go for 15 minutes to talk to some colleague about a problem happened after someone forgot to update the .jar of one project in the other's lib directory.
And it looks more professional :)