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

Licenses are missing in multi-module/multi-flavor project #474

Closed
ar-g opened this issue Feb 27, 2020 · 14 comments
Closed

Licenses are missing in multi-module/multi-flavor project #474

ar-g opened this issue Feb 27, 2020 · 14 comments
Assignees

Comments

@ar-g
Copy link

ar-g commented Feb 27, 2020

About this issue

Some of the licenses are missing in our multi-module/multi-flavor project.

I've run this code:

val noLicenses = libraries.filter { it.license == null || it.license?.licenseName?.isEmpty() ?: false }.map { it.libraryName }
        Log.d("licenses", noLicenses.joinToString { "$it\n" })

and got:

      AppsFlyerSDK
    , Android SDK Answers
    , Facebook-Common-Android-SDK
    , Facebook-Core-Android-SDK
    , Facebook-Login-Android-SDK
    , Stetho
    , Stetho OkHttp 3 module
    , Jackson-annotations
    , Aspsine/FragmentNavigator
    , robotoworks/composter
    , AutoValue Annotations
    , Gson
    , Guava InternalFutureFailureAccess and InternalFutures
    , Guava: Google Core Libraries for Java
    , Guava ListenableFuture only
    , Protocol Buffers [Lite]
    , ZXing Core
    , Onfido Android SDK Core
    , Bolts-Android
    , Bolts-AppLinks
    , Bolts-Tasks
    , OkHttp Logging Interceptor
    , MockWebServer
    , OkHttp
    , OkHttp URLConnection
    , OkHttp Logging Interceptor
    , OkHttp
    , Okio
    , Picasso
    , Adapter: RxJava 2
    , Converter: Gson
    , Converter: Java Scalars
    , Retrofit
    , Mobile Chat SDK
    , Mobile Chat API
    , Apache Commons CLI
    , Animal Sniffer Annotations
    , Hamcrest Core
    , reactive-streams
    , SLF4J API Module
    , ThreeTen backport

I've also checked generated xml, for example for okhttp:

<string name="define_plu_com_squareup_okhttp__okhttp"></string>
  <string name="library_com_squareup_okhttp__okhttp_libraryName">OkHttp</string>
  <string name="library_com_squareup_okhttp__okhttp_libraryDescription"><![CDATA[]]></string>
  <string name="library_com_squareup_okhttp__okhttp_libraryVersion"></string>
  <string name="library_com_squareup_okhttp__okhttp_libraryArtifactId">com.squareup.okhttp:okhttp:</string>
@mikepenz
Copy link
Owner

@ar-g which version of the library do you use? how did you set it up?

Libraries are generally merged from all the different flavors, and should also cover all transitive dependencies.

Do you have by coincidence the whole xml generated?

okhttp is a known special case as there is some topic with their POM file.

@adrianlandborn
Copy link

I can add my input on this matter. Yes, there are lots of libs that are missing since POM files are incomplete and does not follow the standards. I am not running a multi-flavor setup by these are the ones missing on my side.

  • Android SDK Answers
  • fbjni
  • SoLoader
  • SoLoader
  • SoLoader
  • Stetho
  • AutoValue Annotations
  • Commons CLI
  • reactive-streams
  • ThreeTen back port

No, maybe it is not the proper way to solve this but is how we solve this.

 LibsBuilder()
       .withActivityTitle(getString(R.string.settings_licenses_open_source))
       .withAboutIconShown(true)
       .withAboutVersionShown(false)
       .withAboutAppName(getString(R.string.app_name))
       .withLicenseShown(true)
       .withLibraryEnchantment("com_facebook_stetho__stetho", "xcom_facebook_stetho__stetho")
       .withLibraryEnchantment("com_facebook_soloader__nativeloader", "xcom_facebook_soloader__nativeloader")
       .withLibraryEnchantment("com_facebook_soloader__soloader", "xcom_facebook_soloader__soloader")
       .withLibraryEnchantment("com_facebook_soloader__annotation", "xcom_facebook_soloader__annotation")
      .withLibraryEnchantment("com_google_auto_value__auto_value_annotations",
                    "xcom_google_auto_value__auto_value_annotations")
      .withLibraryEnchantment("commons_cli__commons_cli", "xcommons_cli__commons_cli")
      .withLibraryEnchantment("com_facebook_fbjni__fbjni", "xcom_facebook_fbjni__fbjni")
      .withLibraryEnchantment("org_reactivestreams__reactive_streams",
                    "xorg_reactivestreams__reactive_streams")
      .withLibraryEnchantment("org_threeten__threetenbp", "xorg_threeten__threetenbp")
      .activity(requireContext())

And then have the new licence texts in a resources file:

