/** * Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cloudsmith * */ package org.cloudsmith.geppetto.forge; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.Collection; import org.cloudsmith.geppetto.diagnostic.Diagnostic; import org.cloudsmith.geppetto.diagnostic.DiagnosticType; import org.cloudsmith.geppetto.forge.v2.model.Metadata; /** * This class basically mimics the PMT (Puppet Module Tool) */ public interface Forge { public static final DiagnosticType FORGE = new DiagnosticType("FORGE", ForgeService.class.getName()); public static final DiagnosticType PACKAGE = new DiagnosticType("PACKAGE", ForgeService.class.getName()); public static final DiagnosticType PUBLISHER = new DiagnosticType("PUBLISHER", ForgeService.class.getName()); public static final DiagnosticType PARSE_FAILURE = new DiagnosticType("PARSE_FAILURE", ForgeService.class.getName()); public static final String MODULEFILE_NAME = "Modulefile"; public static final String METADATA_JSON_NAME = "metadata.json"; /** * Name of injected file filter */ public static final String MODULE_FILE_FILTER = "module.file.filter"; /** * Name of optionally injected cache location */ public static final String CACHE_LOCATION = "forge.cache.location"; /** * Build a module for release. The end result is a gzipped tar file (.tar.gz) archive that * contains the module source and a freshly generated metadata.json. * * @param moduleSource * The module directory * @param destination * The directory where the build will be performed and also where the created archive will end up * adjacent to the built module. Created if necessary. * @param filter * The filter that is used for selecting the files. Can be null in which case the injected * filter annotated by {@link Named @Named}({@link ForgeConstants#MODULE_FILE_FILTER}) will be used. * @param resultingMetadata * A one element array that will receive the resulting metadata. Can be <tt>null</tt>. * @param result * diagnostics generated during extraction * @return The resulting gzipped tar file or <code>null</code> if extraction could not be performed. When that * happens, the result will contain * the reason. * @throws IOException */ File build(File moduleSource, File destination, FileFilter filter, Metadata[] resultingMetadata, Diagnostic result) throws IOException; /** * List modified files in an installed module * * @param path * The module directory * @param filter * The filter that is used by the scan. Can be null in which case the injected * filter annotated by {@link Named @Named}({@link ForgeConstants#MODULE_FILE_FILTER}) will be used. * @return A collection of modified files. * @throws IOException */ Collection<File> changes(File path, FileFilter filter) throws IOException; /** * Create a Metadata instance from a module structure. If a file named "metadata.json" exists * in the <tt>moduleDirectory</tt> then that file will be the sole source of input. Otherwise, this method * will consult injected {@link MetadataExtractor metadata extractors} to load the initial metadata, * and then, unless <tt>includeTypesAndChecksums</tt> is <tt>false</tt> reads puppet types from the directory * "lib/puppet" and generates checksums for all files. * * @param moduleDirectory * The directory containing the module * @param includeTypesAndChecksums * If set, analyze all types in and generated checksums * @param filter * The filter that is used by the scan. Can be null in which case the injected * filter annotated by {@link Named @Named}({@link ForgeConstants#MODULE_FILE_FILTER}) will be used. * @param extractedFrom * A one element File array that will receive the file that the metadata was extracted from. * Can be <tt>null</tt> when that piece of information is of no interest * Can be <tt>null</tt> when that piece of information is of no interest * @param result * diagnostics generated during extraction * @return The extracted metadata * @throws IOException */ Metadata createFromModuleDirectory(File moduleDirectory, boolean includeTypesAndChecksums, FileFilter filter, File[] extractedFrom, Diagnostic result) throws IOException; /** * Scan for valid directories containing a "metadata.json" or other files recognized by injected * {@link MetadataExtractor metadata extractors} using the provided <tt>filter</tt> to discriminate unwanted files. * A directory that contains such a file will not be scanned in turn. * * @param modulesRoot * The directory where the scan starts. Can be a module in itself. * @param filter * The filter that is used for selecting the files. Can be null in which case the injected * filter annotated by {@link Named @Named}({@link ForgeConstants#MODULE_FILE_FILTER}) will be used. * @return A list of directories that seems to be module roots. */ Collection<File> findModuleRoots(File modulesRoot, FileFilter filter); /** * Generate boilerplate for a new module * * @param destination * The module directory * @param metadata * The name of the module * @throws IOException */ void generate(File destination, Metadata metadata) throws IOException; /** * Extract metadata from a packaged module * * @param gzippedTarball * The packaged module file in gzipped tar format * @return The metadata or null if no metadata was present in the file * @throws IOException */ Metadata getMetadataFromPackage(File gzippedTarball) throws IOException; /** * Consults injected {@link MetadataExtractor metadata extractors} to check if metadata can * be extracted from the given location. * * @param moduleDirectory * @param filter * The filter that is used for selecting the files. Can be null in which case the injected * filter annotated by {@link Named @Named}({@link ForgeConstants#MODULE_FILE_FILTER}) will be used. * @return <tt>true</tt> if a least one metadata extractor can extract metadata from the given location */ boolean hasModuleMetadata(File moduleDirectory, FileFilter filter); /** * Checks if the file <tt>source</tt> is a file that one of the injected {@link MetadataExtractor metadata * extractors} would consider. * * @param source * The path to check. Should be relative to the expected module root * @return <tt>true</tt> if the file would be used for metadata extraction */ boolean isMetadataFile(String source); /** * Load metadata from a JSON file * * @param jsonFile * The file containing the JSON representation * @return The resulting metadata * @throws IOException */ Metadata loadJSONMetadata(File jsonFile) throws IOException; /** * Parse a Modulefile and create a Metadata instance from the result. The parser <i>will not evaluate</i> actual * ruby code. It * just parses the code and extracts values from the resulting AST. * * * @param moduleFile * The file to parse * @param result * Diagnostics collecting errors * @return The resulting metadata * @throws IOException * when it is not possible to read the <tt>modulefile</tt>. * @throws IllegalArgumentException * if <tt>result</tt> is <tt>null</tt> and errors are detected in the file. */ Metadata loadModulefile(File moduleFile, Diagnostic result) throws IOException; /** * Store the given metadata as JSON * * @param md * The metadata to store * @param jsonFile * The file to create * @throws IOException */ void saveJSONMetadata(Metadata md, File jsonFile) throws IOException; /** * Store the given <code>metadata</code> as a Modulefile (ruby format) * * @param metadata * The metadata to store * @param moduleFile * The file to create * @throws IOException */ void saveModulefile(Metadata metadata, File moduleFile) throws IOException; }