Skip to content
Snippets Groups Projects
Commit 3559c90c authored by Maxime Lefrançois's avatar Maxime Lefrançois
Browse files

starting integration

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1250 additions and 0 deletions
/target/
dependency-reduced-pom.xml
.project
.classpath
.settings
\ No newline at end of file
image: maven:3.6.2-jdk-8
build:
stage: build
script:
- mvn package
artifacts:
paths:
- target/sarefPipeline.jar
only:
- master
# Description
This project integrates the SAREF development and documentation generation pipeline
pom.xml 0 → 100644
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.emse.gitlab.saref</groupId>
<artifactId>saref-pipeline</artifactId>
<version>1.0-SNAPSHOT</version>
<name>saref-pipeline</name>
<developers>
<developer>
<name>Omar Qawasmeh</name>
<email>omar.alqawasmeh@emse.fr</email>
<url>https://perso.univ-st-etienne.fr/alo09685/</url>
<organization>Ecole des mines de Saint-Etienne</organization>
<organizationUrl>http://www.mines-stetienne.fr/</organizationUrl>
<timezone>+1</timezone>
</developer>
<developer>
<name>Maxime Lefrançois</name>
<email>maxime.lefrancois@emse.fr</email>
<url>http://www.maxime-lefrancois.info/</url>
<organization>Ecole des mines de Saint-Etienne</organization>
<organizationUrl>http://www.mines-stetienne.fr/</organizationUrl>
<timezone>+1</timezone>
</developer>
</developers>
<organization>
<name>École des Mines de Saint-Étienne</name>
<url>http://www.mines-stetienne.fr/</url>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ssZ</maven.build.timestamp.format>
<jdk.version>1.8</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<sparql-generate.version>2.0-SNAPSHOT</sparql-generate.version>
</properties>
<dependencies>
<!-- <dependency> -->
<!-- <groupId>org.topbraid</groupId> -->
<!-- <artifactId>shacl</artifactId> -->
<!-- <version>1.3.1</version> -->
<!-- </dependency> -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-tdb</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>fr.emse.ci</groupId>
<artifactId>sparql-generate-jena</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>fr.emse.ci</groupId>
<artifactId>sparql-generate-markdown</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- see Porcelain https://git-scm.com/book/uz/v2/Appendix-B%3A-Embedding-Git-in-your-Applications-JGit -->
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.2.1.201812262042-r</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>fr.emse.gitlab.saref.Main
</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package fr.emse.gitlab.saref;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Layout;
import org.apache.log4j.PatternLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.emse.gitlab.saref.entities.TestSuites;
import fr.emse.gitlab.saref.jobs.JobRunner;
import fr.emse.gitlab.saref.jobs.library.ReadOntologies;
import fr.emse.gitlab.saref.jobs.library.RepositoryStructureChecker;
import fr.emse.gitlab.saref.utils.SAREF;
public class Main {
static final Logger LOG = LoggerFactory.getLogger(Main.class);
private static final Layout LAYOUT = new PatternLayout("%d{mm:ss,SSS} %t %-5p %c:%L - %m%n");
private static final org.apache.log4j.Logger ROOT_LOGGER = org.apache.log4j.Logger.getRootLogger();
private static TestSuites testSuites = new TestSuites();
private static File directory;
private static File target;
public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException, JAXBException {
if (args.length == 0) {
directory = new File("").getAbsoluteFile();
} else if (args.length > 1) {
throw new IllegalArgumentException(
"Expecting at most one argument: the location of the SAREF directory where to run the pipeline");
} else {
directory = new File(args[0]).getAbsoluteFile();
}
target = new File(directory, "target");
FileUtils.forceDelete(target);
FileUtils.forceMkdir(target);
File logFile = new File(directory, "target/output.log");
ROOT_LOGGER.addAppender(new org.apache.log4j.RollingFileAppender(LAYOUT, logFile.getAbsolutePath(), false));
LOG.info("Starting pipeline");
JobRunner checker = new RepositoryStructureChecker(directory);
checker.doJob(testSuites);
if(testSuites.getErrors() > 0) {
reportAndExit(-1);
}
checker = new ReadOntologies(directory);
checker.doJob(testSuites);
reportAndExit(0);
}
private static void reportAndExit(int code) {
try {
File report = new File(target, "report_output.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(TestSuites.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
jaxbMarshaller.marshal(testSuites, report);
jaxbMarshaller.marshal(testSuites, System.out);
final StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(testSuites, sw);
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(new URI(SAREF.BASE + "report.html?report=" + URLEncoder.encode(sw.toString(), "UTF-8")));
}
} catch(JAXBException | URISyntaxException | IOException ex) {
LOG.error("Exception:", ex);
ex.printStackTrace();
}
System.exit(code);
}
// private static void testRead() {
// try {
// JAXBContext jaxbContext = JAXBContext.newInstance(TestSuite.class);
// Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
//
// TestCase testCase = (TestCase) jaxbUnmarshaller.unmarshal(target);
//
// } catch (JAXBException e) {
// e.printStackTrace();
// }
// }
}
/*
* Copyright 2020 École des Mines de Saint-Étienne.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.emse.gitlab.saref.entities;
import org.eclipse.jgit.lib.PersonIdent;
/**
*
* @author maxime.lefrancois
*/
public class Contributor {
private final String name;
private final String emailAddress;
public Contributor(PersonIdent person) {
name = person.getName();
emailAddress = person.getEmailAddress();
}
public Contributor(String aName, String aEmailAddress) {
name = aName;
emailAddress = aEmailAddress;
}
/**
* Get name of person
*
* @return Name of person
*/
public String getName() {
return name;
}
/**
* Get email address of person
*
* @return email address of person
*/
public String getEmailAddress() {
return emailAddress;
}
/**
* {@inheritDoc}
* <p>
* Hashcode is based only on the email address.
*/
@Override
public int hashCode() {
return getEmailAddress().hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object o) {
if (o instanceof Contributor) {
final Contributor p = (Contributor) o;
return getName().equals(p.getName())
&& getEmailAddress().equals(p.getEmailAddress());
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
final StringBuilder r = new StringBuilder();
r.append("Contributor[");
r.append(getName());
r.append(", ");
r.append(getEmailAddress());
r.append("]");
return r.toString();
}
}
/*
* Copyright 2020 École des Mines de Saint-Étienne.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.emse.gitlab.saref.entities;
import java.util.List;
/**
*
* @author maxime.lefrancois
*/
public class Group {
public List<Project> projects;
}
/*
* Copyright 2020 École des Mines de Saint-Étienne.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.emse.gitlab.saref.entities;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.jena.rdf.model.Resource;
/**
*
* @author maxime.lefrancois
*/
public class Project {
public String name;
public String http_url_to_repo;
public transient File directory;
public transient List<Version> releases = new ArrayList<>();
public transient String namespace;
public transient String prefix;
public transient Resource resource;
}
/**
*
*/
package fr.emse.gitlab.saref.entities;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author Omar Qawasmeh
*
*
*/
@XmlRootElement
public class Property {
}
/*
* Copyright 2020 École des Mines de Saint-Étienne.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.emse.gitlab.saref.entities;
/**
*
* @author maxime.lefrancois
*/
public class Term {
private final String id;
private final String localName;
public Term(String id, String localName) {
this.id = id;
this.localName = localName;
}
public String getId() {
return id;
}
public String getLocalName() {
return localName;
}
/**
* {@inheritDoc}
* <p>
* Hashcode is based only on the id.
*/
@Override
public int hashCode() {
return getLocalName().hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object o) {
if (o instanceof Contributor) {
final Term p = (Term) o;
return getId().equals(p.getId())
&& getLocalName().equals(p.getLocalName());
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
final StringBuilder r = new StringBuilder();
r.append("Term[");
r.append(getId());
r.append(", ");
r.append(getLocalName());
r.append("]");
return r.toString();
}
}
/**
*
*/
package fr.emse.gitlab.saref.entities;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
/**
* @author Omar Qawasmeh
*
*
*/
@XmlRootElement(name = "testcase")
@XmlType(propOrder = { "name", "status", "error", "failure", "systemErr", "systemOut" })
public class TestCase {
@XmlAttribute
private String name = "";
@XmlTransient
private String status = "success";
@XmlElement
private Error error;
@XmlElement
private Error failure;
@XmlTransient
private String systemErr;
@XmlTransient
private String systemOut;
public TestCase() {
}
public TestCase(final String name) {
this.name = name;
}
public String getName() {
return name;
}
@XmlAttribute
public String getStatus() {
return status;
}
@XmlElement(name = "system-err")
public String getSystemErr() {
return systemErr;
}
public void setSystemErr(String systemErr) {
this.systemErr = systemErr;
}
@XmlElement(name = "system-out")
public String getSystemOut() {
return systemOut;
}
public void setSystemOut(String systemOut) {
this.systemOut = systemOut;
}
public void setStatus(Status status) {
this.status = status.getName();
}
public void setError(String type, String message) {
this.error = new Error(type, message);
this.status = "error";
}
public boolean isError() {
return status.equals(Status.ERROR.getName());
}
public void setFailure(String type, String message) {
this.failure = new Error(type, message);
this.status = "failure";
}
public boolean isFailure() {
return status.equals(Status.FAILURE.getName());
}
public String getErrorType() {
if (error != null) {
return error.getType();
}
return null;
}
public String getErrorMessage() {
if (error != null) {
return error.getMessage();
}
return null;
}
public String getFailureType() {
if (failure != null) {
return failure.getType();
}
return null;
}
public String getFailureMessage() {
if (failure != null) {
return failure.getMessage();
}
return null;
}
@XmlRootElement(name = "error")
private static class Error implements Serializable {
@XmlAttribute
private String type;
@XmlAttribute
private String message;
public Error() {
}
private Error(String type, String message) {
this.type = type;
this.message = message;
}
public String getType() {
return type;
}
public String getMessage() {
return message;
}
}
public static enum Status {
SUCCESS, FAILURE, ERROR, WARNING;
public String getName() {
return toString().toLowerCase();
}
}
}
/**
*
*/
package fr.emse.gitlab.saref.entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* @author Omar Qawasmeh
*
*
*/
@XmlRootElement(name = "testsuite")
@XmlType(propOrder = { "name", "tests", "failures", "errors", "testCases" })
public class TestSuite implements Serializable {
@XmlAttribute
private String name = "";
@XmlAttribute
private int tests = 0;
@XmlAttribute
private int failures = 0;
@XmlAttribute
private int errors = 0;
@XmlElement(name = "testcase")
private List<TestCase> testCases = new ArrayList<>();
public TestSuite() {}
public TestSuite(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getTests() {
return tests;
}
public int getFailures() {
return failures;
}
public int getErrors() {
return errors;
}
public void addTestcase(TestCase testCase) {
testCases.add(testCase);
tests++;
if(testCase.isFailure()) {
failures++;
}
if(testCase.isError()) {
errors++;
}
}
public List<TestCase> getTestCases() {
return testCases;
}
}
\ No newline at end of file
/**
*
*/
package fr.emse.gitlab.saref.entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* @author Omar Qawasmeh
*
*
*/
@XmlRootElement(name = "testsuites")
@XmlType(propOrder = { "name", "tests", "failures", "errors", "testSuites" })
public class TestSuites implements Serializable {
@XmlAttribute
private String name = "";
@XmlAttribute
private int tests = 0;
@XmlAttribute
private int failures = 0;
@XmlAttribute
private int errors = 0;
@XmlElement(name = "testsuite")
private List<TestSuite> testSuites = new ArrayList<>();
public TestSuites() {}
public TestSuites(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getFailures() {
return failures;
}
public int getErrors() {
return errors;
}
public void addTestsuite(TestSuite testSuite) {
testSuites.add(testSuite);
tests+=testSuite.getTests();
failures+=testSuite.getFailures();
errors+=testSuite.getErrors();
}
public List<TestSuite> getTestSuites() {
return testSuites;
}
}
\ No newline at end of file
/*
* Copyright 2020 École des Mines de Saint-Étienne.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.emse.gitlab.saref.entities;
import java.util.Date;
import java.util.Set;
import org.apache.jena.rdf.model.Resource;
import org.eclipse.jgit.lib.Ref;
/**
*
* @author maxime.lefrancois
*/
public class Version {
public int major;
public int minor;
public int patch;
public Ref ref;
public String uri;
public String prefix;
public Date issued;
public transient Resource resource;
@Override
public String toString() {
return String.format("v%s.%s.%s", major, minor, patch);
}
}
package fr.emse.gitlab.saref.jobs;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import fr.emse.gitlab.saref.entities.TestCase;
import fr.emse.gitlab.saref.entities.TestCase.Status;
import fr.emse.gitlab.saref.entities.TestSuite;
import fr.emse.gitlab.saref.entities.TestSuites;
public abstract class AbstractJobRunner implements JobRunner {
private final TestSuite testSuite = new TestSuite();
protected final File directory;
public AbstractJobRunner(File dir) {
this.directory = dir;
}
public final void doJob(TestSuites testSuites) {
doJob0();
testSuites.addTestsuite(testSuite);
}
protected abstract void doJob0();
protected void error(String name, Exception ex) {
TestCase tc = new TestCase(name);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
tc.setSystemErr(sw.toString());
tc.setError(ex.getClass().getCanonicalName(), ex.getMessage());
testSuite.addTestcase(tc);
}
protected void error(String name) {
TestCase tc = new TestCase(name);
tc.setStatus(Status.ERROR);
testSuite.addTestcase(tc);
}
protected void warning(String name) {
TestCase tc = new TestCase(name);
tc.setStatus(Status.WARNING);
testSuite.addTestcase(tc);
}
protected void failure(String name) {
TestCase tc = new TestCase(name);
tc.setStatus(Status.FAILURE);
testSuite.addTestcase(tc);
}
protected void failure(String name, String type, String message) {
TestCase tc = new TestCase(name);
tc.setFailure(type, message);
testSuite.addTestcase(tc);
}
protected void success(String name) {
testSuite.addTestcase(new TestCase(name));
}
}
package fr.emse.gitlab.saref.jobs;
import fr.emse.gitlab.saref.entities.TestSuites;
public interface JobRunner {
void doJob(TestSuites testSuites);
}
This diff is collapsed.
package fr.emse.gitlab.saref.jobs.library;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.Lang;
import fr.emse.gitlab.saref.jobs.AbstractJobRunner;
public class ReadOntologies extends AbstractJobRunner {
public ReadOntologies(File dir) {
super(dir);
}
@Override
protected void doJob0() {
String repoName = getRepoName();
String ontologyName = repoName.equals("saref-core") ? "saref.ttl" : repoName + ".ttl";
checkOntology(ontologyName);
checkExamples();
}
private void checkOntology(String ontologyName) {
File ontologyFile = new File(directory, "ontology/" + ontologyName);
Model model = ModelFactory.createDefaultModel();
try(FileInputStream input = new FileInputStream(ontologyFile)) {
model.read(input, null, Lang.TTL.getLabel());
} catch ( Exception ex) {
error("Exception while reading the ontology file", ex);
}
}
private void checkExamples() {
File dir = new File(directory, "examples");
try {
Files.walk(dir.toPath()).filter(p -> {
return p.endsWith(".ttl");
}).forEach(p->{
File exampleFile = p.toFile();
Model model = ModelFactory.createDefaultModel();
try(FileInputStream input = new FileInputStream(exampleFile)) {
model.read(input, null, Lang.TTL.getLabel());
} catch ( Exception ex) {
failure(String.format("Exception while reading the example file %s", exampleFile.toString()), ex.getClass().getSimpleName(), ex.getMessage());
}
});
} catch(IOException ex) {
error("Exception while walking the example directory", ex);
}
}
private String getRepoName() {
String REGEX = "^(?<ext>saref-core|saref4[a-z][a-z][a-z][a-z])";
String name = directory.getName();
Pattern pattern = Pattern.compile(REGEX);
Matcher matcher = pattern.matcher(name);
if (!matcher.find()) {
error(String.format(
"The SAREF pipeline must be run inside a directory whose name begins with `saref-core`, or `saref4abcd` (where abcd can be any sequence of four letters). Got: %s",
name));
return null;
}
return matcher.group("ext");
}
}
package fr.emse.gitlab.saref.jobs.library;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import fr.emse.gitlab.saref.jobs.AbstractJobRunner;
public class RepositoryStructureChecker extends AbstractJobRunner {
static Logger logger = Logger.getLogger("MaintenanceReport");
private final Set<String> gitignoreLines = new HashSet<>(
Arrays.asList("target", "*~", ".DS_Store", "catalog-v001.xml"));
private final String NAME = "Check the structure of the repository";
public RepositoryStructureChecker(File dir) {
super(dir);
}
public void doJob0() {
try {
if (!directory.isDirectory()) {
error("The SAREF pipeline must be run inside a directory");
}
} catch (SecurityException ex) {
error("Security error while running the SAREF pipeline", ex);
}
checkThereExistsDirectory("diagrams");
checkThereExistsDirectory("ontology");
String repoName = checkRepoName();
if (repoName == null) {
return;
}
String ontologyFile = repoName.equals("saref-core") ? "saref.ttl" : repoName + ".ttl";
checkOntoloyFolder(ontologyFile);
checkGitIgnoreFolder();
checkLICENSE();
checkExamplesFolder();
}
private void checkThereExistsDirectory(String dirName) {
final File dir = new File(directory, dirName);
try {
if (dir.isDirectory()) {
success(String.format("There exists a folder named `%s`", dirName));
} else {
failure(String.format("There should exist a folder named `%s`", dirName));
}
} catch (SecurityException ex) {
error(String.format("Error while checking if there exists a folder named `%s`", dirName), ex);
}
}
private String checkRepoName() {
String REGEX = "^(?<ext>saref-core|saref4[a-z][a-z][a-z][a-z])";
String name = directory.getName();
Pattern pattern = Pattern.compile(REGEX);
Matcher matcher = pattern.matcher(name);
if (!matcher.find()) {
error(String.format(
"The SAREF pipeline must be run inside a directory whose name begins with `saref-core`, or `saref4abcd` (where abcd can be any sequence of four letters). Got: %s",
name));
return null;
}
return matcher.group("ext");
}
private void checkOntoloyFolder(String ontoName) {
final File ontoDir = new File(directory, "ontology");
final File ontoFile = new File(ontoDir, ontoName);
if (!ontoFile.isFile()) {
error(String.format("The ontology folder must contain an ontology file named `%s`", ontoName));
return;
}
}
private void checkGitIgnoreFolder() {
final File gitignore = new File(directory, ".gitignore");
if (!gitignore.exists()) {
failure("The directory must contain a file named `.gitignore`");
}
try (BufferedReader br = Files.newBufferedReader(gitignore.toPath())) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
gitignoreLines.remove(line);
}
if (!gitignoreLines.isEmpty()) {
failure(String.format("The file `.gitignore` lacks one line for each of the following strings: %s",
gitignoreLines.toString()));
}
} catch (IOException ex) {
error("Error while checking if the file `.gitignore` has the appropriate lines", ex);
}
}
private void checkLICENSE() {
final File licenseFile = new File(directory, "LICENSE");
if (!licenseFile.exists()) {
failure("The directory must contain a file named `LICENSE`");
return;
}
File licenseModelFile = new File(
RepositoryStructureChecker.class.getClassLoader().getResource("LICENSE_MODEL").getFile());
try (BufferedReader licenseModelFileReader = new BufferedReader(new FileReader(licenseModelFile));
BufferedReader licenseFileReader = new BufferedReader(new FileReader(licenseFile));) {
// first line
String modelLine = licenseModelFileReader.readLine();
String licenseLine = licenseFileReader.readLine();
String regex = modelLine.replaceFirst("YYYY", "(?<year>\\\\d{4})");
Pattern pattern = Pattern.compile(String.format("^%s$", regex));
Matcher regexMatcher = pattern.matcher(licenseLine);
if (!regexMatcher.find()) {
failure("First line of the `LICENSE` file must match the following string (see details below)",
"First line of the `LICENSE` file must match the following string, where YYYY is a year. Got: "
+ licenseLine,
modelLine);
return;
}
int year = Integer.parseInt(regexMatcher.group("year"));
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
if (year < 2015 || year > currentYear) {
failure(String.format("The year in the `LICENSE` should be between %s and %s", 2015, currentYear));
return;
}
int i = 1;
modelLine = licenseModelFileReader.readLine();
licenseLine = licenseFileReader.readLine();
while (modelLine != null && licenseLine != null) {
i++;
if (!modelLine.equals(licenseLine)) {
failure(String.format("Line %s in the `LICENSE` should be `%s`", i, modelLine));
return;
}
modelLine = licenseModelFileReader.readLine();
licenseLine = licenseFileReader.readLine();
}
if(modelLine == null && licenseLine != null) {
failure(String.format("The license contains too many lines. Need %s", i));
return;
}
if(modelLine != null && licenseLine == null) {
failure(String.format("The license is incomplete.", i));
return;
}
} catch (Exception ex) {
error("Exception while creating the path for the LICENSE model", ex);
return;
}
}
private void checkExamplesFolder() {
final File dir = new File(directory, "examples");
try {
if (!dir.isDirectory()) {
failure("There should exist a folder named `examples`");
return;
}
} catch (SecurityException ex) {
error("Error while checking if there exists a folder named `examples`", ex);
return;
}
try {
boolean containsExample = Files.walk(dir.toPath()).anyMatch(p -> {
return p.endsWith(".ttl");
});
if (!containsExample) {
failure("The `examples` folder should contain at least one example file (some `.ttl` document");
}
} catch (IOException ex) {
error("Exception while browsing the `examples` folder", ex);
}
}
}
///**
// *
// */
//package fr.emse.gitlab.saref.tests;
//
//import org.apache.commons.cli.CommandLine;
//import org.apache.commons.cli.DefaultParser;
//import org.apache.commons.cli.HelpFormatter;
//import org.apache.commons.cli.Options;
//import org.apache.commons.cli.ParseException;
//
///**
// * @author Omar Qawasmeh
// *
// *
// */
//public class CMDConfigurations {
//
// public static final String ARG_HELP = "h";
// public static final String ARG_HELP_LONG = "help";
// public static final String ARG_HELP_MAN = "Show help";
// public static final String ARG_DIRECTORY = "d";
// public static final String ARG_DIRECTORY_LONG = "dir";
// public static final String ARG_DIRECTORY_MAN = "Location of the directory with Turtle documents";
// public static final String ARG_FILE = "f";
// public static final String ARG_FILE_LONG = "file";
// public static final String ARG_FILE_MAN = "Location of a Turtle document";
// public static final String ARG_OUTPUT = "o";
// public static final String ARG_OUTPUT_LONG = "output";
// public static final String ARG_OUTPUT_MAN = "Location where the output is to be stored.";
//
// public static CommandLine parseArguments(String[] args) throws ParseException {
// DefaultParser commandLineParser = new DefaultParser();
// CommandLine cl = commandLineParser.parse(getCMDOptions(), args);
// return cl;
// }
//
// public static Options getCMDOptions() {
// return new Options().addOption(ARG_HELP, ARG_HELP_LONG, false, ARG_HELP_MAN)
// .addOption(ARG_DIRECTORY, ARG_DIRECTORY_LONG, true, ARG_DIRECTORY_MAN)
// .addOption(ARG_FILE, ARG_FILE_LONG, true, ARG_FILE_MAN)
// .addOption(ARG_OUTPUT, ARG_OUTPUT_LONG, true, ARG_OUTPUT_MAN);
// }
//
// public static void displayHelp() {
// HelpFormatter formatter = new HelpFormatter();
// formatter.printHelp("Check Turtle", getCMDOptions());
// System.exit(-1);
// }
//
//}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment