Search in sources :

Example 16 with ArtifactResult

use of org.eclipse.ceylon.model.cmr.ArtifactResult in project ceylon by eclipse.

the class ModuleCopycat method copyModuleInternal.

private void copyModuleInternal(ArtifactContext context) throws Exception {
    assert (context != null);
    if (!shouldExclude(context.getName())) {
        String module = ModuleUtil.makeModuleName(context.getName(), context.getVersion());
        // Skip all duplicates and artifacts from repositories that don't support copying
        if (!copiedModules.add(module) || !canBeCopied(context)) {
            // Faking a copy here for feedback because it was already done and we never copy twice
            if (feedback != null) {
                feedback.beforeCopyModule(context, count++, maxCount);
            }
            if (feedback != null) {
                feedback.afterCopyModule(context, count, maxCount, false);
            }
            return;
        }
        Collection<ModuleVersionDetails> versions = getModuleVersions(srcRepoman, context.getName(), context.getVersion(), ModuleQuery.Type.ALL, null, null, null, null);
        if (!versions.isEmpty()) {
            ArtifactContext depContext = context.copy();
            ModuleVersionDetails ver = versions.iterator().next();
            boolean copyModule = true;
            if (feedback != null) {
                copyModule = feedback.beforeCopyModule(context, count++, maxCount);
            }
            boolean copiedModule = false;
            if (copyModule) {
                List<ArtifactResult> results = srcRepoman.getArtifactResults(context);
                int artCnt = 0;
                for (ArtifactResult r : results) {
                    boolean copyArtifact = true;
                    if (feedback != null) {
                        copyArtifact = feedback.beforeCopyArtifact(context, r, artCnt++, results.size());
                    }
                    boolean copied = copyArtifact && copyArtifact(context, r);
                    if (feedback != null) {
                        feedback.afterCopyArtifact(context, r, artCnt, results.size(), copied);
                    }
                    copiedModule |= copied;
                }
            }
            if (feedback != null) {
                feedback.afterCopyModule(context, count, maxCount, copiedModule);
            }
            if (copyModule && !context.isIgnoreDependencies()) {
                maxCount += countNonExcludedDeps(ver.getDependencies());
                for (ModuleDependencyInfo dep : ver.getDependencies()) {
                    if (skipDependency(dep)) {
                        continue;
                    }
                    ModuleSpec depModule = new ModuleSpec(dep.getNamespace(), dep.getName(), dep.getVersion());
                    ArtifactContext copyContext = depContext.copy();
                    copyContext.setNamespace(dep.getNamespace());
                    copyContext.setName(depModule.getName());
                    copyContext.setVersion(depModule.getVersion());
                    copyModuleInternal(copyContext);
                }
            }
        } else {
            if (feedback != null) {
                feedback.notFound(context);
            }
        }
    }
}
Also used : ModuleSpec(org.eclipse.ceylon.common.ModuleSpec) ModuleVersionDetails(org.eclipse.ceylon.cmr.api.ModuleVersionDetails) ArtifactContext(org.eclipse.ceylon.cmr.api.ArtifactContext) ModuleDependencyInfo(org.eclipse.ceylon.cmr.api.ModuleDependencyInfo) ArtifactResult(org.eclipse.ceylon.model.cmr.ArtifactResult)

Example 17 with ArtifactResult

use of org.eclipse.ceylon.model.cmr.ArtifactResult in project ceylon by eclipse.

the class AbstractRepositoryManager method getArtifactResults.

