<|start_filename|>dev.jeka.core-samples/src/main/java/dev/jeka/core/samples/Foo.java<|end_filename|>
package dev.jeka.core.samples;

public class Foo {
	
	public void display() {
		System.out.println("I am Foo. Isn't it ?");
	}

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/file/package-info.java<|end_filename|>
/**
 * Contains classes to manipulate files in a fluent way.
 */
package dev.jeka.core.api.file;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/package-info.java<|end_filename|>
/**
 * Contains interfaces and classes that form the core Jeka API. Core Jeka
 * API are a set of classes that can be reused/embedded in any java program and
 * have no dependency on the Jeka automation tool.
 * 
 * You can use it for describing your build files or embbed it in any of your
 * program.
 */
package dev.jeka.core.api;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/JkDoc.java<|end_filename|>
package dev.jeka.core.tool;

import java.lang.annotation.*;

/**
 * Documents the annotated element so that Jeka can display some information
 * when 'help' is invoked from command line.
 *
 * @author <NAME>
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
@Inherited
public @interface JkDoc {

    /**
     * The text to display when help is requested.
     */
    String[] value();

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/builtins/intellij/ModulesXmlGenerator.java<|end_filename|>
package dev.jeka.core.tool.builtins.intellij;

import dev.jeka.core.api.system.JkLog;
import dev.jeka.core.api.utils.JkUtilsPath;
import dev.jeka.core.api.utils.JkUtilsThrowable;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

class ModulesXmlGenerator {

    private static final String ENCODING = "UTF-8";

    private static final String T1 = "  ";

    private static final String T2 = T1 + T1;

    private static final String T3 = T2 + T1;

    private final Iterable<Path> imlFiles;

    private final Path projectDir;

    private final Path outputFile;

    public ModulesXmlGenerator(Path projectDir, Iterable<Path> imlFiles) {
        this.imlFiles = imlFiles;
        this.projectDir = projectDir;
        this.outputFile = projectDir.resolve(".idea/modules.xml");
    }

    public void generate() {
        try {
            _generate();
        } catch (final Exception e) {
            throw JkUtilsThrowable.unchecked(e);
        }
    }

    public Path outputFile() {
        return outputFile;
    }

    private void _generate() throws IOException, XMLStreamException, FactoryConfigurationError {

        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(baos, ENCODING);
        writer.writeStartDocument(ENCODING, "1.0");
        writer.writeCharacters("\n");
        writer.writeStartElement("project");
        writer.writeCharacters("\n" + T1);
        writer.writeStartElement("component");
        writer.writeAttribute("name", "ProjectModuleManager");
        writer.writeCharacters("\n" + T2);
        writer.writeStartElement("modules");
        writer.writeCharacters("\n");
        for (final Path iml : imlFiles) {
            final Path relPath = projectDir.relativize(iml);
            JkLog.info("Iml file detected : " + relPath);
            final String path = path(relPath);
            writer.writeCharacters(T3);
            writer.writeEmptyElement("module");
            writer.writeAttribute("fileurl", "file://" + path);
            writer.writeAttribute("filepath", path);
            writer.writeCharacters("\n");
        }
        writer.writeCharacters(T2);
        writer.writeEndElement();
        writer.writeCharacters("\n" + T1);
        writer.writeEndElement();
        writer.writeEndDocument();
        writer.flush();
        writer.close();
        JkUtilsPath.deleteIfExists(outputFile);
        JkUtilsPath.createDirectories(outputFile.getParent());
        Files.write(outputFile, baos.toByteArray());
    }

    private String path(Path relPath) {
        return "$PROJECT_DIR$/" + relPath.toString().replace('\\', '/');
    }



}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/system/package-info.java<|end_filename|>
/**
 * Contains classes for dealing with Jeka ofSystem.
 */
package dev.jeka.core.api.system;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/crypto/gpg/package-info.java<|end_filename|>
/**
 * Contains classes providing PGP signature facility.
 */
package dev.jeka.core.api.crypto.gpg;

<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/tool/builtins/templates/javabuild/test/junit/JkJunitTest.java<|end_filename|>
package dev.jeka.core.tool.builtins.templates.javabuild.test.junit;

import org.junit.Test;

@SuppressWarnings("javadoc")
public class JkJunitTest {

    @Test
    public void testSystemOutRedirect() {

        // Just print something in the console to see if it appears during test
        // execution
        System.out.println("ofSystem out : This text should appear during test execution");
        System.err.println("ofSystem err : This text should appear during test execution");
    }

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/file/JkPathMatcherTest.java<|end_filename|>
package dev.jeka.core.api.file;

import org.junit.Test;

import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

@SuppressWarnings("javadoc")
public class JkPathMatcherTest {

