Last active
January 29, 2026 12:52
-
-
Save mcgivrer/3fabaa2cd1a1e1fc934c7b5da6a6e8ca to your computer and use it in GitHub Desktop.
java project micro build with libs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| #---- project parameters | |
| project_name=[[DEFAULT_APP_NAME]] | |
| project_version=[[DEFAULT_APP_VERSION]] | |
| main_class=[[DEFAULT_MAIN_CLASS]] | |
| vendor_name="[[DEFAULT_VENDOR_NAME]]" | |
| author_name=[[DEFAULT_AUTHOR_NAME]] | |
| JARS= | |
| SOURCE_VERSION="25" | |
| JAR_OPTS="-Xmx512m" | |
| # | |
| #--- DO NOT CHANGE THE FOLLOWING LINES --- | |
| # | |
| main_class_array=($main_class) | |
| num_main_classes=${#main_class_array[@]} | |
| SRC=./src | |
| LIBS=./libs | |
| TARGET=./target | |
| BUILD=${TARGET}/build | |
| CLASSES=${TARGET}/classes | |
| RESOURCES=${SRC}/main/resources | |
| SOURCE_ENCODING="UTF-8" | |
| JARS=libs/dependencies/ | |
| COMPILATION_OPTS="-Xlint:unchecked -Xlint:deprecation -parameters" | |
| # add your test execution commands here | |
| TEST_CLASSES=${TARGET}/test-classes | |
| TEST_RESOURCES=${SRC}/test/resources | |
| LIB_TEST=$LIBS/junit-platform-console-standalone-6.0.0.jar | |
| # detect OS type to set the classpath separator | |
| if [[ "$OSTYPE" == "linux"* ]]; then | |
| FS=":" | |
| else | |
| FS=";" | |
| fi | |
| # define colors | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' | |
| #---- process buid | |
| GIT_COMMIT_ID=$(git rev-parse HEAD) | |
| JAVA_BUILD=$(java --version | head -1 | cut -f2 -d' ') | |
| #---- check SDKMAN | |
| REQUIRED_JAVA_VERSION=$SOURCE_VERSION | |
| JAVA_BIN=$(command -v java 2>/dev/null) | |
| JAVA_VERSION_DETECTED=$($JAVA_BIN -version 2>&1 | awk -F '[\"_]' '/version/ {print $2}' | cut -d'.' -f1) | |
| if [ -z "$JAVA_BIN" ] || [ "$JAVA_VERSION_DETECTED" != "$REQUIRED_JAVA_VERSION" ]; then | |
| echo -e "${RED}Java n'est pas installé. Tentative d'installation de Java $REQUIRED_JAVA_VERSION avec SDKMAN.${NC}" | |
| # Ensure the `sdk` command is available by sourcing SDKMAN init if installed | |
| if [ -z "$(command -v sdk 2>/dev/null)" ] && [ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]; then | |
| # shellcheck source=/dev/null | |
| source "$HOME/.sdkman/bin/sdkman-init.sh" | |
| if [ -f .sdkmanrc ]; then | |
| echo "Install SDKMAN environment" | |
| sdk env install | |
| sdk env use | |
| echo "done." | |
| fi | |
| fi | |
| else | |
| echo -e "${GREEN}Java détecté: version $JAVA_VERSION_DETECTED${NC}" | |
| fi | |
| # Prepare Build | |
| rm -vrf target/ | |
| find $SRC/main/java $RESOURCES -name "*.java" | |
| mkdir -vp ${TARGET}/{classes,build/libs} | |
| # Compile sources | |
| javac ${COMPILATION_OPTS} -cp libs/ $(find $SRC/main/java $RESOURCES -name "*.java") -d ${CLASSES} | |
| # create MANIFEST file | |
| cp -vr $RESOURCES/* $CLASSES | |
| echo "build jar..." | |
| for app in "${main_class_array[@]}"; do | |
| if [ $num_main_classes -eq 1 ]; then | |
| jar_name="${project_name}-${project_version}.jar" | |
| else | |
| jar_name="${project_name}-$app-${project_version}.jar" | |
| fi | |
| mkdir -p ${TARGET}/META-INF | |
| echo ">> for ${project_name}.$app..." | |
| echo """ | |
| Manifest-Version: ${project_name} | |
| Main-Class: ${app} | |
| Class-Path: ${JARS} | |
| Created-By: ${JAVA_BUILD} | |
| Implementation-Title: ${project_name} | |
| Implementation-Version: ${project_version}-build_${GIT_COMMIT_ID:0:12} | |
| Implementation-Vendor: ${vendor_name} | |
| Implementation-Author: ${author_name} | |
| """ >>${TARGET}/META-INF/MANIFEST.MF | |
| jar cvfe ${TARGET}/build/${jar_name} $app -C ${CLASSES} . | |
| # create run script | |
| echo "create run script ${project_name}.sh ..." | |
| rm -f ${project_name}.sh | |
| echo """#!/bin/bash | |
| java -cp libs/ -jar ${TARGET}/build/${jar_name} \$@ | |
| """ >${project_name}.sh | |
| chmod +x ${project_name}.sh | |
| echo "done." | |
| done | |
| if ([ "$1" == "test" ]); then | |
| echo "Run tests..." | |
| echo -e "|_ ${BLUE}6. Execute tests${NC}..." | |
| echo "> from : ${SRC}/test" | |
| echo "> to : ${TARGET}/test-classes" | |
| mkdir -p ${TARGET}/test-classes | |
| echo "copy test resources" | |
| cp -r ./$RESOURCES/* $TEST_CLASSES | |
| cp -r ./$TEST_RESOURCES/* $TEST_CLASSES | |
| echo "compile test classes" | |
| #list test sources | |
| find ${SRC}/main -name '*.java' >${TARGET}/sources.lst | |
| find ${SRC}/test -name '*.java' >${TARGET}/test-sources.lst | |
| javac -source $SOURCE_VERSION -encoding $SOURCE_ENCODING $COMPILATION_OPTS -cp ".${FS}$LIB_TEST${FS}${EXTERNAL_JARS}" -d $TEST_CLASSES @${TARGET}/sources.lst @${TARGET}/test-sources.lst | |
| echo "execute tests through JUnit" | |
| java $JAR_OPTS -jar $LIB_TEST execute -cp "${EXTERNAL_JARS}${FS}${CLASSES}${FS}${TEST_CLASSES}${FS}." --scan-class-path | |
| echo -e " |_ ${GREEN}done$NC" | |
| echo "- execute tests through JUnit ${SRC}/test." >>${TARGET}/build.log | |
| fi | |
| if ([ "$1" == "run" ]); then | |
| echo "Run the generated JAR(s)..." | |
| for app in "${main_class_array[@]}"; do | |
| if [ $num_main_classes -eq 1 ]; then | |
| jar_name="${project_name}-${project_version}.jar" | |
| else | |
| jar_name="${project_name}-$app-${project_version}.jar" | |
| fi | |
| echo ">> run JAR ${jar_name} ..." | |
| shift 1 | |
| java $JAR_OPTS -jar ${TARGET}/build/${jar_name} $@ | |
| echo "done." | |
| done | |
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package core; | |
| import static core.App.Log.error; | |
| import static core.App.Log.info; | |
| import static core.App.Log.warn; | |
| import java.io.IOException; | |
| import java.time.ZonedDateTime; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.Properties; | |
| public class App { | |
| public enum LogLevel { | |
| DEBUG, | |
| INFO, | |
| WARN, | |
| ERROR, | |
| FATAL; | |
| } | |
| public enum AppMode { | |
| DEVELOPMENT, | |
| TESTING, | |
| PRODUCTION; | |
| } | |
| public static class Log { | |
| public static void log(Class<?> cls, LogLevel level, String message, Object... args) { | |
| if (!(mode.equals(AppMode.DEVELOPMENT) && LogLevel.DEBUG.equals(level)) && isDebugGreaterThan(0)) { | |
| return; | |
| } | |
| System.out.printf("%s;%s;%s;%s%n", | |
| ZonedDateTime.now(), | |
| cls.getCanonicalName(), | |
| level.name(), | |
| message.formatted(args)); | |
| } | |
| public static void debug(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.DEBUG, message, args); | |
| } | |
| public static void info(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.INFO, message, args); | |
| } | |
| public static void warn(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.WARN, message, args); | |
| } | |
| public static void error(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.ERROR, message, args); | |
| } | |
| public static void fatal(Class<?> cls, int errCode, String message, Object... args) { | |
| log(cls, LogLevel.FATAL, message, args); | |
| System.exit(errCode); | |
| } | |
| } | |
| public static class Configuration { | |
| interface ConfigParser<T> { | |
| void parseConfig(String value); | |
| T getDefaultValue(); | |
| T getValue(); | |
| String getDescription(); | |
| } | |
| private Properties config = new Properties(); | |
| public static final String DEBUG = "debug"; | |
| public static final String MODE = "mode"; | |
| public static final String TIMEOUT = "timeout"; | |
| public static final Map<String, Object> values = new HashMap<>(); | |
| public static final Map<String, ConfigParser<?>> parsers = new HashMap<>(); | |
| public Configuration(String[] args) { | |
| // set default values | |
| info(getClass(), "Set default configuration"); | |
| config.setProperty("debug", "0"); | |
| config.setProperty("mode", "DEVELOPMENT"); | |
| parsers.put("debug", new ConfigParser<Integer>() { | |
| int debug = 0; | |
| public void parseConfig(String value) { | |
| try { | |
| debug = Integer.parseInt(value); | |
| } catch (NumberFormatException e) { | |
| debug = getDefaultValue(); | |
| } | |
| }; | |
| public Integer getDefaultValue() { | |
| return 0; | |
| } | |
| public Integer getValue() { | |
| return Integer.valueOf(debug); | |
| } | |
| public String getDescription() { | |
| return "Set debug level (0=none, 1=some, 2=verbose)"; | |
| } | |
| }); | |
| parsers.put("mode", new ConfigParser<AppMode>() { | |
| AppMode mode = AppMode.DEVELOPMENT; | |
| public void parseConfig(String value) { | |
| try { | |
| mode = AppMode.valueOf(value.toUpperCase()); | |
| } catch (IllegalArgumentException e) { | |
| mode = getDefaultValue(); | |
| } | |
| }; | |
| public AppMode getDefaultValue() { | |
| return AppMode.DEVELOPMENT; | |
| } | |
| public AppMode getValue() { | |
| return mode; | |
| } | |
| public String getDescription() { | |
| return "Set application mode (DEVELOPMENT, TESTING, PRODUCTION)"; | |
| } | |
| }); | |
| parsers.put("help", new ConfigParser<Boolean>() { | |
| public void parseConfig(String value) { | |
| info(getClass(), " help requested, exiting..."); | |
| System.out.println("Usage: java -jar app.jar [key=value]..."); | |
| parsers.forEach((key, parser) -> { | |
| System.out.printf(" --%-10s=<%-10s> : %s (default: %s)%n", | |
| key, | |
| parser.getDefaultValue().getClass().getSimpleName(), | |
| parser.getDescription(), | |
| parser.getDefaultValue().toString()); | |
| }); | |
| }; | |
| public Boolean getDefaultValue() { | |
| return true; | |
| } | |
| public Boolean getValue() { | |
| System.exit(0); | |
| return null; | |
| } | |
| public String getDescription() { | |
| return "Show help message"; | |
| } | |
| }); | |
| extractConfigurationValues(args); | |
| } | |
| private void extractConfigurationValues(String[] args) { | |
| parseConfiguration(); | |
| info(App.class, " -> default configuration initialized"); | |
| // parse configuration file | |
| try { | |
| info(getClass(), "Load configuration from file"); | |
| config.load(App.class.getResourceAsStream("/config.properties")); | |
| info(App.class, " loaded config.properties"); | |
| parseConfiguration(); | |
| info(App.class, " -> configuration loaded"); | |
| } catch (IOException e) { | |
| error(App.class, " cannot load config.properties: %s", e.getMessage()); | |
| } | |
| // parse command line arguments | |
| parseCliArgs(args); | |
| parseConfiguration(); | |
| } | |
| private void parseConfiguration() { | |
| for (String key : config.stringPropertyNames()) { | |
| parseConfig(key, config.getProperty(key)); | |
| } | |
| } | |
| private void parseCliArgs(String[] args) { | |
| if (args.length > 0) { | |
| info(getClass(), "parse args:"); | |
| int i = 0; | |
| for (String arg : args) { | |
| Log.debug(getClass(), "- arg[%d]: %s", i++, arg); | |
| parseArg(arg); | |
| } | |
| } else { | |
| info(getClass(), "- no argument..."); | |
| } | |
| } | |
| private void parseArg(String arg) { | |
| if (arg.contains("=")) { | |
| String[] key = arg.split("=", 2); | |
| config.setProperty(key[0].trim().replace("--", ""), key[1].trim()); | |
| } else { | |
| config.setProperty(arg.trim().replace("--", ""), "true"); | |
| } | |
| } | |
| private void parseConfig(String key, String value) { | |
| ConfigParser<?> parser = parsers.get(key); | |
| if (parser != null) { | |
| parser.parseConfig(value); | |
| values.put(key, parser.getValue()); | |
| info(getClass(), " set %s=%s (%s)", key, parser.getValue().toString(), parser.getDescription()); | |
| } else { | |
| warn(getClass(), " unknown argument: %s=%s", key, value); | |
| } | |
| } | |
| public <T> T getValue(String key) { | |
| return (T) values.get(key); | |
| } | |
| } | |
| private Configuration config; | |
| public static int debug = 0; | |
| private static AppMode mode = AppMode.DEVELOPMENT; | |
| public App() { | |
| info(getClass(), "Start App class..."); | |
| } | |
| public void run(String[] args) { | |
| initialize(args); | |
| process(); | |
| info(getClass(), "End App class."); | |
| } | |
| protected void process() { | |
| } | |
| private void initialize(String[] args) { | |
| config = new Configuration(args); | |
| debug = (int) config.getValue("debug"); | |
| mode = (AppMode) config.getValue("mode"); | |
| info(getClass(), " -> App initialized with debug=%d, mode=%s", debug, mode.name()); | |
| } | |
| public static void main(String[] args) { | |
| App app = new App(); | |
| app.run(args); | |
| } | |
| public static boolean isDebugGreaterThan(int level) { | |
| return debug > level; | |
| } | |
| public Configuration getConfiguration() { | |
| return config; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| if [ "$#" -ne 1 ]; then | |
| echo "Usage: $0 <project_name>" | |
| echo "Description: create a java project structure into <project_name> with build script" | |
| echo "NOTE: if git user.name and user.email configuration are not set, git initialization will fail" | |
| echo " Make sure to set them using:" | |
| echo " git config --global user.name \"Your Name\"" | |
| echo " git config --global user.email \"[email protected]\"" | |
| echo " After setting these, rerun the script." | |
| exit 1 | |
| fi | |
| JUNIT_VERSION=6.0.1 | |
| GIT_USERNAME="$(git config --get user.name)<$(git config --get user.email)>" | |
| # create project structure | |
| mkdir -p $1/{src/{{main,test}/{java/core,resources},docs},libs,.vscode} | |
| # add readme | |
| echo """# README | |
| ## Project $1 version 0.0.1 | |
| ### Build JAR with sdkman and javac | |
| \`\`\`bash | |
| sdk env use | |
| chmod +x ./build | |
| ./build | |
| \`\`\` | |
| ### Run tests | |
| \`\`\`bash | |
| ./build test | |
| \`\`\` | |
| ### Execute project | |
| \`\`\`bash | |
| ./build run debug=2 | |
| \`\`\` | |
| >**Note** | |
| >You can pass as many argument after run as you need: | |
| >e.g.: | |
| > - \`debug\`=[1 to 5], | |
| > - \`mode\`=[DEVELOPMENT,TESTING,PRODUCTION] | |
| > - \`timeout\`=[milliseconds] | |
| #### help on program | |
| \`\`\`bash | |
| ./build run help | |
| \`\`\` | |
| #### run from java | |
| \`\`\`bash | |
| java -jar target/build/$1-0.0.1.jar debug=2 | |
| \`\`\` | |
| Thanks, | |
| $GIT_USERNAME. | |
| """ >$1/README.md | |
| # add gitignore | |
| echo "target/" >$1/.gitignore | |
| # add sdkman config | |
| echo "java=25-zulu" >$1/.sdkmanrc | |
| ## download JUnit | |
| curl -sL https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/$JUNIT_VERSION/junit-platform-console-standalone-$JUNIT_VERSION.jar >$1/libs/junit-platform-console-standalone-$JUNIT_VERSION.jar | |
| ## build script | |
| curl -sL https://gist.githubusercontent.com/mcgivrer/3fabaa2cd1a1e1fc934c7b5da6a6e8ca/raw/build >$1/build | |
| sed -i \ | |
| -e "s/\[\[DEFAULT_APP_NAME\]\]/$1/g" \ | |
| -e "s/\[\[DEFAULT_APP_VERSION\]\]/0.0.1/g" \ | |
| -e "s/\[\[DEFAULT_MAIN_CLASS\]\]/core.App/g" \ | |
| -e "s/\[\[DEFAULT_AUTHOR_NAME\]\]/\"$GIT_USERNAME\"/g" \ | |
| -e "s/\[\[DEFAULT_VENDOR_NAME\]\]/VENDORNAME/g" \ | |
| "$1/build" | |
| chmod +x $1/build | |
| ## create VSCode support | |
| echo """ | |
| { | |
| \"java.project.sourcePaths\": [ | |
| \"src/main/java\", | |
| \"src/main/resources\", | |
| \"src/test/java\", | |
| \"src/test/resources\" | |
| ], | |
| \"java.project.referencedLibraries\": [ | |
| \"libs/junit-platform-console-standalone-6.0.0.jar\" | |
| ], | |
| \"java.project.outputPath\": \"target/classes\" | |
| } | |
| """ >$1/.vscode/settings.json | |
| ## create .gitignore file | |
| echo """# Compiled class files | |
| *.class | |
| # Log files | |
| *.log | |
| # Package files | |
| *.jar | |
| *.war | |
| *.ear | |
| # Maven target directory | |
| target/ | |
| # Eclipse files | |
| .classpath | |
| .project | |
| .settings/ | |
| # IntelliJ IDEA files | |
| *.iml | |
| .idea/ | |
| # VSCode files | |
| .vscode/ | |
| """ >$1/.gitignore | |
| ## Create Main app class source | |
| echo """package core; | |
| import static core.App.Log.error; | |
| import static core.App.Log.info; | |
| import static core.App.Log.warn; | |
| import java.io.IOException; | |
| import java.time.ZonedDateTime; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.Properties; | |
| public class App { | |
| public enum LogLevel { | |
| DEBUG, | |
| INFO, | |
| WARN, | |
| ERROR, | |
| FATAL; | |
| } | |
| public enum AppMode { | |
| DEVELOPMENT, | |
| TESTING, | |
| PRODUCTION; | |
| } | |
| public static class Log { | |
| public static void log(Class<?> cls, LogLevel level, String message, Object... args) { | |
| if (!(mode.equals(AppMode.DEVELOPMENT) && LogLevel.DEBUG.equals(level)) && isDebugGreaterThan(0)) { | |
| return; | |
| } | |
| System.out.printf(\"%s;%s;%s;%s%n\", | |
| ZonedDateTime.now(), | |
| cls.getCanonicalName(), | |
| level.name(), | |
| message.formatted(args)); | |
| } | |
| public static void debug(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.DEBUG, message, args); | |
| } | |
| public static void info(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.INFO, message, args); | |
| } | |
| public static void warn(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.WARN, message, args); | |
| } | |
| public static void error(Class<?> cls, String message, Object... args) { | |
| log(cls, LogLevel.ERROR, message, args); | |
| } | |
| public static void fatal(Class<?> cls, int errCode, String message, Object... args) { | |
| log(cls, LogLevel.FATAL, message, args); | |
| System.exit(errCode); | |
| } | |
| } | |
| public static class Configuration { | |
| interface ConfigParser<T> { | |
| void parseConfig(String value); | |
| T getDefaultValue(); | |
| T getValue(); | |
| String getDescription(); | |
| } | |
| private Properties config = new Properties(); | |
| public static final String DEBUG = \"debug\"; | |
| public static final String MODE = \"mode\"; | |
| public static final String TIMEOUT = \"timeout\"; | |
| public static final Map<String, Object> values = new HashMap<>(); | |
| public static final Map<String, ConfigParser<?>> parsers = new HashMap<>(); | |
| public Configuration(String[] args) { | |
| // set default values | |
| info(getClass(), \"Set default configuration\"); | |
| config.setProperty(\"debug\", \"0\"); | |
| config.setProperty(\"mode\", \"DEVELOPMENT\"); | |
| parsers.put(\"debug\", new ConfigParser<Integer>() { | |
| int debug = 0; | |
| public void parseConfig(String value) { | |
| try { | |
| debug = Integer.parseInt(value); | |
| } catch (NumberFormatException e) { | |
| debug = getDefaultValue(); | |
| } | |
| }; | |
| public Integer getDefaultValue() { | |
| return 0; | |
| } | |
| public Integer getValue() { | |
| return Integer.valueOf(debug); | |
| } | |
| public String getDescription() { | |
| return \"Set debug level (0=none, 1=some, 2=verbose)\"; | |
| } | |
| }); | |
| parsers.put(\"mode\", new ConfigParser<AppMode>() { | |
| AppMode mode = AppMode.DEVELOPMENT; | |
| public void parseConfig(String value) { | |
| try { | |
| mode = AppMode.valueOf(value.toUpperCase()); | |
| } catch (IllegalArgumentException e) { | |
| mode = getDefaultValue(); | |
| } | |
| }; | |
| public AppMode getDefaultValue() { | |
| return AppMode.DEVELOPMENT; | |
| } | |
| public AppMode getValue() { | |
| return mode; | |
| } | |
| public String getDescription() { | |
| return \"Set application mode (DEVELOPMENT, TESTING, PRODUCTION)\"; | |
| } | |
| }); | |
| parsers.put(\"help\", new ConfigParser<Boolean>() { | |
| public void parseConfig(String value) { | |
| info(getClass(), \" help requested, exiting...\"); | |
| System.out.println(\"Usage: java -jar app.jar [key=value]...\"); | |
| parsers.forEach((key, parser) -> { | |
| System.out.printf(\" --%-10s=<%-10s> : %s (default: %s)%n\", | |
| key, | |
| parser.getDefaultValue().getClass().getSimpleName(), | |
| parser.getDescription(), | |
| parser.getDefaultValue().toString()); | |
| }); | |
| }; | |
| public Boolean getDefaultValue() { | |
| return true; | |
| } | |
| public Boolean getValue() { | |
| System.exit(0); | |
| return null; | |
| } | |
| public String getDescription() { | |
| return \"Show help message\"; | |
| } | |
| }); | |
| extractConfigurationValues(args); | |
| } | |
| private void extractConfigurationValues(String[] args) { | |
| parseConfiguration(); | |
| info(App.class, \" -> default configuration initialized\"); | |
| // parse configuration file | |
| try { | |
| info(getClass(), \"Load configuration from file\"); | |
| config.load(App.class.getResourceAsStream(\"/config.properties\")); | |
| info(App.class, \" loaded config.properties\"); | |
| parseConfiguration(); | |
| info(App.class, \" -> configuration loaded\"); | |
| } catch (IOException e) { | |
| error(App.class, \" cannot load config.properties: %s\", e.getMessage()); | |
| } | |
| // parse command line arguments | |
| parseCliArgs(args); | |
| parseConfiguration(); | |
| } | |
| private void parseConfiguration() { | |
| for (String key : config.stringPropertyNames()) { | |
| parseConfig(key, config.getProperty(key)); | |
| } | |
| } | |
| private void parseCliArgs(String[] args) { | |
| if (args.length > 0) { | |
| info(getClass(), \"parse args:\"); | |
| int i = 0; | |
| for (String arg : args) { | |
| Log.debug(getClass(), \"- arg[%d]: %s\", i++, arg); | |
| parseArg(arg); | |
| } | |
| } else { | |
| info(getClass(), \"- no argument...\"); | |
| } | |
| } | |
| private void parseArg(String arg) { | |
| if (arg.contains(\"=\")) { | |
| String[] key = arg.split(\"=\", 2); | |
| config.setProperty(key[0].trim().replace(\"--\", \"\"), key[1].trim()); | |
| } else { | |
| config.setProperty(arg.trim().replace(\"--\", \"\"), \"true\"); | |
| } | |
| } | |
| private void parseConfig(String key, String value) { | |
| ConfigParser<?> parser = parsers.get(key); | |
| if (parser != null) { | |
| parser.parseConfig(value); | |
| values.put(key, parser.getValue()); | |
| info(getClass(), \" set %s=%s (%s)\", key, parser.getValue().toString(), parser.getDescription()); | |
| } else { | |
| warn(getClass(), \" unknown argument: %s=%s\", key, value); | |
| } | |
| } | |
| public <T> T getValue(String key) { | |
| return (T) values.get(key); | |
| } | |
| } | |
| private Configuration config; | |
| public static int debug = 0; | |
| private static AppMode mode = AppMode.DEVELOPMENT; | |
| public App() { | |
| info(getClass(), \"Start App class...\"); | |
| } | |
| public void run(String[] args) { | |
| initialize(args); | |
| process(); | |
| info(getClass(), \"End App class.\"); | |
| } | |
| protected void process() { | |
| } | |
| private void initialize(String[] args) { | |
| config = new Configuration(args); | |
| debug = (int) config.getValue(\"debug\"); | |
| mode = (AppMode) config.getValue(\"mode\"); | |
| info(getClass(), \" -> App initialized with debug=%d, mode=%s\", debug, mode.name()); | |
| } | |
| public static void main(String[] args) { | |
| App app = new App(); | |
| app.run(args); | |
| } | |
| public static boolean isDebugGreaterThan(int level) { | |
| return debug > level; | |
| } | |
| public Configuration getConfiguration() { | |
| return config; | |
| } | |
| } | |
| """ >$1/src/main/java/core/App.java | |
| # add config file | |
| echo """debug=2 | |
| mode=DEVELOPMENT | |
| """ >$1/src/main/resources/config.properties | |
| git init -b main --quiet $1/ | |
| cd $1 | |
| git add . | |
| git commit -m "Create Project $1" | |
| echo "==> Project $1 created." |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Use the
createscripts to create a simple Java project inspired by the Maven project structure :Create the project
Project Structure :
buildis the bash script to build your project.You need to define the following variables in the script:
Defining the jar output :
List jar dependencies for build and run :
libs/]Define entries for MANIFEST: