@@ -23,6 +23,178 @@ See these examples for guidance:
2323* [ ImageJ 1.x plugin template] ( https://github.com/imagej/example-legacy-plugin )
2424* [ ImageJ tutorials] ( https://github.com/imagej/tutorials )
2525
26+ ## Enforcer rules declared in this parent
27+
28+ The ` pom-scijava-base ` parent POM declares several
29+ [ enforcer] ( http://maven.apache.org/enforcer/maven-enforcer-plugin/ ) rules which
30+ we believe make SciJava-based projects more reproducible and more consistent:
31+
32+ * __ Plugin versions.__ Out of the box, Maven does not require plugins used to
33+ declare a version. But plugin versions must be declared to ensure
34+ reproducible builds. Otherwise, the version of Maven core you use at build
35+ time will determine which plugin versions are used, and the behavior might
36+ differ between builds.
37+
38+ * __ No duplicate classes.__ If two dependencies define the same class, then
39+ it introduces the possibility of serious class-loading issues. Which version
40+ of the class should be chosen? In some scenarios, classes from one part of a
41+ certain library may be loaded from dependency ` foo ` , but classes from a
42+ different part of that same library at a _ different version_ may be loaded
43+ from dependency ` bar ` . When this happens, difficult-to-understand compiler
44+ errors, or even runtime errors, may occur. Best practice is to ensure that
45+ all classes come onto the classpath from exactly _ one_ source.
46+
47+ * __ No too-new dependencies.__ When a project is compiled for Java version X,
48+ then it may not use any dependencies which require a version newer than X.
49+ Otherwise, your project is lying about needing only version X.
50+
51+ * __ No circular dependencies.__ Actually, this is a central rule of Maven. But
52+ we configure the Enforcer to explicitly check for it, just to be safe. It is
53+ always possible to avoid circular dependencies; if you feel like you need
54+ one, you should instead solve it in one of the following ways, depending on
55+ how much code is co-dependent:
56+ 1 . Combine the co-dependent artifacts into a single artifact.
57+ 2 . Introduce a third artifact to house the co-dependent code, which depends
58+ on the other two artifacts.
59+ 3 . If all else fails, write to the
60+ [ SciJava list] ( http://groups.google.com/group/scijava ) for help.
61+
62+ * __ Reproducible builds.__ This rule means no ` SNAPSHOT ` dependencies, no
63+ ` SNAPSHOT ` parents, and no ` SNAPSHOT ` plugin versions. A snapshot version is
64+ not immutable, which means that code which depends on a snapshot may build
65+ today, but not build tomorrow, if the snapshot is later changed. The best way
66+ to avoid this conundrum is to _ never depend on ` SNAPSHOT ` versions_ . Snapshot
67+ are best used for testing only; they can be used transiently, but their use
68+ should never make it onto the main integration branch (i.e., ` master ` ) of a
69+ project. See also
70+ [ Using snapshot couplings during development] ( https://imagej.net/Architecture#Using_snapshot_couplings_during_development ) .
71+
72+ * __ Developer roles.__ SciJava-based projects define developers and
73+ contributors with roles matching the
74+ [ SciJava team roles] ( http://imagej.net/Team ) . Doing this is vital for
75+ consistency, and for communicating expectations to the community. By being
76+ careful about which developers are pledging which sorts of responsibility,
77+ the social status of each project becomes much clearer, and which social
78+ actions to take in various circumstances becomes a more tractable problem.
79+ We have [ automated tooling] ( https://github.com/scijava/mediawiki-maven-info )
80+ which generates MediaWiki sidebar templates for all components of the
81+ [ ImageJ software stack] ( https://imagej.net/Architecture#Definitions ) ; this
82+ tooling requires SciJava developer roles to be present for sensible results.
83+
84+ * __ Required metadata.__ Every SciJava-based project must override key pieces
85+ of metadata, including the ` name ` , ` description ` , ` url ` , ` inceptionYear ` ,
86+ ` organization ` , ` licenses ` , ` developers ` , ` contributors ` , ` mailingLists ` ,
87+ ` scm ` , ` issueManagement ` and ` ciManagement ` elements, as well as the
88+ ` license.licenseName ` and ` license.copyrightOwners ` properties.
89+ There are several reasons for requiring these overrides:
90+ * __ Avoid inadvertent inheritance.__ The ` pom-scijava-base ` POM itself
91+ declares all of this metadata for itself (e.g., its ` <scm> ` block defines
92+ where the ` pom-scijava-base ` source code is managed, and this information
93+ is necessary for the tooling which cuts releases of the
94+ ` pom-scijava-base ` POM itself). For better and worse, when extending
95+ ` pom-scijava-base ` , the child POM inherits all of these elements (except
96+ for ` <name> ` , but that is the sole exception in the above list). If the
97+ child POM does not override each and every one of these elements, then it
98+ will inadvertently inherit the incorrect values from the
99+ ` pom-scijava-base ` parent. Furthermore, due to a quirk/limitation in
100+ Maven, if you specify an empty block (e.g., ` <contributors /> ` ), then the
101+ non-empty value from the ancestor will take precedence in the
102+ interpolated POM. Hence, we enforce that all of these fields are
103+ overridden with _ non-empty_ values. See below for advice on how to best
104+ override specific metadata fields.
105+ * __ Present the project's metadata simply and clearly.__ For humans, being
106+ able to look at a project POM and clearly see the metadata is very
107+ helpful for understanding the project. Whereas when inheritance is
108+ involved, the human must be patient enough to dig through the ancestor
109+ POMs manually looking for the information, or else knowledgeable enough
110+ to know that they should actually use ` mvn help:effective-pom ` and check
111+ the metadata there instead, to know the actual values.
112+ * __ Make the metadata easier for tooling to consume.__ Maven-based tooling
113+ which uses the interpolated POM will be able to extract the correct
114+ inherited metadata from a POM, sure. But in many cases, it is much
115+ simpler and more natural, especially for Maven non-experts, to code
116+ tooling using shell scripts and similar approaches. In those cases, it is
117+ much easier if the tooling can simply extract the metadata from the child
118+ POM itself and be guaranteed that the values there are the correct ones,
119+ without needing to recurse into parent POMs whose contents may be less
120+ trivial to inspect.
121+ * __ Make it easier to maintain license headers in the sources.__ Putting a
122+ license blurb at the top of each source file is legal best practice, but
123+ it is undeniably a hassle, which is one reason many projects do not
124+ bother. But with the ` license-maven-plugin ` , generating and maintaining
125+ these license headers becomes very easy—as long as the ` inceptionYear ` ,
126+ ` license.projectLicense ` and ` license.copyrightOwners ` values are
127+ provided in the POM. At that point, you can just invoke `mvn
128+ license: update-file-header license: update-project-license ` and your work
129+ is done.
130+ * __ Encourage responsible metadata curation.__ As a project maintainer,
131+ _ you_ are responsible for your project's metadata. Yes, it is a hassle to
132+ specify it. But regardless, you need to understand where (if anywhere)
133+ your project lives in SCM, which (if any) system is being used to
134+ automatically build it, and so on. You have legal and social obligations
135+ to clearly communicate the project license, to clearly document community
136+ expectations, to give credit where credit is due, etc.
137+
138+ The full set of Enforcer rules as of ` pom-scijava-base ` version 3.0.0 can be
139+ [ seen here] ( https://github.com/scijava/pom-scijava-base/blob/pom-scijava-base-3.0.0/pom.xml#L542-L638 ) .
140+
141+ ### How to override a field with an "empty" value
142+
143+ For some projects, you may have "empty" metadata fields, and you may be unsure
144+ how best to override those values accordingly. The most common scenarios are:
145+
146+ * If your project has no contributors, write:
147+ ``` xml
148+ <contributors >
149+ <!--
150+ NB: Need at least one element to override the parent.
151+ See: https://issues.apache.org/jira/browse/MNG-5220
152+ -->
153+ <contributor >
154+ <name >None</name >
155+ </contributor >
156+ </contributors >
157+ ```
158+ * If your project has no discussion forum or mailing list, write:
159+ ```xml
160+ <mailingLists >
161+ <mailingList >
162+ <name >None</name >
163+ </mailingList >
164+ </mailingLists >
165+ ```
166+ But actually, you are warmly welcome to use the
167+ [ImageJ Forum](http://forum.imagej.net/) for discussing your project,
168+ so instead it is better to write:
169+ ```xml
170+ <mailingLists >
171+ <mailingList >
172+ <name >ImageJ Forum</name >
173+ <archive >http://forum.imagej.net/</archive >
174+ </mailingList >
175+ </mailingLists >
176+ ```
177+ * If your project has no CI, write:
178+ ```xml
179+ <ciManagement >
180+ <system >None</system >
181+ </ciManagement >
182+ ```
183+ * If your project has no issue tracker, write:
184+ ```xml
185+ <issueManagement >
186+ <system >None</system >
187+ </issueManagement >
188+ ```
189+ * If your project does not live in SCM, then write:
190+ ```xml
191+ <scm >
192+ <system >None</system >
193+ </scm >
194+ ```
195+ But as an aside, in this case, we strongly encourage you to adopt an SCM;
196+ [check yourself before you wreck yourself](https://imagej.net/Distribution).
197+
26198## Getting help with Maven
27199
28200For more information about Maven, see:
0 commit comments