This CLI tool is designed to help Android developers produce the best XML layouts they can. This tool runs a variety of rules against the given files to ensure certain styles are adhered to. These rules are styles we adhere to within our team. Yours may (and probably will) be different, so why not fork this project and add your own. Our intention is not to impose a style guide, but to offer a tool to help you stick to yours.
Add the jar to your project found on the releases page.
You must specify the path you wish to run the rules on:
xmlcheck ./src/main/res/layout
-h
--help
- Show help (e.g.xmlcheck --help
).-x
--exclude
- The rules you want to exclude (e.g.xmlcheck ./src/main/res/layout --exclude Rule1,Rule2
).--fail-on-empty
or--no-fail-on-empty
- Whether or not you want the checks to fail if you provide an empty or non-existent path (e.g.xmlcheck ./src/main/res/layout --fail-on-empty
). Defaults to failing on empty.
Ensure that all buttons are MaterialButton
's rather than normal Button
's. This is important if you are implementing a MaterialComponents theme.
android:textSize
should be specified in sp.
android:id
should start with @+id/
.
android:id
should adhere to our naming conventions.
Generally we should start our id's with the first word of the class name e.g. image_something
. There are some specific exceptions though which can be found within the rule: src/main/kotlin/uk/co/brightec/xmlcheck/rules/attr/android/Id.kt
.
All heights should follow the 2's rule i.e. 2, 4, 6, 8, 12, 16, 24, 32, 64. Or be wrap_content, match_parent, etc.
All widths should follow the 2's rule i.e. 2, 4, 6, 8, 12, 16, 24, 32, 64. Or be wrap_content, match_parent, etc.
All margins should follow the 2's rule i.e. 2, 4, 6, 8, 12, 16, 24, 32, 64.
All references to id's should start with @+id/
.
All colors should be specified in resources rather than hex.
In addition to being able to exclude a rule, you can also suppress specific instances by adding tools:ignore="Rule1,Rule2"
.
To add your own rules, fork this project and add away. Why not share them with us too, by submitting an issue.
We have two types of rules, attribute and element. Attribute rules define a rule for an XML attribute and Element for the entire XML element.
Let's say we wanted to add an attribute rule for the android:text
attribute. We want all our text to always contain I Love XML
.
First, we will add the class for a new AttrRule
for the android:text
attribute.
src/main/kotlin/uk/co/brightec/xmlcheck/rules/attr/android/TextLoveXml.kt
package uk.co.brightec.xmlcheck.rules.attr.android
import org.w3c.dom.Attr
import uk.co.brightec.xmlcheck.Constants.ATTR_NAMESPACE_ANDROID
import uk.co.brightec.xmlcheck.Failure
import uk.co.brightec.xmlcheck.rules.attr.AttrRule
class TextLoveXml : AttrRule(
name = "TextLoveXml",
attrName = "$ATTR_NAMESPACE_ANDROID:text"
) {
override fun run(node: Attr): Failure<Attr>? {
// ...
}
}
We subclass AttrRule
and then override the required methods.
name
- The name of your ruleattrName
orattrNames
- The attribute(s) this rule should apply to i.e.android:text
run()
- This is where we will actually implement our rule logic
To implement our rule we adjust the run()
implementation.
override fun run(node: Attr): Failure<Attr>? {
return if (node.value.contains("I Love XML")) {
null
} else {
failure(node, "All text should love XML")
}
}
We need to check whether this attribute has violated the rule. If it has, we need to return a Failure
, if not then return null
.
Within uk.co.brightec.xmlcheck.Checker.kt
, we add our new attribute rule to the allAttrRules
list.
private val allAttrRules: List<AttrRule> = arrayListOf(
// ...
TextLoveXml()
)
Now XMLCheck is aware of our rule, and we can run XMLCheck and our new rule will be checked against.
We have two kinds of tests within the project. Unit and EndToEnd. Within Unit tests we mock an attribute and then assert various cases about our rule. Within EndToEnd, we run our rules against an XML file and verify the expected output (i.e. command line output).
Checkout some of the tests we have already written for an example of how to tests for your new rules.
There are a few gradle tasks to aid with development and distribution
installAndRun
- This installs the current state of the project and runs it against the XML files withinsrc/test/resources/files/cases/
installAndHelp
- This installs the current state of the project and runs the help commandcheck
- This runs all the tests and checks against the projectdistJar
- Creates a jar file for distribution which can be found withinbuild/distributions/
distTar
- Creates a tar file for distribution which can be found withinbuild/distributions/
distZip
- Creates a zip file for distribution which can be found withinbuild/distributions/
- Kotlin
- Clikt - Clikt (pronounced “clicked”) is a Kotlin library that makes writing command line interfaces simple and intuitive. It is the “Command Line Interface for Kotlin”. I have really enjoyed using this library, it makes writing command line interfaces very simple.
- JUnit5 - JUnit5 has helped make the testing simple and easier (especially having parameterized tests).
- Mockk - Mockk is our mocking framework of choice for Kotlin.
See license
Alistair Sykes - Github Medium Twitter
This tool is maintained by the Brightec team