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;
017
018import org.gradle.api.model.ObjectFactory;
019import org.gradle.api.provider.Property;
020import org.gradle.api.provider.ProviderFactory;
021import org.gradle.api.tasks.Input;
022import org.gradle.api.tasks.Internal;
023
024import javax.inject.Inject;
025
026/**
027 * Configuration properties for [DexCountTask] instances.
028 */
029public class DexCountExtension {
030    private final Property<Boolean> runOnEachPackage;
031    private final Property<OutputFormat> outputFormat;
032    private final Property<Boolean> includeClasses;
033    private final Property<Boolean> includeClassCount;
034    private final Property<Boolean> includeFieldCount;
035    private final Property<Boolean> includeTotalMethodCount;
036    private final Property<Boolean> orderByMethodCount;
037    private final Property<Boolean> verbose;
038    private final Property<Integer> maxTreeDepth;
039    private final Property<Boolean> teamCityIntegration;
040    private final Property<String> teamCitySlug;
041    private final Property<Integer> maxMethodCount;
042    private final Property<Boolean> printVersion;
043    private final Property<Boolean> printDeclarations;
044    private final Property<Boolean> enabled;
045
046    @Inject
047    public DexCountExtension(ObjectFactory objects, ProviderFactory providers) {
048        this.runOnEachPackage = objects.property(Boolean.class).convention(Boolean.TRUE);
049        this.outputFormat = objects.property(OutputFormat.class).convention(OutputFormat.LIST);
050        this.includeClasses = objects.property(Boolean.class).convention(Boolean.FALSE);
051        this.includeClassCount = objects.property(Boolean.class).convention(Boolean.FALSE);
052        this.includeFieldCount = objects.property(Boolean.class).convention(Boolean.FALSE);
053        this.includeTotalMethodCount = objects.property(Boolean.class).convention(Boolean.FALSE);
054        this.orderByMethodCount = objects.property(Boolean.class).convention(Boolean.FALSE);
055        this.verbose = objects.property(Boolean.class).convention(Boolean.FALSE);
056        this.maxTreeDepth = objects.property(Integer.class).convention(Integer.MAX_VALUE);
057        this.teamCityIntegration = objects.property(Boolean.class).convention(providers.provider(() -> System.getenv("TEAMCITY_VERSION") != null));
058        this.teamCitySlug = objects.property(String.class);
059        this.maxMethodCount = objects.property(Integer.class).convention(-1);
060        this.printVersion = objects.property(Boolean.class).convention(Boolean.FALSE);
061        this.printDeclarations = objects.property(Boolean.class).convention(Boolean.FALSE);
062        this.enabled = objects.property(Boolean.class).convention(Boolean.TRUE);
063    }
064
065    /**
066     * When false, does not automatically count methods following the `package` task.
067     */
068    @Internal("plugin input, not task input")
069    public Property<Boolean> getRunOnEachPackage() {
070        return runOnEachPackage;
071    }
072
073    /**
074     * The format of the method count output, either "list", "tree", "json", or "yaml".
075     */
076    @Input
077    public Property<OutputFormat> getFormat() {
078        return outputFormat;
079    }
080
081    /**
082     * When true, individual classes will be include in the package list - otherwise, only packages
083     * are included.
084     */
085    @Input
086    public Property<Boolean> getIncludeClasses() {
087        return includeClasses;
088    }
089
090    /**
091     * When true, the number of classes in a package or class will be included in the printed output.
092     */
093    @Input
094    public Property<Boolean> getIncludeClassCount() {
095        return includeClassCount;
096    }
097
098    /**
099     * When true, the number of fields in a package or class will be included in the printed output.
100     */
101    @Input
102    public Property<Boolean> getIncludeFieldCount() {
103        return includeFieldCount;
104    }
105
106    /**
107     * When true, the total number of methods in the application will be included in the printed
108     * output.
109     */
110    @Input
111    public Property<Boolean> getIncludeTotalMethodCount() {
112        return includeTotalMethodCount;
113    }
114
115    /**
116     * When true, packages will be sorted in descending order by the number of methods they contain.
117     */
118    @Input
119    public Property<Boolean> getOrderByMethodCount() {
120        return orderByMethodCount;
121    }
122
123    /**
124     * When true, the output file will also be printed to the build's standard output.
125     */
126    @Internal
127    public Property<Boolean> getVerbose() {
128        return verbose;
129    }
130
131    /**
132     * Sets the max number of package segments in the output - i.e. when set to 2, counts stop at
133     * com.google, when set to 3 you get com.google.android, etc. "Unlimited" by default.
134     */
135    @Input
136    public Property<Integer> getMaxTreeDepth() {
137        return maxTreeDepth;
138    }
139
140    /**
141     * When true, Team City integration strings will be printed. If the TEAMCITY_VERSION System
142     * environment variable is defined this will become true by default.
143     */
144    @Internal("TeamCity stats are stdout-only")
145    public Property<Boolean> getTeamCityIntegration() {
146        return teamCityIntegration;
147    }
148
149    /**
150     * A string which, if specified, will be added to TeamCity stat names. Null by default.
151     */
152    @Internal("TeamCity stats are stdout-only")
153    public Property<String> getTeamCitySlug() {
154        return teamCitySlug;
155    }
156
157    /**
158     * When set, the build will fail when the APK/AAR has more methods than the max. 0 by default.
159     */
160    @Input
161    public Property<Integer> getMaxMethodCount() {
162        return maxMethodCount;
163    }
164
165    /**
166     * If the user has passed '--stacktrace' or '--full-stacktrace', assume that they are trying to
167     * report a dexcount bug. Help us help them out by printing the current plugin title and version.
168     */
169    @Internal("stdout-only")
170    public Property<Boolean> getPrintVersion() {
171        return printVersion;
172    }
173
174    /**
175     * When true, then the plugin only counts the declared methods and fields inside this module.
176     * This does NOT represent the actual reference method count, because method references are
177     * ignored. This flag is false by default and can only be turned on for library modules.
178     */
179    @Input
180    public Property<Boolean> getPrintDeclarations() {
181        return printDeclarations;
182    }
183
184    /**
185     * When true, the plugin is enabled and will be run as normal.  When false,
186     * the plugin is disabled and will not be run.
187     */
188    @Internal("this is plugin input, not task input")
189    public Property<Boolean> getEnabled() {
190        return enabled;
191    }
192}