```
<string name="define_xcom_facebook_soloader__nativeloader" tools:ignore="UnusedResources">owner</string>
<string name="library_xcom_facebook_soloader__nativeloader_libraryName" tools:ignore="UnusedResources">SoLoader</string>
<string name="library_xcom_facebook_soloader__nativeloader_licenseId" tools:ignore="UnusedResources">apache_2_0</string>

@mikepenz
Copy link
Owner

For okhttp3 we already have a proper patching applied, will add okhttp to the list

Note for only patching the licenses we maintain a list to allow patching these, so if you may provide the list of identifiers for those libraries we could enhance the list:

https://github.com/mikepenz/AboutLibraries/blob/develop/library-definitions/src/main/res/raw/custom_license_mappings.prop

Btw it is also possible to provide your own custom license mapping too. See here: https://github.com/mikepenz/AboutLibraries#gradle-plugin-configuration

Beside the described approach by @adrianlandborn which works great there is also a way to modify informations on a per field basis:

.withLibraryModification("androidx_activity__activity", Libs.LibraryFields.LIBRARY_NAME, "Activity Support")

This would allows to provide license name, description, url for the website:
image

@mikepenz mikepenz removed the bug label Feb 28, 2020
@ar-g ar-g changed the title Licenses are missing in multi-module/multi-flavor support Licenses are missing in multi-module/multi-flavor project Feb 28, 2020
@ar-g
Copy link
Author

ar-g commented Feb 28, 2020

The plugin is applied to the app module.

This one included into root Gradle file:

        classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:8.0.0-rc01"

@mikepenz
Copy link
Owner

@ar-g please see @adrianlandborn and my answer. so it looks like parts of your libraries simply do not have their POM file incomplete in the providing repositories. meaning that for these the only approach is a manual one.

you can add missing information as noted above.

but you may also provide a list with all libraries and their licenses so we can look into it:

./gradlew exportLibraries

will output the info in the log :) if you have something sensitive in here which you may do not want to share publicly you may also be able to send me an e-mail with the output

@ar-g
Copy link
Author

ar-g commented Mar 2, 2020

I was only able to add license through

            .withLibraryEnchantment("com_squareup_okhttp__okhttp", "xcom_squareup_okhttp__okhttp")
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <string name="define_xcom_squareup_okhttp__okhttp" tools:ignore="UnusedResources">owner</string>
    <string name="library_xcom_squareup_okhttp__okhttp_licenseId">Apache_2_0</string>
    <string name="library_xcom_squareup_okhttp__okhttp_libraryName">OkHttp</string>
    <string name="library_xcom_squareup_okhttp__okhttp_libraryDescription"><![CDATA[]]></string>
    <string name="library_xcom_squareup_okhttp__okhttp_libraryArtifactId">com.squareup.okhttp:okhttp:</string>
</resources>

Gradle Plugin config didn't work for me.

I'm going to add all those 42 licenses manually to the xml file and config.

@mikepenz
Copy link
Owner

mikepenz commented Mar 2, 2020

What did you try via the gradle plugin config? @ar-g I'd be curious to perhaps see if we can improve something here

@ar-g
Copy link
Author

ar-g commented Mar 6, 2020

@mikepenz I just copied library definitions, modified okhttp to point apache_2_0 license and turned on configuration for the AboutLibraries gradle plugin.

@ar-g
Copy link
Author

ar-g commented Mar 6, 2020

Now, we have another issue. This is how the generated folder looks like

Screenshot 2020-03-06 at 23 24 30

The problem is that there is no license description, and XML file with license looks like this:

<resources>
  <string name="define_license_Apache_2_0"></string>
  <string name="license_Apache_2_0_licenseName">Apache License 2.0</string>
  <string name="license_Apache_2_0_licenseWebsite">https://spdx.org/licenses/Apache-2.0.html</string>
</resources>

@mikepenz
Copy link
Owner

mikepenz commented Mar 8, 2020

@ar-g not sure if it is too much to ask. but perhaps it would be possible if you could remove all the application code and just keep the dependencies and the adjustments you made so that I can try and see why the apache license may no longer be used from the plugin but instead from the auto generated spec according to the spdx list

@ar-g
Copy link
Author

ar-g commented Mar 9, 2020

I'm using a standard configuration of Gradle plugin:

//root gradle file
buildscript {
    dependencies {
        classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:8.0.0-rc02"
}}
//app main module gradle file
plugins {
    id 'com.mikepenz.aboutlibraries.plugin'
}
dependencies {
    implementation "com.mikepenz:aboutlibraries-core:8.0.0-rc02"
    implementation "com.mikepenz:aboutlibraries:8.0.0-rc02
}

I'm wondering how to debug this plugin 🤔

@mikepenz
Copy link
Owner

mikepenz commented Mar 9, 2020

@ar-g so usually I use uploadArchives to publish it to my local maven (with a new version number) and then try to use it from the sample app.

(upload archives is available within the plugin sub project)

Debugging itself.. I tent to put log outputs and check the good old fashioned way. if there is a muc better way to get debugging and stuff working in AS I would be happy as it could speed up additionally

@ar-g
Copy link
Author

ar-g commented Mar 11, 2020

I was able to do a bit of progress with debugging plugin.

Basically, I was running
gradle clean && gradle prepareLibraryDefinitions

When I was running latest published rc-02 version, the output was

<resources>
  <string name="define_license_Apache_2_0"></string>
  <string name="license_Apache_2_0_licenseName">Apache License 2.0</string>
  <string name="license_Apache_2_0_licenseWebsite">https://spdx.org/licenses/Apache-2.0.html</string>
</resources>

Then I've made some changes to the gradle plugin, mainly commented part of it:

class AboutLibrariesPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        // create the config possible
        project.extensions.create('aboutLibraries', AboutLibrariesExtension)

        File outputFile = project.file("$project.buildDir/generated/aboutlibraries/res/")

        // task for cleaning
        def cleanupTask = project.tasks.create("aboutLibrariesClean", AboutLibrariesCleanTask)
        cleanupTask.description = "Cleans the generated data from the AboutLibraries plugin"
        cleanupTask.dependencies = outputFile
        project.tasks.findByName("clean").dependsOn(cleanupTask)

        // task to write the general definitions information
        AboutLibrariesTask task = project.tasks.create("prepareLibraryDefinitions", AboutLibrariesTask)
        task.description = "Writes the relevant meta data for the AboutLibraries plugin to display dependencies"
        task.setDependencies(outputFile)

        /*project.android.applicationVariants.all { variant ->
            // This is necessary for backwards compatibility with versions of gradle that do not support
            // this new API.
            if (variant.hasProperty("preBuildProvider")) {
                variant.preBuildProvider.configure { dependsOn(task) }
            } else {
                //noinspection GrDeprecatedAPIUsage
                variant.preBuild.dependsOn(task)
            }

            // This is necessary for backwards compatibility with versions of gradle that do not support
            // this new API.
            if (variant.respondsTo("registerGeneratedResFolders")) {
                task.ext.generatedResFolders = project.files(task.getDependencies()).builtBy(task)
                variant.registerGeneratedResFolders(task.generatedResFolders)

                if (variant.hasProperty("mergeResourcesProvider")) {
                    variant.mergeResourcesProvider.configure { dependsOn(task) }
                } else {
                    //noinspection GrDeprecatedAPIUsage
                    variant.mergeResources.dependsOn(task)
                }
            } else {
                //noinspection GrDeprecatedAPIUsage
                variant.registerResGeneratingTask(task, task.getDependencies())
            }
        }*/

        // task to output library names with ids for further actions
        AboutLibrariesIdTask taskId = project.tasks.create("findLibraries", AboutLibrariesIdTask)
        taskId.description = "Writes the relevant meta data for the AboutLibraries plugin to display dependencies"

        // task to output libraries and their license in CSV format to the CLI
        AboutLibrariesExportTask exportTaskId = project.tasks.create("exportLibraries", AboutLibrariesExportTask)
        exportTaskId.description = "Writes all libraries and their license in CSV format to the CLI"
    }
}

Now the license file is generated propperly when run
gradle clean && gradle prepareLibraryDefinitions:

<?xml version="1.0" encoding="utf-8"?>
<resources translatable="false">

    <string name="define_license_Apache_2_0"></string>
    <string name="license_Apache_2_0_licenseName">Apache Version 2.0</string>
    <string name="license_Apache_2_0_licenseWebsite">http://www.apache.org/licenses/LICENSE-2.0.html</string>
    <string name="license_Apache_2_0_licenseShortDescription">
        <![CDATA[
        Copyright &#169; <<<YEAR>>>, <<<OWNER>>>
        <br />
        All rights reserved.
        <br /><br />
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at
        <br /><br />
        http://www.apache.org/licenses/LICENSE-2.0
        <br /><br />
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
        ]]>
    </string>
    <string name="license_Apache_2_0_licenseDescription">raw:license_apache_2_0</string>

</resources>

@mikepenz
Copy link
Owner

I believe with v8.0.0-rc03 I may have been able to fix various problems.

Not sure about the task problem you were seeing, as this seems to not occur in the projects I have.

I have though added a new task for your usecase to directly execute the generation to circumstance the code you commented out

./gradlew generateLibraryDefinitions

I think with v8.0.0-rc03 the main issue should be resolved and we can close this.
If not please let me know and we can look further

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants