<commit_before>package com.athaydes.gradle.osgi

import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging

import java.util.zip.ZipEntry
import java.util.zip.ZipFile

import static java.util.Collections.emptyList

/**
 *
 */
class OsgiRuntimeTaskCreator {

    static final Logger log = Logging.getLogger( OsgiRuntimeTaskCreator )

    Closure createOsgiRuntimeTask( Project project, OsgiConfig osgiConfig ) {
        return {
            String target = getTarget( project, osgiConfig )
            osgiConfig.outDirFile = target as File
            log.info( "Will copy osgi runtime resources into $target" )
            configBundles( project, osgiConfig )
            copyBundles( project, "${target}/${osgiConfig.bundlesPath}" )
            configMainDeps( project, osgiConfig )
            copyMainDeps( project, target )
            copyConfigFiles( target, osgiConfig )
        }
    }

    private void configMainDeps( Project project, OsgiConfig osgiConfig ) {
        def hasOsgiMainDeps = !project.configurations.osgiMain.dependencies.empty
        if ( !hasOsgiMainDeps ) {
            assert osgiConfig.osgiMain, 'No osgiMain provided, cannot create OSGi runtime'
            project.dependencies.add( 'osgiMain', osgiConfig.osgiMain )
        }
    }

    private void copyMainDeps( Project project, String target ) {
        project.copy {
            from project.configurations.osgiMain
            into target
        }
    }

    private void configBundles( Project project, OsgiConfig osgiConfig ) {
        def allBundles = osgiConfig.bundles.flatten()
        project.configurations { c ->
            allBundles.size().times { i -> c."osgiRuntime$i" }
        }
        allBundles.eachWithIndex { bundle, i ->
            project.dependencies.add( "osgiRuntime$i", bundle ) {
                transitive = bundle instanceof Project
            }
        }
    }

    private void copyBundles( Project project, String bundlesDir ) {
        project.copy {
            from project.configurations.findAll { it.name.startsWith( 'osgiRuntime' ) }
            into bundlesDir
        }
        nonBundles( new File( bundlesDir ).listFiles() ).each {
            log.info "Removing non-bundle from classpath: ${it.name}"
            assert it.delete()
        }
    }

    private Collection<File> nonBundles( File[] files ) {
        if ( !files ) return emptyList()
        def notBundle = { File file ->
            def zip = new ZipFile( file )
            try {
                ZipEntry entry = zip.getEntry( 'META-INF/MANIFEST.MF' )
                if ( !entry ) return true
                def lines = zip.getInputStream( entry ).readLines()
                return !lines.any { it.trim().startsWith( 'Bundle' ) }
            } finally {
                zip.close()
            }
        }
        files.findAll( notBundle )
    }

    private void copyConfigFiles( String target, OsgiConfig osgiConfig ) {
        def configFile = getConfigFile( target, osgiConfig )
        if ( !configFile ) return;
        if ( !configFile.exists() ) {
            configFile.parentFile.mkdirs()
        }<commit_msg>Same bundles with different versions can be added to osgiRuntime<commit_after>package com.athaydes.gradle.osgi

import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging

import java.util.zip.ZipEntry
import java.util.zip.ZipFile

import static java.util.Collections.emptyList

/**
 *
 */
class OsgiRuntimeTaskCreator {

    static final Logger log = Logging.getLogger( OsgiRuntimeTaskCreator )

    Closure createOsgiRuntimeTask( Project project, OsgiConfig osgiConfig ) {
        return {
            String target = getTarget( project, osgiConfig )
            osgiConfig.outDirFile = target as File
            log.info( "Will copy osgi runtime resources into $target" )
            configBundles( project, osgiConfig )
            copyBundles( project, "${target}/${osgiConfig.bundlesPath}" )
            configMainDeps( project, osgiConfig )
            copyMainDeps( project, target )
            copyConfigFiles( target, osgiConfig )
        }
    }

    private void configMainDeps( Project project, OsgiConfig osgiConfig ) {
        def hasOsgiMainDeps = !project.configurations.osgiMain.dependencies.empty
        if ( !hasOsgiMainDeps ) {
            assert osgiConfig.osgiMain, 'No osgiMain provided, cannot create OSGi runtime'
            project.dependencies.add( 'osgiMain', osgiConfig.osgiMain )
        }
    }

    private void copyMainDeps( Project project, String target ) {
        project.copy {
            from project.configurations.osgiMain
            into target
        }
    }

    private void configBundles( Project project, OsgiConfig osgiConfig ) {
        def allBundles = osgiConfig.bundles.flatten() + project.configurations.osgiRuntime.allDependencies.asList()
        project.configurations { c ->
            // create individual configurations for each dependency so that version conflicts need not be resolved
            allBundles.size().times { i -> c."__osgiRuntime$i" }
        }
        allBundles.eachWithIndex { Object bundle, i ->
            def depConfig = ( bundle instanceof Dependency ) ? {} : { transitive = bundle instanceof Project }
            project.dependencies.add( "__osgiRuntime$i", bundle, depConfig )
        }
    }

    private void copyBundles( Project project, String bundlesDir ) {
        project.copy {
            from project.configurations.findAll { it.name.startsWith( '__osgiRuntime' ) }
            into bundlesDir
        }
        nonBundles( new File( bundlesDir ).listFiles() ).each {
            log.info "Removing non-bundle from classpath: ${it.name}"
            assert it.delete()
        }
    }

    private Collection<File> nonBundles( File[] files ) {
        if ( !files ) return emptyList()
        def notBundle = { File file ->
            def zip = new ZipFile( file )
            try {
                ZipEntry entry = zip.getEntry( 'META-INF/MANIFEST.MF' )
                if ( !entry ) return true
                def lines = zip.getInputStream( entry ).readLines()
                return !lines.any { it.trim().startsWith( 'Bundle' ) }
            } finally {
                zip.close()
            }
        }
        files.findAll( notBundle )
    }

    private void copyConfigFiles( String target, OsgiConfig osgiConfig ) {
        def configFile = getConfigFile( target, osgiConfig )
        if ( !configFile ) return;
        if ( !configFile.exists() ) {
            configFile.parentFile.mkdirs()
        }
{'fraction_non_alphanumeric': 0.08975306816501552, 'fraction_numerical': 0.0, 'mean_word_length': 2.1996215704824977, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '2501433', 'n_tokens_mistral': 1954, 'n_tokens_neox': 1839, 'n_words': 457}