diff --git a/build.gradle b/build.gradle index c90f13d..7eb1d70 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ def PROD = "prod" final String URL_PROD = "https://maven.pkg.github.com/etendosoftware/com.etendoerp.gradleplugin" final String URL_DEV = "https://repo.futit.cloud/repository/maven-public-snapshots" -final String PLUGIN_VERSION = "1.5.0" +final String PLUGIN_VERSION = "1.5.1" // Default mode def mode = DEV diff --git a/src/main/groovy/com/etendoerp/EtendoPlugin.groovy b/src/main/groovy/com/etendoerp/EtendoPlugin.groovy index 381e953..246b26b 100644 --- a/src/main/groovy/com/etendoerp/EtendoPlugin.groovy +++ b/src/main/groovy/com/etendoerp/EtendoPlugin.groovy @@ -23,7 +23,7 @@ import com.etendoerp.publication.git.CloneDependencies class EtendoPlugin implements Plugin { - final static String PLUGIN_VERSION = "1.5.0" + final static String PLUGIN_VERSION = "1.5.1" @Override void apply(Project project) { diff --git a/src/main/groovy/com/etendoerp/legacy/dependencies/ResolverDependencyLoader.groovy b/src/main/groovy/com/etendoerp/legacy/dependencies/ResolverDependencyLoader.groovy index dde3261..af5d1c6 100644 --- a/src/main/groovy/com/etendoerp/legacy/dependencies/ResolverDependencyLoader.groovy +++ b/src/main/groovy/com/etendoerp/legacy/dependencies/ResolverDependencyLoader.groovy @@ -9,141 +9,130 @@ import com.etendoerp.legacy.utils.GithubUtils import com.etendoerp.modules.ModulesConfigurationUtils import com.etendoerp.publication.configuration.PublicationConfiguration import org.gradle.api.Project -import org.gradle.api.logging.LogLevel -import java.nio.file.Files -import java.nio.file.StandardCopyOption import org.gradle.api.file.FileTree import org.gradle.internal.os.OperatingSystem -import org.gradle.api.logging.LogLevel -import java.nio.file.Files -import java.nio.file.StandardCopyOption class ResolverDependencyLoader { - final static String CONSISTENCY_CONTAINER = "CONSISTENCY_CONTAINER" + final static String CONSISTENCY_CONTAINER = "CONSISTENCY_CONTAINER" - static load(Project project) { - - // Configuration container used to store all project and subproject dependencies - project.configurations { - etendoDependencyContainer - } - - /** - * This method gets all resolved dependencies by gradle and pass all resolved jars to ANT tasks - */ - - project.afterEvaluate { - project.logger.info("Running GRADLE projectsEvaluated.") - - if (project.state.failure) { - project.logger.error("* ERROR: ${project.state.failure.getMessage()}") - project.state.failure.printStackTrace() - return - } - - GithubUtils.configureRepositories(project) - CoreMetadata coreMetadata = new CoreMetadata(project) - - ModulesConfigurationUtils.configureSubprojects(project) - - PublicationConfiguration publicationConfiguration = new PublicationConfiguration(project) - publicationConfiguration.configurePublication() - - EtendoArtifactsConsistencyContainer consistencyContainer = new EtendoArtifactsConsistencyContainer(project, coreMetadata) - consistencyContainer.loadInstalledArtifacts() - - // Save the consistency container in the project - project.ext.set(CONSISTENCY_CONTAINER, consistencyContainer) - - def extension = project.extensions.findByType(EtendoPluginExtension) - boolean loadCompilationDependencies = extension.loadCompilationDependencies - boolean loadTestDependencies = extension.loadTestDependencies - - // Load Etendo core compilation dependencies when the core is in jar - if (loadCompilationDependencies) { - EtendoCoreDependencies.loadCoreCompilationDependencies(project) - } - - // Load Etendo core test dependencies - if (loadTestDependencies) { - EtendoCoreDependencies.loadCoreTestDependencies(project) - } - - DependencyProcessor dependencyProcessor = new DependencyProcessor(project, coreMetadata) - List jarFiles = dependencyProcessor.processJarFiles() - - // Note: previously the antClassLoader was used to add classes to ant's classpath - // but when the core is a complete jar (with libs) affecting the class loader can cause collisions - // (for example, the IOFileFilter of apache commons appears in the core jar and the gradle libs) - // Since the defined ant tasks specify a classpath, the code below should be enough - // otherwise doing a antClassLoader.addURL for each dependency will bring back the previous behaviour, but it will cause problems - // see https://github.com/gradle/gradle/issues/11914 for more info - def antClassLoader = org.apache.tools.ant.Project.class.classLoader - List dependencies = [] - List files = [] - // - - /** - * aux ant path used to hold gradle jar files - */ - File destDirectory = new File(sourcePath, "./build/lib/runtime") - destDirectory.mkdirs() - jarFiles.each { - // Copy the jar to the runtime directory - File destFile = new File(destDirectory, it.name) - Files.copy(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) - files.add("./" + it.getName()) - // Add the jar to the ant path to be used to create WebContent - dependencies.add(it.absolutePath) - } - def classpathJarName = "classpath.jar"; - // CREATE JAR HERE FROM gradle.custom and create a Manifest with the classpath - project.ant.jar(destfile: "${destDirectory.absolutePath}/${classpathJarName}") { - manifest { - attribute(name: "Class-Path", value: files.join(' ')) - } - } - project.ant.path(id:'gradle.custom') - project.ant.references['gradle.custom'].add(project.ant.path(location: new File(destDirectory.absolutePath, classpathJarName))) - - /** - * Creates an Ant property with the value of the gradle Jar paths. - * Ex: '/path/to/jar0:/path/to/jar1/' - * - * This is used when the project loads the Ant file - * to pass the Gradle libs classpath (dependencies defined with 'implementation'). - * - * This is a workaround to the problem when an Ant target calls another target with '' - * and the Gradle classpath is not being recognized. - * - * When a target uses the 'depends' value pointing to another Ant target there is no problem. - * should be avoided. - * - * Also sometimes when Ant calls forked classes, the Ant references 'refid' defined by Gradle will be lost. - * To prevents 'refid' errors a property with 'value' is used. - * - */ - project.ant.properties['gradle.custom.dependencies'] = project.ant.references['gradle.custom'].toString() - - project.ant.project.setProperty("env.GRADLE_CLASSPATH", project.ant.references['gradle.custom'].toString()) - - // This gets all dependencies and sets them in ant as a file list with id: "gradle.libs" - // Ant task build.local.context uses this to copy them to WebContent - project.ant.filelist(id: 'gradle.libs', files: dependencies.join(',')) - - AntLoader.loadAntFile(project, coreMetadata) - } + static load(Project project) { + // Configuration container used to store all project and subproject dependencies + project.configurations { + etendoDependencyContainer } - static String getSourcePath() { - def propsFile = new File("config/Openbravo.properties") - def props = new Properties() - if(!propsFile.exists()) { - return "." + /** + * This method gets all resolved dependencies by gradle and pass all resolved jars to ANT tasks + */ + + project.afterEvaluate { + project.logger.info("Running GRADLE projectsEvaluated.") + + if (project.state.failure) { + project.logger.error("* ERROR: ${project.state.failure.getMessage()}") + project.state.failure.printStackTrace() + return + } + + GithubUtils.configureRepositories(project) + CoreMetadata coreMetadata = new CoreMetadata(project) + + ModulesConfigurationUtils.configureSubprojects(project) + + PublicationConfiguration publicationConfiguration = new PublicationConfiguration(project) + publicationConfiguration.configurePublication() + + EtendoArtifactsConsistencyContainer consistencyContainer = new EtendoArtifactsConsistencyContainer(project, coreMetadata) + consistencyContainer.loadInstalledArtifacts() + + // Save the consistency container in the project + project.ext.set(CONSISTENCY_CONTAINER, consistencyContainer) + + def extension = project.extensions.findByType(EtendoPluginExtension) + boolean loadCompilationDependencies = extension.loadCompilationDependencies + boolean loadTestDependencies = extension.loadTestDependencies + + // Load Etendo core compilation dependencies when the core is in jar + if (loadCompilationDependencies) { + EtendoCoreDependencies.loadCoreCompilationDependencies(project) + } + + // Load Etendo core test dependencies + if (loadTestDependencies) { + EtendoCoreDependencies.loadCoreTestDependencies(project) + } + + DependencyProcessor dependencyProcessor = new DependencyProcessor(project, coreMetadata) + List jarFiles = dependencyProcessor.processJarFiles() + + // Note: previously the antClassLoader was used to add classes to ant's classpath + // but when the core is a complete jar (with libs) affecting the class loader can cause collisions + // (for example, the IOFileFilter of apache commons appears in the core jar and the gradle libs) + // Since the defined ant tasks specify a classpath, the code below should be enough + // otherwise doing a antClassLoader.addURL for each dependency will bring back the previous behaviour, but it will cause problems + // see https://github.com/gradle/gradle/issues/11914 for more info + def antClassLoader = org.apache.tools.ant.Project.class.classLoader + List dependencies = [] + /** + * aux ant path used to hold gradle jar files + */ + final String LIB_DIR = 'lib' + File destDirectory = new File(project.buildDir, LIB_DIR) + destDirectory.mkdirs() + jarFiles.each { File jarFile -> + // Copy the jar to the runtime directory + dependencies.add(jarFile.absolutePath) + } + List files = dependencies + final List DIRS = [ + new File("${project.rootDir.absolutePath}/lib"), + new File("${project.rootDir.absolutePath}/modules"), + new File("${project.rootDir.absolutePath}/modules_core"), + ] + DIRS.each { File dir -> + if (dir.exists()) { + FileTree libFiles = project.fileTree(dir).include('**/*.jar') as FileTree + // Search recursively for all jars in the lib directory and add to classpath jar + libFiles.each { File lib -> + files.add(lib.absolutePath) + } } - props.load(propsFile.newReader()) - return props.getProperty("source.path") + } + final String CLASSPATH_JAR_NAME = 'classpath.jar' + final String CLASSPATH_JAR_ABSOLUTE_PATH = "${destDirectory.absolutePath}/${CLASSPATH_JAR_NAME}" + final String CLASSPATH_SEPARATOR = ' ' + String strClasspath = '' + files.forEach { String file -> + if (OperatingSystem.current().isWindows()) { + // Windows paths need to be file:/// and replace \ with / + strClasspath += 'file:///' + file.toString().replaceAll('\\\\', '/') + CLASSPATH_SEPARATOR + } else { + strClasspath += file.toString() + CLASSPATH_SEPARATOR + } + } + // CREATE JAR HERE FROM gradle.custom and create a Manifest with the classpath + project.ant.jar(destfile: CLASSPATH_JAR_ABSOLUTE_PATH) { + manifest { + attribute(name: 'Class-Path', value: strClasspath) + } + } + project.ant.property(name: 'base.lib', location: new File("${project.rootDir}/build", LIB_DIR)) + // + final String GRADE_CUSTOM = 'gradle.custom' + project.ant.path(id: GRADE_CUSTOM) + project.ant.references[GRADE_CUSTOM].add(project.ant.path(location: CLASSPATH_JAR_ABSOLUTE_PATH)) + project.ant.properties['gradle.custom.dependencies'] = project.ant.references[GRADE_CUSTOM].toString() + project.ant.project.setProperty('env.GRADLE_CLASSPATH', project.ant.references[GRADE_CUSTOM].toString()) + + // This gets all dependencies and sets them in ant as a file list with id: "gradle.libs" + // Ant task build.local.context uses this to copy them to WebContent + project.ant.filelist(id: 'gradle.libs', files: dependencies.join(',')) + + AntLoader.loadAntFile(project, coreMetadata) } + + } + }