001/*
002 * Copyright (C) 2015-2021 KeepSafe Software
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package com.getkeepsafe.dexcount.treegen;
017
018import com.getkeepsafe.dexcount.DexCountExtension;
019import com.getkeepsafe.dexcount.PrintOptions;
020import com.getkeepsafe.dexcount.treegen.workers.BaseWorker;
021import org.gradle.api.DefaultTask;
022import org.gradle.api.file.ConfigurableFileCollection;
023import org.gradle.api.file.DirectoryProperty;
024import org.gradle.api.file.RegularFileProperty;
025import org.gradle.api.provider.Property;
026import org.gradle.api.tasks.Classpath;
027import org.gradle.api.tasks.Input;
028import org.gradle.api.tasks.Internal;
029import org.gradle.api.tasks.Nested;
030import org.gradle.api.tasks.OutputDirectory;
031import org.gradle.api.tasks.OutputFile;
032import org.gradle.api.tasks.TaskAction;
033import org.gradle.workers.WorkQueue;
034import org.gradle.workers.WorkerExecutor;
035import org.jetbrains.annotations.NotNull;
036
037import javax.inject.Inject;
038
039public abstract class BaseGeneratePackageTreeTask<P extends BaseWorker.Params, W extends BaseWorker<P>> extends DefaultTask {
040    /**
041     * The plugin configuration, as provided by the 'dexcount' block.
042     */
043    @Nested
044    public abstract Property<DexCountExtension> getConfigProperty();
045
046    /**
047     * The name of the the method-count report file, without a file extension.
048     */
049    @Input
050    public abstract Property<String> getOutputFileNameProperty();
051
052    /**
053     * The full path to the serialized [PackageTree] produced by this task.
054     *
055     * This file is an intermediate representation, not intended for public
056     * consumption.  Its format is likely to change without notice.
057     */
058    @NotNull
059    @OutputFile
060    public abstract RegularFileProperty getPackageTreeFileProperty();
061
062    /**
063     * The directory in which plugin outputs (the report file, summary file,
064     * and charts) will be written.
065     */
066    @OutputDirectory
067    public abstract DirectoryProperty getOutputDirectoryProperty();
068
069    @Internal
070    protected boolean isAndroidProject() {
071        return true;
072    }
073
074    @Classpath
075    public abstract ConfigurableFileCollection getWorkerClasspath();
076
077    @Inject
078    public abstract WorkerExecutor getWorkerExecutor();
079
080    @TaskAction
081    public void execute() {
082        WorkQueue workQueue = getWorkerExecutor().classLoaderIsolation(spec -> {
083            spec.getClasspath().from(getWorkerClasspath());
084        });
085
086        workQueue.submit(getWorkerClass(), this::configureParams);
087    }
088
089    @Internal
090    protected abstract Class<W> getWorkerClass();
091
092    protected void configureParams(P params) {
093        PrintOptions options = PrintOptions.fromDexCountExtension(getConfigProperty().get())
094            .withIsAndroidProject(isAndroidProject());
095
096        params.getOutputFileName().set(getOutputFileNameProperty());
097        params.getPackageTreeFile().set(getPackageTreeFileProperty());
098        params.getOutputDirectory().set(getOutputDirectoryProperty());
099        params.getPrintOptions().set(options);
100    }
101}