diff --git a/src/main/java/ru/etu/petci/Main.java b/src/main/java/ru/etu/petci/Main.java
index 144616f..4cab25d 100644
--- a/src/main/java/ru/etu/petci/Main.java
+++ b/src/main/java/ru/etu/petci/Main.java
@@ -1,6 +1,7 @@
package ru.etu.petci;
import ru.etu.petci.handlers.CommandHandler;
+import ru.etu.petci.handlers.ContinueCommandHandler;
import ru.etu.petci.handlers.InitCommandHandler;
import java.io.IOException;
@@ -10,7 +11,7 @@
public class Main {
public static final String SETTINGS_FILE_NAME = "settings.properties";
- public static String JOBS_DIR_NAME = "";
+ public static final String JOBS_DIR_NAME = "";
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
static {
@@ -38,7 +39,11 @@ public static void main(String[] args) {
handler = new InitCommandHandler();
exitStatus = handler.handle(args.length > 1 ? args[1] : "");
}
- case "continue" -> LOGGER.info("User entered \"continue\" command.");
+ case "continue" -> {
+ LOGGER.info("User entered \"continue\" command.");
+ handler = new ContinueCommandHandler();
+ exitStatus = handler.handle("");
+ }
case "add" -> LOGGER.info("User entered \"add\" command.");
default -> {
System.out.printf("petCI: \"%s\" is not a command. Use \"help\" command%n", args[0]);
diff --git a/src/main/java/ru/etu/petci/configuration/Configurator.java b/src/main/java/ru/etu/petci/configuration/Configurator.java
index 9da8974..e652a54 100644
--- a/src/main/java/ru/etu/petci/configuration/Configurator.java
+++ b/src/main/java/ru/etu/petci/configuration/Configurator.java
@@ -1,67 +1,57 @@
package ru.etu.petci.configuration;
+import ru.etu.petci.jobs.Job;
import ru.etu.petci.observers.RepositoryObserver;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.file.Files;
+import java.io.*;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Properties;
import static ru.etu.petci.Main.JOBS_DIR_NAME;
-import static ru.etu.petci.Main.SETTINGS_FILE_NAME;
public class Configurator {
- public RepositoryObserver readRepositoryConfig() {
+ public RepositoryObserver readRepositoryConfig() throws IOException {
RepositoryObserver observer = new RepositoryObserver();
- try {
- Properties repoConfig = new Properties();
- repoConfig.load(new FileReader("repository.properties"));
- if (!observer.setRepositoryPath(repoConfig.getProperty("repository_path"))) {
- System.exit(1);
- }
+ Properties repoConfig = new Properties();
+ try (var propertyReader = new FileReader("repository.properties")) {
+ repoConfig.load(propertyReader);
+ observer.setRepositoryPath(repoConfig.getProperty("repository_path"));
observer.setBranchName(repoConfig.getProperty("branch_name", "master"));
- observer.setLastHash(repoConfig.getProperty("last_hash", null));
- } catch (IOException e) {
- System.out.println("Error while reading repository config");
- System.exit(1);
+ observer.setLastHash(repoConfig.getProperty("last_hash"));
}
return observer;
}
- public void saveRepositoryConfig(String repoPath, String branchName, String lastHash) {
- try {
- var properties = new Properties();
- properties.setProperty("repository_path", Path.of(repoPath).toAbsolutePath().normalize().toString());
- properties.setProperty("branch_name", branchName);
- properties.setProperty("last_hash", lastHash.length() == 40 ? lastHash : "null");
- properties.store(new FileWriter("repository.properties"), "Repository configuration");
- } catch (IOException e) {
- throw new RuntimeException(e);
+ public void saveRepositoryConfig(String repoPath, String branchName, String lastHash) throws IOException {
+ var properties = new Properties();
+ properties.setProperty("repository_path", Path.of(repoPath).toAbsolutePath().normalize().toString());
+ properties.setProperty("branch_name", branchName);
+ properties.setProperty("last_hash", lastHash.length() == 40 ? lastHash : "null");
+ try (var propertyWriter = new FileWriter("repository.properties")) {
+ properties.store(propertyWriter, "Repository configuration");
}
}
- public void saveRepositoryConfig(String repoPath, String branchName) {
+ public void saveRepositoryConfig(String repoPath, String branchName) throws IOException {
saveRepositoryConfig(repoPath, branchName, "");
}
-
- /**
- *
This method performs the check whether the current folder
- * is an application folder. An application folder must consist
- * of a configuration file with name {@link}
- * and a directory with name {@link}.
- * If there is no application directory, then the method returned false,
- * user should use "init" command.
- */
- public boolean checkApplicationDir() {
- return Files.isDirectory(Path.of(JOBS_DIR_NAME)) && Files.isRegularFile(Path.of(SETTINGS_FILE_NAME));
+ public void saveJobConfig(Job job) {
+ Objects.requireNonNull(job);
+ try (var out = new BufferedWriter(new FileWriter(JOBS_DIR_NAME + File.separator + job.getName()))) {
+ out.append(job.getName());
+ out.newLine();
+ out.append(job.getScriptFile().toString());
+ out.newLine();
+ out.append(String.valueOf(job.isActive()));
+ } catch (IOException e) {
+ System.out.println("Error with writing jobFile");
+ System.exit(1);
+ }
}
}
diff --git a/src/main/java/ru/etu/petci/exceptions/RepositoryNotFoundException.java b/src/main/java/ru/etu/petci/exceptions/RepositoryNotFoundException.java
new file mode 100644
index 0000000..ac3e1ea
--- /dev/null
+++ b/src/main/java/ru/etu/petci/exceptions/RepositoryNotFoundException.java
@@ -0,0 +1,7 @@
+package ru.etu.petci.exceptions;
+
+public class RepositoryNotFoundException extends Exception {
+ public RepositoryNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/ru/etu/petci/handlers/CommandHandler.java b/src/main/java/ru/etu/petci/handlers/CommandHandler.java
index 72eeacf..73a4846 100644
--- a/src/main/java/ru/etu/petci/handlers/CommandHandler.java
+++ b/src/main/java/ru/etu/petci/handlers/CommandHandler.java
@@ -6,7 +6,7 @@ public interface CommandHandler {
/**
* This method should handle a certain command which is entered by user.
*
- * @param arg argument after name of the command. You should check if arg is null.
+ * @param arg argument after name of the command. Arg is NotNull.
* @return exit code for the program
*/
int handle(String arg);
diff --git a/src/main/java/ru/etu/petci/handlers/ContinueCommandHandler.java b/src/main/java/ru/etu/petci/handlers/ContinueCommandHandler.java
new file mode 100644
index 0000000..e6868ff
--- /dev/null
+++ b/src/main/java/ru/etu/petci/handlers/ContinueCommandHandler.java
@@ -0,0 +1,45 @@
+package ru.etu.petci.handlers;
+
+
+import ru.etu.petci.configuration.Configurator;
+import ru.etu.petci.exceptions.RepositoryNotFoundException;
+import ru.etu.petci.jobs.Job;
+import ru.etu.petci.jobs.JobsExecutor;
+import ru.etu.petci.observers.RepositoryObserver;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class ContinueCommandHandler implements CommandHandler {
+
+ private static final Logger LOGGER;
+
+ static {
+ LOGGER = Logger.getLogger(ContinueCommandHandler.class.getName());
+ LOGGER.setLevel(Level.WARNING);
+ }
+
+ @Override
+ public int handle(String arg) {
+ Objects.requireNonNull(arg);
+ var configurator = new Configurator();
+ try {
+ RepositoryObserver repositoryObserver = configurator.readRepositoryConfig();
+ List jobs = new ArrayList<>();
+ // TODO Reading jobs from properties
+ repositoryObserver.setExecutor(new JobsExecutor(jobs));
+ repositoryObserver.start();
+ } catch (InterruptedException e) {
+ LOGGER.log(Level.SEVERE, "The program was interrupted");
+ Thread.currentThread().interrupt();
+ } catch (IOException | RepositoryNotFoundException e) {
+ LOGGER.log(Level.SEVERE, e.getMessage());
+ return 1;
+ }
+ return 1;
+ }
+}
diff --git a/src/main/java/ru/etu/petci/handlers/InitCommandHandler.java b/src/main/java/ru/etu/petci/handlers/InitCommandHandler.java
index a3c06cd..02551a0 100644
--- a/src/main/java/ru/etu/petci/handlers/InitCommandHandler.java
+++ b/src/main/java/ru/etu/petci/handlers/InitCommandHandler.java
@@ -2,6 +2,7 @@
import ru.etu.petci.configuration.Configurator;
+import java.io.IOException;
import java.util.Objects;
import java.util.Scanner;
import java.util.logging.Level;
@@ -37,10 +38,15 @@ public int handle(String arg) {
// If branchName is empty, using master-branch
System.out.print("Name of observing branch (default - master): ");
var branchName = scanner.nextLine().strip();
- if (branchName.isEmpty()) {
- configurator.saveRepositoryConfig(repositoryPath, "master");
- } else {
- configurator.saveRepositoryConfig(repositoryPath, branchName);
+ try {
+ if (branchName.isEmpty()) {
+ configurator.saveRepositoryConfig(repositoryPath, "master");
+ } else {
+ configurator.saveRepositoryConfig(repositoryPath, branchName);
+ }
+ } catch (IOException e) {
+ LOGGER.severe(e.getMessage());
+ return 1;
}
scanner.close();
System.out.println("Successful initialization!");
diff --git a/src/main/java/ru/etu/petci/jobs/Job.java b/src/main/java/ru/etu/petci/jobs/Job.java
new file mode 100644
index 0000000..d892881
--- /dev/null
+++ b/src/main/java/ru/etu/petci/jobs/Job.java
@@ -0,0 +1,68 @@
+package ru.etu.petci.jobs;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Path;
+import java.util.Objects;
+
+public class Job {
+ private boolean isActive = true;
+ private String name;
+ private final Path scriptFile;
+
+ public Job(Path scriptFile, String name) {
+ this.scriptFile = scriptFile.toAbsolutePath().normalize();
+ this.name = name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Path getScriptFile() {
+ return scriptFile;
+ }
+
+
+ public void setActive(boolean active) {
+ isActive = active;
+ }
+
+ public boolean isActive() {
+ return isActive;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Job job)) return false;
+ return Objects.equals(name, job.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name);
+ }
+
+
+ public int execute() throws IOException {
+ Process scriptProcess = Runtime.getRuntime().exec(scriptFile.toString());
+ try {
+ var input = new BufferedReader(new InputStreamReader(scriptProcess.getInputStream()));
+ String line;
+ while ((line = input.readLine()) != null) {
+ System.out.println(line);
+ }
+ scriptProcess.waitFor();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ return scriptProcess.exitValue();
+ }
+}
diff --git a/src/main/java/ru/etu/petci/jobs/JobsExecutor.java b/src/main/java/ru/etu/petci/jobs/JobsExecutor.java
new file mode 100644
index 0000000..7c5d6a0
--- /dev/null
+++ b/src/main/java/ru/etu/petci/jobs/JobsExecutor.java
@@ -0,0 +1,39 @@
+package ru.etu.petci.jobs;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class JobsExecutor {
+
+ private final List jobs;
+ private static final Logger LOGGER = Logger.getLogger(JobsExecutor.class.getName());
+
+ static {
+ LOGGER.setLevel(Level.WARNING);
+ }
+
+ public JobsExecutor(List jobs) {
+ this.jobs = jobs;
+ }
+
+ public void runJobs() throws IOException {
+ Objects.requireNonNull(jobs);
+ for (Job job : jobs) {
+ System.out.println(job.getScriptFile().toAbsolutePath());
+ System.out.printf("Run job \"%s\"...%n%n", job.getName());
+ if (!job.isActive()) {
+ System.out.println(": Deactivated");
+ continue;
+ }
+ if (job.execute() == 0) {
+ System.out.printf("%n--Succeed--%n");
+ } else {
+ System.out.printf("%n--Failed--%n");
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/ru/etu/petci/observers/RepositoryObserver.java b/src/main/java/ru/etu/petci/observers/RepositoryObserver.java
index 6b7f2b3..488915a 100644
--- a/src/main/java/ru/etu/petci/observers/RepositoryObserver.java
+++ b/src/main/java/ru/etu/petci/observers/RepositoryObserver.java
@@ -1,10 +1,11 @@
package ru.etu.petci.observers;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
+import ru.etu.petci.exceptions.RepositoryNotFoundException;
+import ru.etu.petci.jobs.JobsExecutor;
+
+import java.io.*;
import java.nio.file.Path;
+import java.util.Objects;
import java.util.Properties;
import java.util.Scanner;
import java.util.concurrent.Executors;
@@ -15,9 +16,11 @@
public class RepositoryObserver {
+ public static final String REPOSITORY_PROPERTIES = "repository.properties";
private Path repositoryPath;
- private String lastHash; // Hash of last commit
- private String branchName; // Name of the observed branch
+ private String lastHash; // Hash of last commit
+ private String branchName; // Name of the observed branch
+ private JobsExecutor executor;
private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
private static final Logger LOGGER = Logger.getLogger(RepositoryObserver.class.getName());
@@ -25,21 +28,17 @@ public class RepositoryObserver {
LOGGER.setLevel(Level.INFO);
}
- public boolean setRepositoryPath(Path path) {
- boolean isSet = false;
- path = path.toAbsolutePath().normalize();
+ public boolean isRepositoryExists() throws InterruptedException {
+ if (Objects.isNull(repositoryPath)) {
+ return false;
+ }
Process gitProcess = null;
-
+ int exitStatus = -1;
try {
- gitProcess = Runtime.getRuntime().exec("git ls-remote %s".formatted(path));
- if (gitProcess.exitValue() == 0) {
- repositoryPath = path;
- isSet = true;
- } else {
- LOGGER.log(Level.WARNING, "Unable to find repository by path: {0}", repositoryPath);
- System.out.println("Unable to find repository by path");
- }
+ gitProcess = Runtime.getRuntime().exec("git ls-remote %s".formatted(repositoryPath));
+ gitProcess.waitFor();
+ exitStatus = gitProcess.exitValue();
} catch (IOException e) {
LOGGER.warning("Error while executing 'git ls-remote'.%n" + e.getMessage());
} finally {
@@ -47,7 +46,14 @@ public boolean setRepositoryPath(Path path) {
gitProcess.destroy();
}
}
- return isSet;
+ return exitStatus == 0;
+ }
+
+
+ public void setRepositoryPath(Path path) {
+ if (Objects.isNull(path))
+ return;
+ repositoryPath = path.toAbsolutePath().normalize();
}
@@ -63,8 +69,10 @@ public String getBranchName() {
return branchName;
}
- public boolean setRepositoryPath(String path) {
- return setRepositoryPath(Path.of(path));
+ public void setRepositoryPath(String path) {
+ if (Objects.isNull(path))
+ return;
+ setRepositoryPath(Path.of(path));
}
public Path getRepositoryPath() {
@@ -78,37 +86,51 @@ private void checkRepositoryUpdate() {
String currentHash = scanner.nextLine();
if (currentHash.length() == 40 && !currentHash.equals(lastHash)) {
lastHash = currentHash;
- try {
- Properties properties = new Properties();
- properties.load(new FileReader("repository.properties"));
+
+
+ // Save new hash to properties
+ Properties properties = new Properties();
+ try (var propertyReader = new FileReader(REPOSITORY_PROPERTIES);
+ var propertyWriter = new FileWriter(REPOSITORY_PROPERTIES)) {
+ properties.load(propertyReader);
properties.setProperty("last_hash", lastHash);
- properties.store(new FileWriter("repository.properties"), "repository settings");
- } catch (IOException e) {
- LOGGER.log(Level.WARNING, "Error while working with repository properties");
+ properties.store(propertyWriter, "repository settings");
}
+
LOGGER.log(Level.INFO, "Commits checked. New commit was found. Hash: {0}", lastHash);
+ executor.runJobs();
} else {
LOGGER.info("Commits checked. No new commits found.");
}
} catch (FileNotFoundException e) {
- LOGGER.warning(e.getMessage());
- System.out.printf("Branch \"%s\" does not exist!%n", getBranchName());
+ LOGGER.severe(e.getMessage());
+ System.out.printf("Unable to find branch \"%s\"%n", getBranchName());
+ service.shutdown();
+ System.exit(1);
+ } catch (IOException e) {
+ LOGGER.severe(e.getMessage());
service.shutdown();
System.exit(1);
}
}
- public void start() throws InterruptedException {
- // Check for a new commit per 3 seconds
- if (repositoryPath != null) {
+ public void start() throws InterruptedException, RepositoryNotFoundException {
+ if (isRepositoryExists()) {
+ // Check for a new commit per 3 seconds
service.scheduleWithFixedDelay(this::checkRepositoryUpdate, 0, 3, TimeUnit.SECONDS);
Thread.currentThread().join();
+ } else {
+ throw new RepositoryNotFoundException("Unable to find git repository by path: %s".formatted(repositoryPath));
}
}
public void setLastHash(String lastHash) {
- if (lastHash.length() == 40) {
+ if (Objects.nonNull(lastHash) && lastHash.length() == 40) {
this.lastHash = lastHash;
}
}
+
+ public void setExecutor(JobsExecutor executor) {
+ this.executor = executor;
+ }
}