@Override
public List<ArtifactResult> getArtifactResults(ArtifactContext context) throws RepositoryException {
    final List<ArtifactResult> results = new ArrayList<>();
    ArtifactResult result = null;
    LinkedHashSet<String> suffixes = new LinkedHashSet<>(Arrays.asList(context.getSuffixes()));
    while (!suffixes.isEmpty()) {
        // Try to get one of the artifacts
        String[] sfx = suffixes.toArray(new String[suffixes.size()]);
        ArtifactContext ac;
        if (result == null) {
            ac = context;
        } else {
            // We re-use the previous result so we can efficiently
            // retrieve further artifacts from the same module
            ac = context.getSibling(result, sfx);
        }
        result = getArtifactResult(ac);
        if (result != null) {
            results.add(result);
            // make sure we don't try to get the same artifact twice
            String suffix = ArtifactContext.getSuffixFromFilename(result.artifact().getName());
            // but we don't just remove the one we got, but all of suffixes
            // up to the one we found, because we know the list is ordered
            // and the others were tried first
            Iterator<String> iter = suffixes.iterator();
            while (iter.hasNext() && !suffix.equals(iter.next())) {
                iter.remove();
            }
            suffixes.remove(suffix);
            // TODO this shouldn't be hard-coded here but is to prevent
            // unnecessary queries to remote repositories
            boolean isLangMod = "ceylon.language".equals(context.getName());
            if (suffix.equals(ArtifactContext.CAR)) {
                // If we found a car we can skip the jar and module descriptors.
                // But we make an exception for the language module because it's
                // the only .car file that also has a module.xml descriptor
                suffixes.remove(ArtifactContext.JAR);
                suffixes.remove(ArtifactContext.MODULE_PROPERTIES);
                if (!isLangMod) {
                    suffixes.remove(ArtifactContext.MODULE_XML);
                }
            } else if (suffix.equals(ArtifactContext.JAR) || suffix.equals(ArtifactContext.MODULE_PROPERTIES) || suffix.equals(ArtifactContext.MODULE_XML)) {
                // or the exact opposite (and again an exception is made for the language module)
                if (!isLangMod) {
                    suffixes.remove(ArtifactContext.CAR);
                }
            }
        } else {
            // we can stop trying more artifact types
            break;
        }
    }
    return results;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) ArtifactResult(org.eclipse.ceylon.model.cmr.ArtifactResult)

Example 18 with ArtifactResult

use of org.eclipse.ceylon.model.cmr.ArtifactResult in project ceylon by eclipse.

the class CeylonAssembleTool method run.

