<commit_before>/*
 * Copyright (C) 2015 KeepSafe Software
 *
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

package com.getkeepsafe.dexcount

import com.android.build.gradle.api.BaseVariantOutput
import com.android.dexdeps.HasDeclaringClass
import com.android.dexdeps.Output
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import org.gradle.api.DefaultTask
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.logging.StyledTextOutput
import org.gradle.logging.StyledTextOutputFactory

class DexMethodCountTask extends DefaultTask {
    @Input
    def BaseVariantOutput apkOrDex

    @OutputFile
    def File outputFileTxt

    @OutputFile
    def File outputFileCSV

    def DexMethodCountExtension config

    @TaskAction
    void countMethods() {
        def tree = getPackageTree()
        def methodCount = tree.getMethodCount()
        def fieldCount = tree.getFieldCount()

        if (outputFileTxt != null) {
            outputFileTxt.parentFile.mkdirs()
            outputFileTxt.createNewFile()
            outputFileTxt.withOutputStream { stream ->
                def appendableStream = new PrintStream(stream)
                print(tree, appendableStream)
                appendableStream.flush()
                appendableStream.close()
            }
        }

        def filename = apkOrDex.outputFile.name
        withStyledOutput(StyledTextOutput.Style.Info) { out ->
            out.println("Total methods in ${filename}: ${methodCount}")
            out.println("Total fields in ${filename}:  ${fieldCount}")
        }

        // Log the entire package list/tree at LogLevel.DEBUG, unless
        // verbose is enabled (in which case use the default log level).
        def level = config.verbose ? null : LogLevel.DEBUG

        withStyledOutput(StyledTextOutput.Style.Info, level) { out ->
            print(tree, out)
        }

        if (config.exportAsCSV && outputFileCSV != null) {
            outputFileCSV.parentFile.mkdirs()
            outputFileCSV.createNewFile()

            if (config.includeFieldCount) {
                outputFileCSV.println("methods,fields")
                outputFileCSV.println("${methodCount},${fieldCount}")
            } else {
                outputFileCSV.println("methods")
                outputFileCSV.println("${methodCount}")
            }
        }
    }

    def print(tree, writer) {
        def opts = getPrintOptions()
        if (config.printAsTree) {
            tree.printTree(writer, opts)
        } else {
            tree.printPackageList(writer, opts)
        }
    }

    private void withStyledOutput(
            StyledTextOutput.Style style,
            LogLevel level = null,
            @ClosureParams(value = SimpleType, options = ['org.gradle.logging.StyledTextOutput']) Closure closure) {
        def factory = services.get(StyledTextOutputFactory)<commit_msg>Fix minor bug in exportAsCSV (output was not written to file)<commit_after>/*
 * Copyright (C) 2015 KeepSafe Software
 *
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

package com.getkeepsafe.dexcount

import com.android.build.gradle.api.BaseVariantOutput
import com.android.dexdeps.HasDeclaringClass
import com.android.dexdeps.Output
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import org.gradle.api.DefaultTask
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.logging.StyledTextOutput
import org.gradle.logging.StyledTextOutputFactory

class DexMethodCountTask extends DefaultTask {
    @Input
    def BaseVariantOutput apkOrDex

    @OutputFile
    def File outputFileTxt

    @OutputFile
    def File outputFileCSV

    def DexMethodCountExtension config

    @TaskAction
    void countMethods() {
        def tree = getPackageTree()
        def methodCount = tree.getMethodCount()
        def fieldCount = tree.getFieldCount()

        if (outputFileTxt != null) {
            outputFileTxt.parentFile.mkdirs()
            outputFileTxt.createNewFile()
            outputFileTxt.withOutputStream { stream ->
                def appendableStream = new PrintStream(stream)
                print(tree, appendableStream)
                appendableStream.flush()
                appendableStream.close()
            }
        }

        def filename = apkOrDex.outputFile.name
        withStyledOutput(StyledTextOutput.Style.Info) { out ->
            out.println("Total methods in ${filename}: ${methodCount}")
            out.println("Total fields in ${filename}:  ${fieldCount}")
        }

        // Log the entire package list/tree at LogLevel.DEBUG, unless
        // verbose is enabled (in which case use the default log level).
        def level = config.verbose ? null : LogLevel.DEBUG

        withStyledOutput(StyledTextOutput.Style.Info, level) { out ->
            print(tree, out)
        }

        if (config.exportAsCSV && outputFileCSV != null) {
            outputFileCSV.parentFile.mkdirs()
            outputFileCSV.createNewFile()

            final String headers = config.includeFieldCount ? "methods,fields" : "methods";
            final String counts = config.includeFieldCount ? "${methodCount},${fieldCount}" : "${methodCount}";

            outputFileCSV.withOutputStream { stream ->
                def appendableStream = new PrintStream(stream)
                appendableStream.println(headers)
                appendableStream.println(counts);
            }
        }
    }

    def print(tree, writer) {
        def opts = getPrintOptions()
        if (config.printAsTree) {
            tree.printTree(writer, opts)
        } else {
            tree.printPackageList(writer, opts)
        }
    }

    private void withStyledOutput(
            StyledTextOutput.Style style,
            LogLevel level = null,
            @ClosureParams(value = SimpleType, options = ['org.gradle.logging.StyledTextOutput']) Closure closure) {
        def factory = services.get(StyledTextOutputFactory)
{'fraction_non_alphanumeric': 0.08517131363573312, 'fraction_numerical': 0.0022194479123318076, 'mean_word_length': 2.6158475426278835, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5012361', 'n_tokens_mistral': 1987, 'n_tokens_neox': 1880, 'n_words': 508}