    @Test
    public void testAccept() {
        this.testDoMatchOk("foo/bar.txt");
        this.testDoMatchOk("./foo/bar.txt");

        assertTrue(JkPathMatcher.of(true,"**/*.java").matches(Paths.get("foo/subfoo/bar.java")));
        assertTrue(JkPathMatcher.of(true,"**.java").matches(Paths.get("Bar.java")));
        assertTrue(JkPathMatcher.of(true,"**.java").matches(Paths.get("foo/Bar.java")));
        assertTrue(JkPathMatcher.of(true,"*.java").matches(Paths.get("Bar.java")));
        assertTrue(JkPathMatcher.of(true,"com/**", "com").matches(Paths.get("com")));
        assertTrue(!JkPathMatcher.of(true,"com/**/*").matches(Paths.get("com")));

        final String pathString = "foo/bar.txt";
        Path path = Paths.get(pathString);
        assertTrue(!JkPathMatcher.of(true,"**/*.tx").matches(path));
        assertTrue(!JkPathMatcher.of(true,"foo/br.txt").matches(path));
        assertTrue(!JkPathMatcher.of(true,"k*/bar.txt").matches(path));
        assertTrue(!JkPathMatcher.of(true,"*.java").matches(Paths.get("foo/Bar.java")));
    }

    @Test
    public void testNegative() {
        assertTrue(JkPathMatcher.of(false, "org/**", "com/**").matches(Paths.get("foo/subfoo/bar.java")));
        assertFalse(JkPathMatcher.of(false,"org/**", "com/**").matches(Paths.get("com/subfoo/bar.java")));
        assertFalse(JkPathMatcher.of(false,"org/**", "com/**/*").matches(Paths.get("com/subfoo/bar.java")));
        assertFalse(JkPathMatcher.of(false,"org/**", "com/**").matches(Paths.get("org/subfoo/bar.java")));
        assertFalse(JkPathMatcher.of(false,"**/_*").matches(Paths.get("foo/subfoo/_Bar.java")));
        assertFalse(JkPathMatcher.of(false,"**/_*", "_*").matches(Paths.get("_Bar.java")));
    }

    @Test
    public void testAndRefuse() {
        assertTrue(JkPathMatcher.of(true,"**/*.java").and(false, "**/_*")
                .matches(Paths.get("foo/subfoo/Bar.java")));

        Path path = Paths.get("C:/samples/sample-dependee/AClassicBuild.java");
        assertTrue(JkPathMatcher.of(true,"**/*.java").and(false, "**/_*").matches(path));


    }

    private void testDoMatchOk(String pathString) {

        Path path = Paths.get(pathString).normalize();
        System.out.println("---------------------- " + pathString + ":" + path);

        PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/*.txt");
        assertTrue(matcher.matches(path));
        assertTrue(pathString, JkPathMatcher.of(true,"**/*.txt").matches(path));

        matcher = FileSystems.getDefault().getPathMatcher("glob:foo/bar.txt");
        assertTrue(pathString , matcher.matches(path));
        assertTrue(pathString, JkPathMatcher.of(true,"foo/bar.txt").matches(path));

        assertTrue(JkPathMatcher.of(true,"foo/b?r.txt").matches(path));
        assertTrue(JkPathMatcher.of(true,"f*/bar.txt").matches(path));
        assertTrue(JkPathMatcher.of(true,"*/bar.txt").matches(path));
        assertTrue(JkPathMatcher.of(true,"**").matches(path));
    }

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/depmanagement/JkModuleIdTest.java<|end_filename|>
package dev.jeka.core.api.depmanagement;

import org.junit.Assert;
import org.junit.Test;

@SuppressWarnings("javadoc")
public class JkModuleIdTest {

    @Test
    public void testOf() {
        final String groupAndName = "org.springframework.boot:spring-boot-starter-data-rest";
        final JkModuleId jkModuleId = JkModuleId.of(groupAndName);
        Assert.assertEquals("org.springframework.boot", jkModuleId.getGroup());
        Assert.assertEquals("spring-boot-starter-data-rest", jkModuleId.getName());
    }

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/depmanagement/JkDependencyTest.java<|end_filename|>
package dev.jeka.core.api.depmanagement;

import org.junit.Assert;
import org.junit.Test;

@SuppressWarnings("javadoc")
public class JkDependencyTest {