@Override
public void run() throws Exception {
    if (includeRuntime) {
        // includeRuntime implies includeLanguage
        includeLanguage = true;
    }
    String firstModuleName = null, firstModuleVersion = null;
    for (ModuleSpec module : modules) {
        String moduleName = module.getName();
        String version = checkModuleVersionsOrShowSuggestions(moduleName, module.isVersioned() ? module.getVersion() : null, mqt, Versions.JVM_BINARY_MAJOR_VERSION, Versions.JVM_BINARY_MINOR_VERSION, Versions.JS_BINARY_MAJOR_VERSION, Versions.JS_BINARY_MINOR_VERSION, null);
        if (version == null)
            return;
        if (firstModuleName == null) {
            firstModuleName = moduleName;
            firstModuleVersion = version;
        }
        loadModule(null, moduleName, version);
        if (!force)
            errorOnConflictingModule(moduleName, version);
    }
    if (includeRuntime) {
        loadModule(null, "ceylon.runtime", Versions.CEYLON_VERSION_NUMBER);
        loadModule(null, "org.eclipse.ceylon.module-resolver-aether", Versions.CEYLON_VERSION_NUMBER);
    }
    loader.resolve();
    String versionSuffix = firstModuleVersion != null && !firstModuleVersion.isEmpty() ? "-" + firstModuleVersion : "";
    File outputCas = applyCwd(out != null ? out : new File(firstModuleName + versionSuffix + CEYLON_ASSEMBLY_SUFFIX));
    if (outputCas.getParentFile() != null && !outputCas.getParentFile().exists()) {
        FileUtil.mkdirs(outputCas.getParentFile());
    }
    if (outputCas.exists()) {
        FileUtil.delete(outputCas);
    }
    final Set<String> added = new HashSet<>();
    // Create a MANIFEST.MF and add it to the assembly
    Manifest manifest = new Manifest();
    Attributes mainAttributes = manifest.getMainAttributes();
    mainAttributes.putValue("Manifest-Version", "1.0");
    mainAttributes.putValue("Created-By", "Ceylon assemble for module " + firstModuleName + "/" + firstModuleVersion);
    mainAttributes.putValue(Constants.ATTR_ASSEMBLY_MAIN_MODULE, ModuleUtil.makeModuleName(firstModuleName, firstModuleVersion));
    if (run != null) {
        mainAttributes.putValue(Constants.ATTR_ASSEMBLY_RUN, run);
    }
    mainAttributes.putValue(Constants.ATTR_ASSEMBLY_REPOSITORY, "modules");
    File ovrFile = getOverridesFile();
    if (ovrFile != null) {
        mainAttributes.putValue(Constants.ATTR_ASSEMBLY_OVERRIDES, ovrFile.getName());
    }
    if (includeLanguage) {
        String className = JVMModuleUtil.javaClassNameFromCeylon(firstModuleName, run != null ? run : (firstModuleName + "::run"));
        mainAttributes.putValue("Main-Class", "org.eclipse.ceylon.tools.assemble.CeylonAssemblyRunner");
        mainAttributes.putValue(Constants.ATTR_ASSEMBLY_MAIN_CLASS, className);
    }
    added.add("META-INF/");
    added.add("META-INF/MANIFEST.MF");
    try (ZipOutputStream zipFile = new JarOutputStream(new FileOutputStream(outputCas), manifest)) {
        if (ovrFile != null) {
            // Copy the overrides.xml file to the output CAS
            try (InputStream is = new FileInputStream(ovrFile)) {
                zipFile.putNextEntry(new ZipEntry(ovrFile.getName()));
                IOUtils.copyStream(is, zipFile, true, false);
            }
        }
        if (includeLanguage) {
            // Copy the CeylonAssemblyRunner class and dependencies to the output CAS
            String prefix = CeylonAssemblyRunner.class.getName().replace('.', '/');
            String[] postfixes = { "", "$CeylonAssemblyClassLoader", "$CeylonAssemblyClassLoader$1" };
            for (String postfix : postfixes) {
                String clsName = prefix + postfix + ".class";
                try (InputStream is = CeylonAssemblyRunner.class.getResourceAsStream("/" + clsName)) {
                    zipFile.putNextEntry(new ZipEntry(clsName));
                    IOUtils.copyStream(is, zipFile, true, false);
                }
            }
        }
        // Visit the module and all its dependencies
        loader.visitModules(new ModuleGraph.Visitor() {

            @Override
            public void visit(ModuleGraph.Module module) {
                if (module.artifact != null) {
                    File file = module.artifact.artifact();
                    try {
                        if (file != null) {
                            if (isVerbose()) {
                                append(file.getAbsolutePath());
                                newline();
                            }
                            if (module.artifact.namespace() == null) {
                                // Copy all the "interesting" artifacts to the assembly, not just the JVM one
                                ArtifactContext ac = new ArtifactContext(module.artifact.namespace(), module.artifact.name(), module.artifact.version(), assemblySuffixes);
                                List<ArtifactResult> artifacts = getRepositoryManager().getArtifactResults(ac);
                                for (ArtifactResult ar : artifacts) {
                                    String name = "modules/" + moduleToPath(module.name) + "/" + module.version + "/" + ar.artifact().getName();
                                    addEntry(zipFile, ar.artifact(), name);
                                }
                            } else if (module.artifact.namespace().equals(MavenRepository.NAMESPACE)) {
                                String name = "maven/" + moduleToPath(module.name) + "/" + module.version + "/" + file.getName();
                                addEntry(zipFile, file, name);
                                // Copy the Maven artifact's pom file as well
                                String pomName = module.artifact.artifactId() + "-" + module.version + ".pom";
                                File mfile = new File(file.getParentFile(), pomName);
                                if (mfile.isFile()) {
                                    name = "maven/" + moduleToPath(module.name) + "/" + module.version + "/" + mfile.getName();
                                    addEntry(zipFile, mfile, name);
                                }
                            } else if (module.artifact.namespace().equals("npm")) {
                                File parent = module.artifact.artifact().getParentFile().getCanonicalFile();
                                while (parent != null && !(new File(parent, "package.json")).exists()) {
                                    parent = parent.getParentFile();
                                }
                                String name = "node_modules/" + parent.getName();
                                addEntry(zipFile, parent, name);
                            }
                        }
                    } catch (IOException x) {
                        // lame
                        throw new RuntimeException(x);
                    }
                }
            }

            private String moduleToPath(String name) {
                return ModuleUtil.moduleToPath(name).getPath().replace(':', File.separatorChar);
            }

            private void addEntry(final ZipOutputStream zipFile, final File file, final String name) throws IOException {
                if (file.isFile()) {
                    addFileEntry(zipFile, file, name);
                } else if (file.isDirectory()) {
                    Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {

                        @Override
                        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                            if (path.toFile().isFile()) {
                                Path relPath = file.toPath().relativize(path);
                                String newName = name + "/" + relPath;
                                addFileEntry(zipFile, path.toFile(), newName);
                            }
                            return super.visitFile(path, attrs);
                        }
                    });
                }
            }

            private void addFileEntry(ZipOutputStream zipFile, File file, String name) throws IOException {
                try (InputStream is = new FileInputStream(file)) {
                    zipFile.putNextEntry(new ZipEntry(name));
                    IOUtils.copyStream(is, zipFile, true, false);
                }
            }
        });
        zipFile.flush();
    }
    flush();
}
Also used : ZipEntry(java.util.zip.ZipEntry) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) Attributes(java.util.jar.Attributes) ArtifactContext(org.eclipse.ceylon.cmr.api.ArtifactContext) ModuleSpec(org.eclipse.ceylon.common.ModuleSpec) ArrayList(java.util.ArrayList) List(java.util.List) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) HashSet(java.util.HashSet) Path(java.nio.file.Path) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) JarOutputStream(java.util.jar.JarOutputStream) FileVisitResult(java.nio.file.FileVisitResult) IOException(java.io.IOException) Manifest(java.util.jar.Manifest) FileInputStream(java.io.FileInputStream) ArtifactResult(org.eclipse.ceylon.model.cmr.ArtifactResult) ZipOutputStream(java.util.zip.ZipOutputStream) FileOutputStream(java.io.FileOutputStream) ModuleGraph(org.eclipse.ceylon.cmr.ceylon.loader.ModuleGraph) File(java.io.File)

