Librarian
Librarian is generate notice that library used in gradle module
Librarian focuses on:
- Aggregate artifacts as Group by same library
- Accurately aggregate the library
- Automation as much as possible with prepared preset information
- Aggregate configurations as Page, generate multiple notice files
Table of Contents
Required
- Gradle 5.5 or over
- (if you develop Android app) Android Studio and Android Gradle Plugin 3.5 or over
Upgrade Gradle version
- open project folder
- move
gradle/wrapper/gradle-wrapper.properties
- upgrade gradle version
- for example:
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
- for example:
Getting started
Install
Librarian is published on GitHub Packages and Bintray. So you choice maven repository.
using Bintray:
buildscript {
repositories {
maven { url "https://dl.bintray.com/meilcli/librarian" }
}
}
using GitHub Packages:
buildscript {
repositories {
maven {
url "https://maven.pkg.github.com/MeilCli/Librarian"
credentials {
username System.getenv("GITHUB_USER")
password System.getenv("GITHUB_TOKEN") // token has permission of read:packages
}
}
}
}
And set classpath:
buildscript {
dependencies {
classpath "net.meilcli.librarian:plugin-core:VERSION" // replace VERSION
classpath "net.meilcli.librarian:plugin-preset:VERSION" // replace VERSION
}
}
And apply plugin your project:
apply plugin: 'librarian'
apply plugin: 'librarian-preset'
Task
- librarian plugin
- librarianGenerateArtifacts
- librarianGenerateGroups
- librarianGenerateBintrayGroups
- librarianGeneratePages
- librarianGeneratePipeline
- librarianShowConfigurations
- librarianShowModuleConfigurations
- librarianShowFirstDependencies
- librarianShowAllDependencies
- librarianShowFirstConfigurationDependencies
- librarianShowAllConfigurationDependencies
- librarianShowFilteredDependencyGraph
- librarian preset plugin
Configuration
librarian {
dataFolderName = "Library" // String, default value is Library
depth = "firstLevel" // String, firstLevel or allLevel, default value is firstLevel
failOnGeneratePageWhenFoundPlaceholder = true // Boolean, default value is true
failOnOverrideUnMatchedLicense = true // Boolean, default value is true
failOnTooManyResolvingConfigurationLimit = 1000 // Int, default value is 1000
useBintray = false // Boolean, default value is false
ignoreArtifacts = [] // Array of String
pages {
"plugin-core-usings-plugin" { // page name, must be unique
title = "Librarian plugin-core's using libraries" // String?, default value is same the name
description = null // String?, default value is null
markdown = true // Boolean, default value is null
markdownFileName = "README.md" // String, default value is README.md
json = true // Boolean, default value is null
jsonFileName = "notices.json" // String, default value is notices.json
jsonAdditionalOutputPath = null // File, default is null
configurations {
exact {
value = [""] // Array of String
}
contain {
value = [""]
}
exact { value = [""] } // exact and contain can be multiple
}
additionalNotices {
"AdditionalNotice" { // Notice name
artifacts = ["text:com"] // Array of String, default is empty
author = "Tester" // String, default is empty, must set value
url = "https://google.com" // String, default is empty, must set value
description = "" // String?, default value is null
licenses {
"MIT" { // License name, must set value
url = "https://google.com" // String, default is empty, must set value
}
}
}
}
}
}
groups {
"Kotlin" { // group name, must be unique
artifacts = [
"org.jetbrains.kotlin:kotlin-gradle-plugin",
"org.jetbrains.kotlin:kotlin-serialization",
"org.jetbrains.kotlin:kotlin-stdlib-jdk7"
] // Array of String, default is empty list
author = null // String?, default value is null
url = null // String?, default value is null
description = null // String?, default value is null
licenseName = null // String?, default value is null
licenseUrl = null // String?, default value is null
}
}
}
path | summary |
---|---|
librarian.dataFolderName | output root folder name |
librarian.depth | search dependency depth, firstLevel find your directly dependency |
librarian.failOnGeneratePageWhenFoundPlaceholder | fail on librarianGeneratePages when found placeholder |
librarian.failOnOverrideUnMatchedLicense | fail on override un matched license by group |
librarian.failOnTooManyResolvingConfigurationLimit | fail limit that resolving configurations too many, multi module project will be increase exponentially |
librarian.useBintray | if true, actually use Bintray api at librarianGenerateBintrayGroups task, this feature is alpha |
librarian.ignoreArtifacts | ignore notice of maven artifact, ignore by prefix match |
Generate Notice Page
- install Librarian
- configure your project, put
pages
librarianShowConfigurations
task helps when configure your project
- set
false
tolibrarian.failOnGeneratePageWhenFoundPlaceholder
- execute
librarianGeneratePresetPipeline
task - if console output error or incomplete result, configure your project that put
groups
- set
true
tolibrarian.failOnGeneratePageWhenFoundPlaceholder
- execute
librarianGeneratePresetPipeline
task
Android Viewer
Librarian is prepared Android Viewer library
ui-core
: core of UI, including some interface, NoticesView and NoticeViewui-activity
: wrap of core, for easily usage of Activityui-fragment
: wrap of core, for easily usage of Fragmentui-serializer-**
: serializer implementation of some Json Serializer Library
Getting started of ui-activity
install UI Library:
dependencies {
implementation "net.meilcli.librarian:ui-activity:VERSION" // replace VERSION
implementation "net.meilcli.librarian:ui-serializer-kotlin:VERSION" // replace VERSION and serializer
}
configure Librarian:
apply plugin: 'librarian'
apply plugin: 'librarian-preset'
librarian {
pages {
"sample-from-maven" {
title = "Using Libraries"
description = "sample-from-maven is using this libraries."
configurations {
contain {
value = [
"implementationDependenciesMetadata",
"releaseImplementationDependenciesMetadata"
]
}
}
jsonAdditionalOutputPath = file("src/main/assets/notices.json")
}
}
}
register activity:
<application>
<!-- Replace your NoActionBar style -->
<activity
android:name="net.meilcli.librarian.activities.NoticesActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name="net.meilcli.librarian.activities.NoticeActivity"
android:theme="@style/AppTheme.NoActionBar" />
</application>
register listener:
button.setOnClickListener {
startActivity(NoticesActivity.createIntent(this, NoticesReader(), "notices.json"))
}
Serializers
- KotlinX Serialization:
ui-serializer-kotlin
- Moshi:
ui-serializer-moshi
- Gson:
ui-serializer-gson
Samples
- Using
ui-core
: sample/sample-ui-core - Using
ui-activity
: sample/sample-ui-activity - Using
ui-fragment
: sample/sample-ui-fragment - Using Dynamic Feature Module: sample/sample-dynamic-app
- Custom style: sample/sample-ui-custom
Other
Create Viewer
Tips
About the mechanism of page configuration
Librarian can select configurations that including dependencies to notify on every page
in normal case, project has some configurations such as:
implementationDependenciesMetadata
testImplementationDependenciesMetadata
classpath
- etc..
the dependencies
block configuration adds dependencies to these configurations. you can see configurations that has dependencies by librarianShowConfigurations
task
add configuration names that want to notify at page to pages.configurations
block. in normal case, you can use contain
block
in nested module case, you can set exact configuration name order, and librarianShowFilteredDependencyGraph
task show configuration name order
example table:
configurations | contain("releaseRuntimeClasspath", "apiDependenciesMetadata") | exact("releaseRuntimeClasspath", "apiDependenciesMetadata") |
---|---|---|
releaseRuntimeClasspath => releaseApiDependenciesMetadata | |
|
releaseRuntimeClasspath => releaseRuntimeClasspath | |
|
releaseRuntimeClasspath => apiDependenciesMetadata | |
|
contain
: whether configuration names is contained in valueexact
: whether configuration names is equaled to value
Add android dynamic feature module dependency notices
in the case of android dynamic feature module, dependency graph is different from normal case
dynamic feature module configuration names is the starting point about releaseReverseMetadataValues
(different every build flavor)
see sample: sample/sample-dynamic-app
Cannot auto generate because Librarian dose not infer some information
Sometimes, Librarian dose not infer Library information when not enough pom file
You can compensate information by using Library groups. Library groups is prepared originally for aggregation artifacts, but can use as to override information your hand
example:
librarian {
groups {
"Kotlin" { // group name, must be unique
artifacts = [
"org.jetbrains.kotlin:kotlin-gradle-plugin",
"org.jetbrains.kotlin:kotlin-serialization",
"org.jetbrains.kotlin:kotlin-stdlib-jdk7"
] // Array of String, default is empty list
author = null // String?, default value is null
url = null // String?, default value is null
description = null // String?, default value is null
licenseName = null // String?, default value is null
licenseUrl = null // String?, default value is null
}
}
}
Or, can request preset here
Add image resource license notice
Sometimes, developers must notify image resource licence or else. Librarian can add notice apart from maven artifact
example of Material design icons:
librarian {
pages {
"example" { // page name
additionalNotices {
"Material design icons" { // Notice name
artifacts = []
author = "Google Inc."
url = "https://github.com/google/material-design-icons"
description = "Material Design icons by Google" // optional
licenses {
"Apache License 2.0" {
url = "https://github.com/google/material-design-icons/blob/master/LICENSE"
}
}
}
}
}
}
}
Cannot resolve pom file
Sometimes, Librarian cannot resolve pom file. In most cases it's because Maven Repository URL is not set to module's build.gradle.
Librarian task aggregate root build.gradle's buildscript. in time, if it is only set to root build.gradle's buildscript, problems will occur.
GitHub Actions
if you use GitHub Actions, recommend use GitHub Packages when CI Build
switch maven repository by environment variables:
buildscript {
repositories {
def githubUser = System.getenv("GITHUB_USER")
def githubToken = System.getenv("GITHUB_TOKEN")
if (githubUser != null && githubToken != null) {
maven {
url "https://maven.pkg.github.com/MeilCli/Librarian"
credentials {
username githubUser
password githubToken
}
}
} else {
maven { url "https://dl.bintray.com/meilcli/librarian" }
}
}
}
set environment your workflow
jobs:
build:
env:
GITHUB_USER: "github-bot"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Auto Generate Notice Page and Create Pull Request
using peter-evans/create-pull-request example:
name: CI
on:
push:
branches:
- '*'
tags-ignore:
- '*'
jobs:
librarian:
runs-on: ubuntu-latest
env:
GITHUB_USER: "github-bot"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant permission
run: chmod +x gradlew
- run: ./gradlew librarianGeneratePresetPipeline
- name: Create Pull Request
uses: peter-evans/create-pull-request@v2
with:
commit-message: "update library notices"
title: "update library notices"
Contributing
see Contributing.md. if you think to report issue, select Issue Template
License
Librarian is MIT License
Using Libraries
Each notices is located in the Library folder
artifact name | including binary libraries | using when developing |
---|---|---|
plugin-core |
plugin-core-usings-plugin | plugin-core-usings-development |
plugin-preset |
plugin-preset-usings-plugin | plugin-preset-usings-development |
ui-core |
ui-core-usings-library | ui-core-usings-development |
ui-activity |
ui-activity-usings-library | ui-activity-usings-development |
ui-fragment |
ui-fragment-usings-library | ui-fragment-usings-development |
ui-serializer-kotlin |
ui-serializer-kotlin-usings-library | ui-serializer-kotlin-usings-development |
ui-serializer-moshi |
ui-serializer-moshi-usings-library | ui-serializer-moshi-usings-development |
ui-serializer-gson |
ui-serializer-gson-usings-library | ui-serializer-gson-usings-development |