    @Test
    public void test() {
        final JkModuleDependency dep = JkModuleDependency.of("org.hibernate:hibernate-core:3.0.+");
        Assert.assertEquals("org.hibernate", dep.getModuleId().getGroup());
        Assert.assertEquals("hibernate-core", dep.getModuleId().getName());
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/utils/JkUtilsTime.java<|end_filename|>
package dev.jeka.core.api.utils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

/**
 * Utility class to deal with time.
 * 
 * @author <NAME>
 */
public final class JkUtilsTime {

    private JkUtilsTime() {}

    /**
     * Returns the current ofSystem date
     */
    public static Date now() {
        return new Date();
    }

    /**
     * Returns the current ofSystem date as string with the specified format
     */
    public static String now(String pattern) {
        return new SimpleDateFormat(pattern).format(now());
    }

    /**
     * Returns the current ofSystem date as string with the specified format
     */
    public static String nowUtc(String pattern) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return dateFormat.format(now());
    }

    /**
     * Returns the duration in second between the specified nano time and now.
     */
    public static float durationInSeconds(long startNano) {
        final long endNano = System.nanoTime();
        final long durationMillis = (endNano - startNano) / 1000000;
        return durationMillis / 1000f;
    }

    /**
     * Returns the duration in millisecond between the specified nano time and
     * now.
     */
    public static long durationInMillis(long startNano) {
        final long endNano = System.nanoTime();
        return (endNano - startNano) / 1000000;
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/utils/JkUtilsZip.java<|end_filename|>
package dev.jeka.core.api.utils;

import java.io.File;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;


/**
 * Low level utility method to deal with zip files.
 */
public final class JkUtilsZip {

    private JkUtilsZip() {
    }

    /**
     * Returns all zip entry of the specified zip file.
     */
    @SuppressWarnings("unchecked")
    public static List<ZipEntry> getZipEntries(ZipFile zipFile) {
        final List<ZipEntry> result = new LinkedList<>();
        final Enumeration<ZipEntry> en = (Enumeration<ZipEntry>) zipFile.entries();
        while (en.hasMoreElements()) {
            result.add(en.nextElement());
        }
        return result;
    }

    /**
     * Creates a {@link ZipFile} to file without checked exception.
     */
    public static ZipFile getZipFile(File file) {
        try {
            return new ZipFile(file);
        } catch (final Exception e) {
            throw JkUtilsThrowable.unchecked(e);
        }
    }

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/file/JkPathFileTest.java<|end_filename|>
package dev.jeka.core.api.file;

import org.junit.Assert;
import org.junit.Test;

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JkPathFileTest {

    @Test
    public void testCopyRepacingTokens() throws Exception {
        Path from = Paths.get(JkPathFileTest.class.getResource("tokenSample.txt").toURI());
        Path to = Files.createTempFile("test", ".txt");
        Map<String, String> tokens = new HashMap<>();
        tokens.put("${1}", "first");
        tokens.put("${2}", "second");
        tokens.put("${3}", "next ${2}");
        Charset utf8 = Charset.forName("UTF-8");
        JkPathFile.of(from).copyReplacingTokens(to, tokens, utf8);
        List<String> resultLines = Files.readAllLines(to, utf8);
        Assert.assertEquals("This is the first line.", resultLines.get(0));
        Assert.assertEquals("This is the second line.", resultLines.get(1));
        Assert.assertEquals("This is the next second line.", resultLines.get(2));
        System.out.println(to);
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/system/JkPrompt.java<|end_filename|>
package dev.jeka.core.api.system;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public final class JkPrompt {

    private JkPrompt() {
    }

    public static String ask(String prompt) {
        System.out.print(prompt);
        System.out.flush();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
            return br.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/builtins/eclipse/package-info.java<|end_filename|>
/**
 * Contains classes ofIterable the Eclipse plugins
 */
package dev.jeka.core.tool.builtins.eclipse;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/utils/JkUtilsIterable.java<|end_filename|>
package dev.jeka.core.api.utils;

import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;

/**
 * Utility class for dealing with {@link Iterable}.
 *
 * @author <NAME>
 */
public final class JkUtilsIterable {

    /**
     * Returns a list form the the specified {@link Iterable}.
     * If the specified {@link Iterable} is yet a {@link List} than it
     * is returned as is, otherwise a brand new {@link List} is created.
     */
    public static <T> List<T> listOf(Iterable<T> it) {
        if (it instanceof List) {
            return (List<T>) it;
        }
        final List<T> result = new LinkedList<>();
        for (final T t : it) {
            result.add(t);

        }
        return result;
    }

    /**
     * @see #listOf(Iterable)
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> listOf(T... items) {
        return Arrays.asList(items);
    }

    /**
     * @see #listOf(Iterable)
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> listOf2orMore(T item1, T item2, T... others) {
        ArrayList<T> result = new ArrayList<>(others.length + 2);
        result.add(item1);
        result.add(item2);
        for (int i = 0; i < others.length; i++) {
            result.add(others[i]);
        }
        return result;
    }

    /**
     * @see #listOf(Iterable)
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> listOf1orMore(T item1, T... others) {
        ArrayList<T> result = new ArrayList<>(others.length + 1);
        result.add(item1);
        for (int i = 0; i < others.length; i++) {
            result.add(others[i]);
        }
        return result;
    }




    /**
     * Returns a duplicate free list of the given items
     */
    public static <T> List<T> listWithoutDuplicateOf(Iterable<T> items) {
        final Set<T> set = new HashSet<>();
        final LinkedList<T> result = new LinkedList<>();
        for (final T item : items) {
            if (!set.contains(item)) {
                set.add(item);
                result.add(item);
            }
        }
        return result;
    }

    /**
     * Adds items to the specified recipient list. Only item not already present in the recipient list are added.
     */
    public static <T> void addAllWithoutDuplicate(Collection<T> recipientList, Iterable<? extends T> items) {
        for (final T item : items) {
            if (!recipientList.contains(item)) {
                recipientList.add(item);
            }
        }
    }

    /**
     * Creates an array of the specified class and populate it with items of the specified {@link Iterable}.
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] arrayOf(Iterable<T> it, Class<T> clazz) {
        final List<T> list = listOf(it);
        final T[] result = (T[]) Array.newInstance(clazz, list.size());
        int i = 0;
        for (final T t : it) {
            result[i] = t;
            i++;
        }
        return result;
    }

    /**
     * Creates a set of specified items.
     */
    @SuppressWarnings("unchecked")
    public static <T> Set<T> setOf(T... items) {
        final HashSet<T> result = new HashSet<>();
        result.addAll(Arrays.asList(items));
        return result;
    }

    /**
     * Creates a set of specified items.
     */
    public static <T> Set<T> setOf(Iterable<T> items) {
        final HashSet<T> result = new HashSet<>();
        for (final T item : items) {
            result.add(item);
        }
        return result;
    }

    /**
     * Creates a map of specified key/value. Key of should be declared in sequence as
     * <code>mapOf(key1, value1, key2, value2,...)</code>
     */
    @SuppressWarnings("unchecked")
    public static <T, U> Map<T, U> mapOf(T key, U value, Object... others) {
        final Map<T, U> result = new HashMap<>();
        result.put(key, value);
        for (int i = 0; i < others.length; i = i + 2) {
            final T otherKey = (T) others[i];
            final U otherValue = (U) others[i + 1];
            result.put(otherKey, otherValue);
        }
        return result;
    }

    /**
     * Creates a map of specified key/value. Key of should be declared in sequence as
     * <code>mapOf(key1, value1, key2, value2,...)</code>
     */
    @SuppressWarnings("unchecked")
    public static <T, U> Map<T, U> mapOfAny(Object... others) {
        final Map<T, U> result = new LinkedHashMap<>();
        for (int i = 0; i < others.length; i = i + 2) {
            final T otherKey = (T) others[i];
            final U otherValue = (U) others[i + 1];
            result.put(otherKey, otherValue);
        }
        return result;
    }

    private static <T> List<Iterable<T>> removeEmptyIt(Iterable<Iterable<T>> iterables) {
        final List<Iterable<T>> result = new LinkedList<>();
        for (final Iterable<T> iterable : iterables) {
            if (iterable.iterator().hasNext()) {
                result.add(iterable);
            }
        }
        return result;
    }

    /**
     * Convenient method to put several entry in a map having the same value at
     * once.
     */
    public static <K, V> void putMultiEntry(Map<K, V> map, Iterable<K> keys, V value) {
        for (final K key : keys) {
            map.put(key, value);
        }
    }

    /**
     * Returns a list that is a concatenation of the specified lists.
     * The result is not backed by specified {@link Iterable}.
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> concatLists(Iterable<? extends T>... lists) {
        final List<T> result = new LinkedList<>();
        for (final Iterable<? extends T> list : lists) {
            for (final T item : list) {
                result.add(item);
            }
        }
        return result;
    }

    /**
     * Creates a {@link Map} and populates it with specified properties.
     */
    public static Map<String, String> propertiesToMap(Properties properties) {
        final Map<String, String> result = new HashMap<>();
        for (final Object propKey : properties.keySet()) {
            result.put(propKey.toString(), properties.getProperty(propKey.toString()));
        }
        return result;
    }

    /**
     * Returns a string representation of the specified map constructed as
     * [key0]=[value0], [key1]=[value1], ...
     */
    @SuppressWarnings("unchecked")
    public static String toString(Map<?, ?> map) {
        final StringBuilder builder = new StringBuilder();
        for (final Iterator<?> it = map.entrySet().iterator(); it.hasNext();) {
            final Map.Entry<Object, Object> entry = (Entry<Object, Object>) it.next();
            builder.append(entry.getKey()).append("=");
            builder.append(JkUtilsObject.toString(entry.getValue()));
            if (it.hasNext()) {
                builder.append(", ");
            }
        }
        return builder.toString();
    }

    /**
     * Returns a multi-line string representation of the specified map
     * constructed as [key0]=[value0], [key1]=[value1], ...
     */
    @SuppressWarnings("unchecked")
    public static List<String> toStrings(Map<?, ?> map) {
        final List<String> result = new LinkedList<>();
        for (final Object name : map.entrySet()) {
            final Map.Entry<Object, Object> entry = (Entry<Object, Object>) name;
            result.add(entry.getKey() + "=" + JkUtilsObject.toString(entry.getValue()));
        }
        return result;
    }

    /**
     * Concats two arrays
     */
    public static <T> T[] concat(T[] a, T[] b) {
        final int aLen = a.length;
        final int bLen = b.length;

        @SuppressWarnings("unchecked")
        final T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
        System.arraycopy(a, 0, c, 0, aLen);
        System.arraycopy(b, 0, c, aLen, bLen);

        return c;
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/JkDocPluginDeps.java<|end_filename|>
package dev.jeka.core.tool;

import java.lang.annotation.*;

/**
 * Mentions that the annotated plugin class relies on other plugins.
 *
 * @author <NAME>
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@Inherited
public @interface JkDocPluginDeps {

    /**
     * Plugins classes this plugin relies on.
     */
    Class<? extends JkPlugin>[] value();

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/PackageDependencyTest.java<|end_filename|>
package dev.jeka.core;

import dev.jeka.core.tool.Main;
import jdepend.framework.JDepend;
import jdepend.framework.JavaClass;
import jdepend.framework.JavaPackage;
import jdepend.framework.PackageFilter;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@SuppressWarnings("javadoc")
public class PackageDependencyTest {

    @Test
    public void testDependencies() throws Exception {
        final String packagePrefix = "dev.jeka.core";
        final File classDir = Paths.get(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toFile();
        final String cycle = PackageAnalyser.of(classDir, packagePrefix).cycle();
        Assert.assertTrue(cycle, cycle == null);
    }

    public static class PackageAnalyser {

        private final Collection<JavaPackage> packages;

        private PackageAnalyser(Collection<JavaPackage> packages) {
            this.packages = packages;
        }

        @SuppressWarnings("unchecked")
        public static PackageAnalyser of(File classDir, final String packagePrefix) {
            final PackageFilter filter = new PackageFilter() {

                @Override
                public boolean accept(String name) {
                    return name.startsWith(packagePrefix);
                }

            };
            final JDepend depend = new JDepend(filter);
            try {
                depend.addDirectory(classDir.getPath());
            } catch (final IOException e) {
                throw new RuntimeException(e);
            }
            final Collection<JavaPackage> packages = depend.analyze();
            return new PackageAnalyser(packages);
        }

        public String cycle() {
            for (final JavaPackage javaPackage : packages) {
                if (javaPackage.containsCycle()) {
                    return "package " + javaPackage.getName() + " involved in cycles : " + cycleAsString(javaPackage);
                }
            }
            return null;
        }

        private static String cycleAsString(JavaPackage root) {
            final List<JavaPackage> involvedPackages = new ArrayList<>();
            root.collectCycle(involvedPackages);
            final StringBuilder builder = new StringBuilder();
            for (final JavaPackage involvedPackage : involvedPackages) {
                builder.append(involvedPackage.getName()).append(" -> ");
            }
            if (builder.length() > 4) {
                builder.delete(builder.length() - 4, builder.length());
            }
            builder.append("\n");

            for (int i = 0; i < involvedPackages.size()-1; i++) {
                final JavaPackage pack = involvedPackages.get(i);
                final JavaPackage nextPack = involvedPackages.get(i+1);
                builder.append("\nInvolved classes of ").append(pack.getName()).append("\n");
                builder.append("------------------------------------------\n");
                for (final Object javaClassObject : pack.getClasses()) {
                    final JavaClass javaClass = (JavaClass) javaClassObject;
                    for (final Object importedPackageObject : javaClass.getImportedPackages()) {
                        final JavaPackage importedPackage = (JavaPackage) importedPackageObject;
                        if (nextPack.getName().startsWith(importedPackage.getName())) {
                            builder.append(javaClass.getName()).append("\n");
                        }
                    }
                }
            }
            return builder.toString();
        }

    }

}

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/system/JkInfo.java<|end_filename|>
package dev.jeka.core.api.system;

import dev.jeka.core.api.utils.JkUtilsString;

import java.io.File;
import java.net.URL;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

/**
 * Provides information about Jeka running instance.
 */
public final class JkInfo {

    private static String version;

    public static final String JEKA_MODULE_ID = "dev.jeka:jeka-core";

    /**
     * Returns the current Jeka version.
     */
    public static String getJekaVersion() {
        if (JkUtilsString.isBlank(version)) {
            final Class<?> clazz = JkInfo.class;
            final String className = clazz.getSimpleName() + ".class";
            final String classPath = clazz.getResource(className).toString();
            if (!classPath.startsWith("jar")) {
                // Class not from JAR
                final String relativePath = clazz.getName().replace('.', File.separatorChar)
                        + ".class";
                final String classFolder = classPath.substring(0,
                        classPath.length() - relativePath.length() - 1);
                final String manifestPath = classFolder + "/META-INF/MANIFEST.MF";
                version = readVersionFrom(manifestPath);
            } else {
                final String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1)
                        + "/META-INF/MANIFEST.MF";
                version = readVersionFrom(manifestPath);
            }
        }
        return version;
    }

    private static String readVersionFrom(String manifestPath) {
        Manifest manifest;
        try {
            manifest = new Manifest(new URL(manifestPath).openStream());
            final Attributes attrs = manifest.getMainAttributes();
            return attrs.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/depmanagement/JkExternalModuleTest.java<|end_filename|>
package dev.jeka.core.api.depmanagement;

import org.junit.Test;

@SuppressWarnings("javadoc")
public class JkExternalModuleTest {

    @SuppressWarnings("unused")
    @Test
    public void testOf() {
        JkDependency dep;
        dep = JkModuleDependency.of(JkModuleId.of("org.hibernate", "hibernate-core"),
                JkVersion.of("3.0.1.Final"));
        dep = JkModuleDependency.of("org.hibernate", "hibernate-core", "3.0.1.Final");
        dep = JkModuleDependency.of("org.hibernate:hibernate-core:3.0.1+");
    }

}


<|start_filename|>dev.jeka.core-samples/jekaw.bat<|end_filename|>
@echo off

@rem Change here the default JVM options
@rem SET JEKA_OPTS == ""

@rem set terminal encoding to utf-8
chcp 65001 > nul

if not "%JEKA_JDK%" == "" set "JAVA_HOME=%JEKA_JDK%"
if "%JAVA_HOME%" == "" set "JAVA_CMD=java"
if not "%JAVA_HOME%" == "" set "JAVA_CMD=%JAVA_HOME%\bin\java"

if exist %cd%\jeka\boot set "LOCAL_BUILD_DIR=.\jeka\boot\*;"
set "COMMAND="%JAVA_CMD%" %JEKA_OPTS% -cp "%LOCAL_BUILD_DIR%%~dp0jeka\wrapper\*" dev.jeka.core.wrapper.Booter %~dp0 %*"
if not "%JEKA_ECHO_CMD%" == "" (
	@echo on
	echo %COMMAND%
	@echo off)
%COMMAND%


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/tool/FailureTest.java<|end_filename|>
package dev.jeka.core.tool;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

@SuppressWarnings("javadoc")
@Ignore
public class FailureTest {

    @Test
    public void doAssertFailure() {
        Assert.fail("it must fail");
    }

    @Test
    public void doExceptionraise() {
        throw new RuntimeException(new RuntimeException("exception2"));
    }

    @Test
    @Ignore
    public void doIgnore() {
        throw new RuntimeException();
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/java/package-info.java<|end_filename|>
/**
 * Contains classes providing fluent API for dealing with java tools, classpaths
 * and classloaders.
 */
package dev.jeka.core.api.java;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/package-info.java<|end_filename|>
/**
 * Contains core classes of Jeka automation tool.
 */
package dev.jeka.core.tool;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/utils/JkUtilsJdk.java<|end_filename|>
package dev.jeka.core.api.utils;

import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Convenient methods to deal with running JDK.
 */
public final class JkUtilsJdk {

    private JkUtilsJdk() {
        // Can not instantiate
    }

    /**
     * Returns the tool library file of the running JDK.
     */
    public static Path toolsJar() {
        final String jdkLocation = System.getProperty("java.home");
        final Path javaHome = Paths.get(jdkLocation);
        return javaHome.resolve("../lib/tools.jar").normalize().toAbsolutePath();
    }

    public static Path javaHome() {
        final String jdkLocation = System.getProperty("java.home");
        return Paths.get(jdkLocation);
    }

    public static int runningMajorVersion() {
        String version = System.getProperty("java.version");
        if(version.startsWith("1.")) {
            version = version.substring(2, 3);
        } else {
            int dot = version.indexOf(".");
            if(dot != -1) { version = version.substring(0, dot); }
        }
        return Integer.parseInt(version);
    }

}


<|start_filename|>dev.jeka.core/jeka/doc-templates/menuItem.css<|end_filename|>
.menuItem0 {
    font-size: 1.5em;
    border-bottom: 1px solid #cccccc;
}
.menuItem1 {
    font-weight: bold;
    font-size: x-large;
}
.menuItem2 {
    margin-left: 2em;
    font-size: large;
    font-weight: bold;
}
.menuItem3 {
    margin-left: 4em;
    font-weight: bold;
}
.menuItem4 {
    margin-left: 6em;
}
.menuItem5 {
    margin-left: 8em;
}

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/builtins/package-info.java<|end_filename|>
/**
 * Contains plugins provided with Jeka core. Each plugin may be moved later in
 * their dedicated project.
 */
package dev.jeka.core.tool.builtins;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/utils/JkUtilsXml.java<|end_filename|>
package dev.jeka.core.api.utils;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.OutputStream;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;

/**
 * Utilities methods to ease XML api of the JDK
 *
 * @author <NAME>
 */
public final class JkUtilsXml {

    private JkUtilsXml() {
        // Can't instantiate
    }

    /**
     * Creates an empty document.
     */
    public static Document createDocument() {
        final DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder icBuilder;
        try {
            icBuilder = icFactory.newDocumentBuilder();
            return icBuilder.newDocument();
        } catch (final Exception e) {
            throw JkUtilsThrowable.unchecked(e);
        }
    }

    /**
     * Creates a document from the specified file.
     */
    public static Document documentFrom(File documentFile) {
        if (!documentFile.exists()) {
            throw new IllegalStateException(documentFile.getAbsolutePath() + " file not found.");
        }
        final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        try {
            final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc;
            doc = dBuilder.parse(documentFile);
            doc.getDocumentElement().normalize();
            return doc;
        } catch (final Exception e) {
            throw new RuntimeException("Error while parsing file " + documentFile.getPath(), e);
        }
    }

    public static Document documentFrom(Path documentFile) {
        if (!Files.exists(documentFile)) {
            throw new IllegalStateException(documentFile.toAbsolutePath().normalize() + " file not found.");
        }
        final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        try {
            final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc;
            doc = dBuilder.parse(documentFile.toFile());
            doc.getDocumentElement().normalize();
            return doc;
        } catch (final Exception e) {
            throw new RuntimeException("Error while parsing file " + documentFile, e);
        }
    }

    /**
     * Creates a document from the specified xml string.
     */
    public static Document documentFrom(String xml) {
        final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        try {
            final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc;
            doc = dBuilder.parse(new InputSource(new StringReader(xml)));
            doc.getDocumentElement().normalize();
            return doc;
        } catch (final Exception e) {
            throw new RuntimeException("Error while parsing xml \n" + xml, e);
        }
    }

    /**
     * Returns the direct getChild node of the specified element having specified
     * name.
     */
    public static Element directChild(Node parent, String childName) {
        final NodeList nodeList = parent.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            final Node node = nodeList.item(i);
            if (node instanceof Element) {
                final Element element = (Element) node;
                if (element.getTagName().equals(childName)) {
                    return element;
                }
            }
        }
        return null;
    }

    /**
     * Returns specified element direct getChild node elements.
     */
    public static List<Element> directChildren(Element parent, String childName) {
        final List<Element> result = new LinkedList<>();
        final NodeList nodeList = parent.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            final Node node = nodeList.item(i);
            if (node instanceof Element) {
                final Element element = (Element) node;
                if (element.getTagName().equals(childName)) {
                    result.add(element);
                }
            }
        }
        return result;
    }

    /**
     * Returns the text of the specified direct getChild of the specified element.
     */
    public static String directChildText(Element parent, String childName) {
        final Element child = directChild(parent, childName);
        if (child == null) {
            return null;
        }
        return child.getTextContent();
    }

    /**
     * Prints the specified document in the specified output getOutputStream.
     * The output is indented.
     */
    public static void output(Document doc, OutputStream outputStream) {
        Transformer transformer;
        try {
            transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            final DOMSource source = new DOMSource(doc);
            final StreamResult console = new StreamResult(outputStream);
            transformer.transform(source, console);
        } catch (final Exception e) {
            throw JkUtilsThrowable.unchecked(e);
        }
    }
}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/api/utils/package-info.java<|end_filename|>
/**
 * Contains Jeka utility classes (meaning classes holding only static helper
 * methods). These classes have been created to avoid dependency on Guava or
 * Jakarta-commons.
 */
package dev.jeka.core.api.utils;

<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/PluginOptions.java<|end_filename|>
package dev.jeka.core.tool;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

class PluginOptions {

    @SuppressWarnings("unchecked")
    static PluginOptions of(String name) {
        return new PluginOptions(name, Collections.EMPTY_MAP);
    }

    final String pluginName;

    private final Map<String, String> options;

    private PluginOptions(String pluginName, Map<String, String> options) {
        super();
        this.pluginName = pluginName;
        this.options = Collections.unmodifiableMap(options);
    }

    PluginOptions with(String key, String value) {
        final Map<String, String> map = new HashMap<>(options);
        map.put(key, value);
        return new PluginOptions(pluginName, map);
    }

    @Override
    public String toString() {
        return pluginName + " : " + options;
    }

    static Map<String, String> options(String name, Iterable<PluginOptions> pluginOptionsList) {
        for (PluginOptions pluginOptions : pluginOptionsList) {
            if (pluginOptions.pluginName.equals(name)) {
                return pluginOptions.options;
            }
        }
        return Collections.emptyMap();
    }
}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/crypto/gpg/JkGpgTest.java<|end_filename|>
package dev.jeka.core.api.crypto.gpg;

import dev.jeka.core.tool.JkConstants;
import org.junit.Assert;
import org.junit.Test;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@SuppressWarnings("javadoc")
public class JkGpgTest {

    @Test
    public void testSign() throws Exception {
        final Path pubFile = Paths.get(JkGpgTest.class.getResource("pubring.gpg").toURI());
        final Path secringFile = Paths.get(JkGpgTest.class.getResource("secring.gpg").toURI());
        final JkGpg pgp = JkGpg.of(pubFile, secringFile, "jerkar");
        final Path signatureFile = Paths.get(JkConstants.OUTPUT_PATH+ "/test-out/signature.asm");
        if (!Files.exists(signatureFile)) {
            Files.createDirectories(signatureFile.getParent());
            Files.createFile(signatureFile);
        }
        final Path sampleFile = Paths.get(JkGpgTest.class.getResource("sampleFileToSign.txt").toURI());
        Path signature = pgp.sign(sampleFile, "");
        System.out.println("Signature file : " + signature);
    }

    @Test(expected = RuntimeException.class)
    public void testSignWithBadPassword() throws Exception {
        final Path pubFile = Paths.get(JkGpgTest.class.getResource("pubring.gpg").toURI());
        final Path secringFile = Paths.get(JkGpgTest.class.getResource("secring.gpg").toURI());
        final JkGpg pgp = JkGpg.of(pubFile, secringFile, "badPassword");
        final Path signatureFile = Paths.get(JkConstants.OUTPUT_PATH + "/test-out/signature-fake.asm");
        if (!Files.exists(signatureFile)) {
            Files.createDirectories(signatureFile.getParent());
            Files.createFile(signatureFile);
        }
        final Path sampleFile = Paths.get(JkGpgTest.class.getResource("sampleFileToSign.txt").toURI());
        pgp.withSecretRingPassword("bad password").sign(sampleFile, "", signatureFile);
        Assert.assertTrue(pgp.verify(sampleFile, signatureFile));
    }

}


<|start_filename|>dev.jeka.core/src/test/java/dev/jeka/core/api/crypto/gpg/PgpRunner.java<|end_filename|>
package dev.jeka.core.api.crypto.gpg;

import java.nio.file.Path;
import java.nio.file.Paths;

public class PgpRunner {

    private static final String PGPUTILS_CLASS_NAME = "dev.jeka.core.api.crypto.pgp.embedded.bc.PgpUtils";

    public static void main(String[] args) throws Exception {
        System.out.println("ttt".startsWith(""));
        final Path sampleFile = Paths.get(JkGpgTest.class.getResource("sampleFileToSign.txt").toURI());
        JkGpg.ofDefaultGnuPg().withSecretRingPassword("").sign(sampleFile, "");
    }

}


<|start_filename|>dev.jeka.core/src/main/java/dev/jeka/core/tool/JkHelpOptions.java<|end_filename|>
package dev.jeka.core.tool;

import java.nio.file.Path;

/**
 * Options for help method.
 */
public final class JkHelpOptions {

    @JkDoc("Output help formatted in XML if true. To be used in conjonction of -silent option to parse the output getOutputStream friendly.")
    public boolean xml;

    @JkDoc("Output help in this xml file. If xml option is false, no need to specify help.xml option.")
    public Path xmlFile;

    /**
     * Returns true if the help output must be formatted using XML.
     */
    public boolean xml() {
        return xml;
    }

}