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> runOnEachPackageProperty;
031    private final Property<OutputFormat> outputFormatProperty;
032    private final Property<Boolean> includeClassesProperty;
033    private final Property<Boolean> includeClassCountProperty;
034    private final Property<Boolean> includeFieldCountProperty;
035    private final Property<Boolean> includeTotalMethodCountProperty;
036    private final Property<Boolean> orderByMethodCountProperty;
037    private final Property<Boolean> verboseProperty;
038    private final Property<Integer> maxTreeDepthProperty;
039    private final Property<Boolean> teamCityIntegrationProperty;
040    private final Property<String> teamCitySlugProperty;
041    private final Property<Integer> maxMethodCountProperty;
042    private final Property<Boolean> printVersionProperty;
043    private final Property<Boolean> printDeclarationsProperty;
044    private final Property<Boolean> enabledProperty;
045
046    @Inject
047    public DexCountExtension(ObjectFactory objects, ProviderFactory providers) {
048        this.runOnEachPackageProperty = objects.property(Boolean.class).convention(Boolean.TRUE);
049        this.outputFormatProperty = objects.property(OutputFormat.class).convention(OutputFormat.LIST);
050        this.includeClassesProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
051        this.includeClassCountProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
052        this.includeFieldCountProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
053        this.includeTotalMethodCountProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
054        this.orderByMethodCountProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
055        this.verboseProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
056        this.maxTreeDepthProperty = objects.property(Integer.class).convention(Integer.MAX_VALUE);
057        this.teamCityIntegrationProperty = objects.property(Boolean.class).convention(providers.provider(() -> System.getenv("TEAMCITY_VERSION") != null));
058        this.teamCitySlugProperty = objects.property(String.class);
059        this.maxMethodCountProperty = objects.property(Integer.class).convention(-1);
060        this.printVersionProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
061        this.printDeclarationsProperty = objects.property(Boolean.class).convention(Boolean.FALSE);
062        this.enabledProperty = 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 runOnEachPackageProperty;
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 outputFormatProperty;
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 includeClassesProperty;
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 includeClassCountProperty;
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 includeFieldCountProperty;
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 includeTotalMethodCountProperty;
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 orderByMethodCountProperty;
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 verboseProperty;
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 maxTreeDepthProperty;
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 teamCityIntegrationProperty;
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 teamCitySlugProperty;
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 maxMethodCountProperty;
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 printVersionProperty;
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 printDeclarationsProperty;
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 enabledProperty;
191    }
192}