Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .agents/skills/openfasttrace/SKILL.md
Comment thread
kaklakariada marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
name: openfasttrace
description: Work with OpenFastTrace requirement tracing, including specification items, artifact IDs, coverage markers, Markdown and Gherkin syntax, and trace validation. Use when Codex needs to create, edit, review, or validate OpenFastTrace-traced requirements, design, implementation, tests, or documentation.
Comment thread
kaklakariada marked this conversation as resolved.
---

# OpenFastTrace (OFT) Skill

OpenFastTrace is a tool for requirement tracing across various artifacts (specifications, code, tests).
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
- name: Publish to Maven Central Repository
if: ${{ !inputs.skip-deploy-maven-central }}
run: |
mvn --batch-mode deploy -PcentralPublishing \
mvn --batch-mode deploy -Dossindex.skip=true -PcentralPublishing \
Comment thread
kaklakariada marked this conversation as resolved.
-DcentralPublishingSkipPublishing=false \
-DcentralPublishingAutoPublish=${{ inputs.maven-central-auto-publish }} \
-DcentralPublishingDeploymentName="Auto-deploy OpenFastTrace via release.yml"
Expand Down
2 changes: 1 addition & 1 deletion api/.settings/org.eclipse.jdt.core.prefs
Comment thread
kaklakariada marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.processAnnotations=disabled
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
* Specification items with links that can be followed.
*/
// [impl->dsn~linked-specification-item~1]
@SuppressWarnings("java:S1448") // This is a facade class. Reducing methods hurts expressiveness.
@SuppressWarnings("java:S1448") // This is a facade class. Reducing methods
Comment thread
kaklakariada marked this conversation as resolved.
Outdated
// hurts expressiveness.
public class LinkedSpecificationItem
{
private final SpecificationItem item;
Expand Down Expand Up @@ -161,7 +162,7 @@ private void addMyItemIdToCoveringItem(final LinkedSpecificationItem coveringIte
if (coveringItem.getItem().getCoveredIds() != null
&& !coveringItem.getItem().getCoveredIds().contains(getId()))
{
coveringItem.getItem().getCoveredIds().add(getId());
coveringItem.getItem().addCoveredId(getId());
Comment thread
kaklakariada marked this conversation as resolved.
}
}

Expand Down Expand Up @@ -312,7 +313,7 @@ public boolean isCoveredShallow()

/**
* Check if all needed attribute types are covered by approved items.
*
*
* @return {@code true} if all needed attribute types are covered by
* approved items
*/
Expand Down Expand Up @@ -356,6 +357,7 @@ List<LinkedSpecificationItem> getIncomingItems()
* <p>
* An item counts as a defect if the following applies:
* </p>
*
* <pre>
* has duplicates
* or (not rejected
Expand Down Expand Up @@ -393,7 +395,7 @@ public boolean isTransitiveDefect()

/**
* Check if the item has one or more links.
*
*
* @return {@code true} if the item has one or more links
*/
public boolean hasLinks()
Expand Down Expand Up @@ -492,7 +494,7 @@ public int countDuplicateLinks()

/**
* Check if this item has one ore more duplicates.
*
*
* @return {@code true} if this item has one ore more duplicates.
*/
public boolean hasDuplicates()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package org.itsallcode.openfasttrace.api.core;

import java.util.Objects;
import java.util.Optional;

/**
* One occurrence of a specification item ID in an imported source artifact.
* Component ranges are absent when the corresponding ID component was generated
* by an importer instead of being present in the source.
Comment thread
kaklakariada marked this conversation as resolved.
Outdated
*/
public final class LocatedSpecificationItemId
{
private final SpecificationItemId id;
private final SourceRange range;
private final SourceRange artifactTypeRange;
private final SourceRange nameRange;
private final SourceRange revisionRange;

private LocatedSpecificationItemId(final Builder builder)
{
this.id = Objects.requireNonNull(builder.id, "id");
Comment thread
kaklakariada marked this conversation as resolved.
Outdated
this.range = builder.range;
this.artifactTypeRange = builder.artifactTypeRange;
this.nameRange = builder.nameRange;
this.revisionRange = builder.revisionRange;
}

/**
* Create a new builder for {@link LocatedSpecificationItemId}.
*
* @return a new builder instance for {@link LocatedSpecificationItemId}.
*/
public static Builder builder()
{
return new Builder();
}

/**
* Get the semantic ID of this located specification item.
*
* @return the semantic ID
*/
public SpecificationItemId getId()
{
return this.id;
}

/**
* Get the source range of the complete source construct.
*
* @return range of the complete source construct
*/
public SourceRange getRange()
{
return this.range;
}

/**
* Get the source range of the artifact type, if represented in source.
*
* @return source range of the artifact type, if represented in source
*/
public Optional<SourceRange> getArtifactTypeRange()
{
return Optional.ofNullable(this.artifactTypeRange);
}

/**
* Get the source range of the name, if represented in source.
*
* @return source range of the name, if represented in source
*/
public Optional<SourceRange> getNameRange()
{
return Optional.ofNullable(this.nameRange);
}

/**
* Get the source range of the revision, if represented in source.
*
* @return source range of the revision, if represented in source
*/
public Optional<SourceRange> getRevisionRange()
{
return Optional.ofNullable(this.revisionRange);
}

@Override
public boolean equals(final Object other)
{
if (!(other instanceof final LocatedSpecificationItemId that))
{
return false;
}
return Objects.equals(this.id, that.id) && Objects.equals(this.range, that.range)
&& Objects.equals(this.artifactTypeRange, that.artifactTypeRange)
&& Objects.equals(this.nameRange, that.nameRange)
&& Objects.equals(this.revisionRange, that.revisionRange);
}

@Override
public int hashCode()
{
return Objects.hash(this.id, this.range, this.artifactTypeRange, this.nameRange, this.revisionRange);
}

/**
* Builder for {@link LocatedSpecificationItemId}.
*/
public static class Builder

Check warning on line 110 in api/src/main/java/org/itsallcode/openfasttrace/api/core/LocatedSpecificationItemId.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make this class "final" or add a public constructor.

See more on https://sonarcloud.io/project/issues?id=org.itsallcode.openfasttrace%3Aopenfasttrace-root&issues=AZ_W3Wed4sL5MAk9c0pl&open=AZ_W3Wed4sL5MAk9c0pl&pullRequest=571
Comment thread
kaklakariada marked this conversation as resolved.
Outdated
{
private SpecificationItemId id;
private SourceRange range;
private SourceRange artifactTypeRange;
private SourceRange nameRange;
private SourceRange revisionRange;

private Builder()
{
}

/**
* Set the semantic ID
Comment thread
kaklakariada marked this conversation as resolved.
Outdated
*
* @param id
* the semantic ID
* @return this builder instance
*/
public Builder id(final SpecificationItemId id)
{
this.id = id;
return this;
}

/**
* Set the source range of the complete source construct
*
* @param range
* the source range
* @return this builder instance
*/
public Builder range(final SourceRange range)
{
this.range = range;
return this;
}

/**
* Set the source range of the artifact type, if represented in source
*
* @param artifactTypeRange
* the source range of the artifact type
* @return this builder instance
*/
public Builder artifactTypeRange(final SourceRange artifactTypeRange)
{
this.artifactTypeRange = artifactTypeRange;
return this;
}

/**
* Set the source range of the name, if represented in source
*
* @param nameRange
* the source range of the name
* @return this builder instance
*/
public Builder nameRange(final SourceRange nameRange)
{
this.nameRange = nameRange;
return this;
}

/**
* Set the source range of the revision, if represented in source
*
* @param revisionRange
* the source range of the revision
* @return this builder instance
*/
public Builder revisionRange(final SourceRange revisionRange)
{
this.revisionRange = revisionRange;
return this;
}

/**
* Build a new instance of {@link LocatedSpecificationItemId}.
*
* @return a new instance of {@link LocatedSpecificationItemId}
*/
public LocatedSpecificationItemId build()
{
return new LocatedSpecificationItemId(this);
}
}
}
Comment thread
kaklakariada marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.itsallcode.openfasttrace.api.core;

import java.util.Objects;

/**
* A zero-based position in source text. The character offset is measured in
* UTF-16 code units, matching Java strings and editor protocols.
*/
public final class SourcePosition
{
private final int line;
private final int column;

/**
* Create a source position.
*
* @param line
* zero-based line number
* @param column
* zero-based UTF-16 character offset
*/
public SourcePosition(final int line, final int column)
{
if (line < 0 || column < 0)
{
throw new IllegalArgumentException("Source positions must not be negative");
}
this.line = line;
this.column = column;
}

/**
* Get the zero-based line number.
*
* @return the zero-based line number
*/
public int getLine()
{
return this.line;
}

/**
* Get the zero-based UTF-16 character offset.
*
* @return the zero-based UTF-16 character offset
*/
public int getColumn()
{
return this.column;
}

@Override
public boolean equals(final Object other)
{
if (!(other instanceof final SourcePosition that))
{
return false;
}
return this.line == that.line && this.column == that.column;
}

@Override
public int hashCode()
{
return Objects.hash(this.line, this.column);
}

@Override
public String toString()
{
return this.line + ":" + this.column;
}
}
Loading
Loading