Example 19 with ArtifactResult

use of org.eclipse.ceylon.model.cmr.ArtifactResult in project ceylon by eclipse.

the class ModuleSourceMapper method resolveModule.

public void resolveModule(ArtifactResult artifact, Module module, ModuleImport moduleImport, LinkedList<Module> dependencyTree, List<PhasedUnits> phasedUnitsOfDependencies, boolean forCompiledModule) {
    // This implementation relies on the ability to read the model from source
    // the compiler for example subclasses this to read lazily and from the compiled model
    ArtifactContext artifactContext = new ArtifactContext(null, module.getNameAsString(), module.getVersion(), ArtifactContext.SRC);
    RepositoryManager repositoryManager = context.getRepositoryManager();
    Exception exceptionOnGetArtifact = null;
    ArtifactResult sourceArtifact = null;
    try {
        sourceArtifact = repositoryManager.getArtifactResult(artifactContext);
    } catch (Exception e) {
        exceptionOnGetArtifact = e;
    }
    if (sourceArtifact == null) {
        ModuleHelper.buildErrorOnMissingArtifact(artifactContext, module, moduleImport, dependencyTree, exceptionOnGetArtifact, this, true);
    } else {
        PhasedUnits modulePhasedUnits = createPhasedUnits();
        ClosableVirtualFile virtualArtifact = null;
        try {
            virtualArtifact = context.getVfs().getFromZipFile(sourceArtifact.artifact());
            modulePhasedUnits.parseUnit(virtualArtifact);
            // populate module.getDependencies()
            modulePhasedUnits.visitModules();
            addToPhasedUnitsOfDependencies(modulePhasedUnits, phasedUnitsOfDependencies, module);
        } catch (Exception e) {
            StringBuilder error = new StringBuilder("unable to read source artifact for ");
            error.append(artifactContext.toString());
            error.append("\ndue to connection error: ").append(e.getMessage());
            attachErrorToDependencyDeclaration(moduleImport, dependencyTree, error.toString(), true);
        } finally {
            if (virtualArtifact != null) {
                virtualArtifact.close();
            }
        }
    }
}
Also used : ClosableVirtualFile(org.eclipse.ceylon.compiler.typechecker.io.ClosableVirtualFile) PhasedUnits(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnits) ArtifactContext(org.eclipse.ceylon.cmr.api.ArtifactContext) RepositoryManager(org.eclipse.ceylon.cmr.api.RepositoryManager) ArtifactResult(org.eclipse.ceylon.model.cmr.ArtifactResult)

Example 20 with ArtifactResult

use of org.eclipse.ceylon.model.cmr.ArtifactResult in project ceylon by eclipse.

the class ModuleValidator method resolveModuleIfRequired.

private void resolveModuleIfRequired(Module module, boolean forCompiledModule, ModuleImport moduleImport, ImportDepth importDepth, LinkedList<Module> dependencyTree, Map<Module, ArtifactResult> alreadySearchedArtifacts) {
    if (!module.isAvailable()) {
        ArtifactResult artifact = null;
        boolean firstTime;
        if (alreadySearchedArtifacts.containsKey(module)) {
            artifact = alreadySearchedArtifacts.get(module);
            firstTime = false;
        } else {
            // try and load the module from the repository
            RepositoryManager repositoryManager = context.getRepositoryManager();
            if (repositoryManager.isValidNamespace(moduleImport.getNamespace())) {
                Exception exceptionOnGetArtifact = null;
                Iterable<String> searchedArtifactExtensions = moduleManager.getSearchedArtifactExtensions();
                ArtifactContext artifactContext = new ArtifactContext(moduleImport.getNamespace(), module.getNameAsString(), module.getVersion(), getArtifactSuffixes(searchedArtifactExtensions));
                listener.retrievingModuleArtifact(module, artifactContext);
                try {
                    artifact = repositoryManager.getArtifactResult(artifactContext);
                } catch (Exception e) {
                    exceptionOnGetArtifact = catchIfPossible(e);
                }
                if (artifact == null) {
                    boolean error = true;
                    if (ModuleUtil.isMavenModule(module.getNameAsString()) && !dependencyTree.isEmpty() && ModuleUtil.isMavenModule(dependencyTree.peekLast().getNameAsString()))
                        error = false;
                    // not there => error
                    ModuleHelper.buildErrorOnMissingArtifact(artifactContext, module, moduleImport, dependencyTree, exceptionOnGetArtifact, moduleManagerUtil, error);
                    listener.retrievingModuleArtifactFailed(module, artifactContext);
                } else {
                    listener.retrievingModuleArtifactSuccess(module, artifact);
                }
            } else {
                StringBuilder msg = new StringBuilder().append("unknown import namespace: '").append(moduleImport.getNamespace()).append("' should be one of ");
                TreeSet<String> namespaces = new TreeSet<String>();
                for (CmrRepository repo : repositoryManager.getRepositories()) {
                    namespaces.add(repo.getNamespace());
                }
                boolean first = true;
                for (String namespace : namespaces) {
                    if (first) {
                        first = false;
                    } else {
                        msg.append(", ");
                    }
                    msg.append("'").append(namespace).append("'");
                }
                // if (!MavenRepository.NAMESPACE.equals(moduleImport.getNamespace())) {
                // msg += " (if this is a Maven import make sure to add a 'maven:' prefix)";
                // }
                moduleManagerUtil.attachErrorToDependencyDeclaration(moduleImport, dependencyTree, msg.toString(), true);
            }
            alreadySearchedArtifacts.put(module, artifact);
            firstTime = true;
        }
        // a compiled module, then it MUST resolve it and make it available, so do try in this case.
        if (artifact != null && (firstTime || forCompiledModule)) {
            // parse module units and build module dependency and carry on
            listener.resolvingModuleArtifact(module, artifact);
            Module moduleOverride = moduleManager.overridesModule(artifact, module, moduleImport);
            if (moduleOverride != null) {
                if (importDepth.equals(ImportDepth.First)) {
                    moduleManagerUtil.attachErrorToDependencyDeclaration(moduleImport, dependencyTree, "project source module import is overridden in module overrides file: '" + moduleOverride.getNameAsString() + "/" + moduleOverride.getVersion() + "' overrides '" + module.getNameAsString() + "/" + module.getVersion() + "'", false);
                }
                module = moduleOverride;
            }
            moduleManagerUtil.resolveModule(artifact, module, moduleImport, dependencyTree, phasedUnitsOfDependencies, forCompiledModule);
        }
    }
}
Also used : TreeSet(java.util.TreeSet) RepositoryManager(org.eclipse.ceylon.cmr.api.RepositoryManager) ArtifactContext(org.eclipse.ceylon.cmr.api.ArtifactContext) CmrRepository(org.eclipse.ceylon.cmr.api.CmrRepository) ImportModule(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ImportModule) Module(org.eclipse.ceylon.model.typechecker.model.Module) ArtifactResult(org.eclipse.ceylon.model.cmr.ArtifactResult)

Aggregations

ArtifactResult (org.eclipse.ceylon.model.cmr.ArtifactResult)79 File (java.io.File)40 RepositoryManager (org.eclipse.ceylon.cmr.api.RepositoryManager)32 SimpleRepositoryManager (org.eclipse.ceylon.cmr.impl.SimpleRepositoryManager)28 Test (org.junit.Test)28 ArtifactContext (org.eclipse.ceylon.cmr.api.ArtifactContext)25 IOException (java.io.IOException)17 ArrayList (java.util.ArrayList)17 CmrRepository (org.eclipse.ceylon.cmr.api.CmrRepository)15 ModuleSpec (org.eclipse.ceylon.common.ModuleSpec)13 FileOutputStream (java.io.FileOutputStream)6 InputStream (java.io.InputStream)5 ToolUsageError (org.eclipse.ceylon.common.tool.ToolUsageError)5 Module (org.eclipse.ceylon.model.typechecker.model.Module)5 LinkedList (java.util.LinkedList)4 List (java.util.List)4 ZipEntry (java.util.zip.ZipEntry)4 FileInputStream (java.io.FileInputStream)3 OutputStream (java.io.OutputStream)3 OutputStreamWriter (java.io.OutputStreamWriter)3