Skip to content

Commit

Permalink
tweak metamodel
Browse files Browse the repository at this point in the history
  • Loading branch information
bjornregnell committed Mar 26, 2024
1 parent 24b78e1 commit 02400a8
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 65 deletions.
19 changes: 10 additions & 9 deletions langSpec-GENERATED.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,21 @@ MultiLineRel ::= Ent RelType SubModel
SubModel ::= (Indent(n + 1) ElemStart Elem)* Outdent(n)
EntityType ::= 'Barrier' | 'Breakpoint' | 'Component' | 'Configuration' | 'DataType' | 'Design' | 'Event' |
'Feature' | 'Field' | 'Function' | 'Goal' | 'Idea' | 'Image' | 'Interface' | 'Issue' | 'Label' |
'Product' | 'Prototype' | 'Quality' | 'Relationship' | 'Release' | 'Req' | 'Resource' | 'Risk'
| 'Screen' | 'Section' | 'Stakeholder' | 'State' | 'System' | 'Target' | 'Task' | 'TestCase' |
'UseCase' | 'User' | 'UserStory' | 'Variant' | 'VariationPoint'
EntityType ::= 'Barrier' | 'Breakpoint' | 'Class' | 'Component' | 'Configuration' | 'Data' | 'Design' |
'Domain' | 'Epic' | 'Event' | 'Feature' | 'Function' | 'Goal' | 'Idea' | 'Image' | 'Interface' |
'Issue' | 'Label' | 'Member' | 'Module' | 'Product' | 'Prototype' | 'Quality' | 'Relationship'
| 'Release' | 'Req' | 'Resource' | 'Risk' | 'Screen' | 'Section' | 'Stakeholder' | 'State' |
'Story' | 'System' | 'Target' | 'Task' | 'Term' | 'Test' | 'UseCase' | 'User' | 'Variant' |
'VariationPoint'
IntAttrType ::= 'Benefit' | 'Capacity' | 'Cost' | 'Damage' | 'Frequency' | 'Max' | 'Min' | 'Order' | 'Prio' |
'Probability' | 'Profit' | 'Value'
StrAttr ::= 'Comment' | 'Deprecated' | 'Example' | 'Expectation' | 'Failure' | 'Gist' | 'Heading' |
'Input' | 'Location' | 'Output' | 'Spec' | 'Text' | 'Why'
StrAttr ::= 'Comment' | 'Constraints' | 'Deprecated' | 'Example' | 'Expectation' | 'Failure' | 'Gist' |
'Input' | 'Location' | 'Output' | 'Spec' | 'Text' | 'Title' | 'Why'
RelType ::= 'Binds' | 'Deprecates' | 'Excludes' | 'Has' | 'Helps' | 'Hurts' | 'Implements' | 'Precedes' |
'RelatesTo' | 'Requires' | 'SupertypeOf' | 'Verifies'
RelType ::= 'Binds' | 'Deprecates' | 'Excludes' | 'Has' | 'Helps' | 'Hurts' | 'Impacts' | 'Implements' |
'Inherits' | 'Interacts' | 'Precedes' | 'Relates' | 'Requires' | 'Verifies'
```

## Special Parsing Rules
Expand Down
36 changes: 23 additions & 13 deletions src/main/scala/02-meta-model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ object meta:
import EntGroup.*

val entityConceptGroups: ArraySeq[((EntGroup,String),String)] = ArraySeq(
ReqContext -> "Product" -> "An artifact offered to users or customers in an application domain, e.g. a software app or an embedded system.",
ReqContext -> "Release" -> "A specific version of a product offered at a specific time to end users.",
ReqContext -> "Domain" -> "The application area of a product with its surrounding entities, e.g. users or other systems.",
ReqContext -> "Product" -> "An artifact offered to users or customers, e.g. an app, service or embedded system.",
ReqContext -> "Release" -> "A specific version of a product offered to end users at a specific time.",
ReqContext -> "Resource" -> "A capability of, or support for product development, e.g. a development team or some testing equipment.",
ReqContext -> "Risk" -> "Something negative that may happen.",
ReqContext -> "Section" -> "A part of a requirements document or a subdomain.",
ReqContext -> "Section" -> "A part of a requirements document.",
ReqContext -> "Stakeholder" -> "A role, person or legal entity with a stake in the development or operation of a product.",
ReqContext -> "System" -> "A set of software or hardware components interacting with users or systems.",
ReqContext -> "Term" -> "A word or group of words having a particular meaning in a particular domain.",
ReqContext -> "User" -> "A human interacting with a system.",

GeneralReq -> "Feature" -> "A releasable characteristic of a product. A (high-level, coherent) bundle of requirements.",
Expand All @@ -23,26 +25,31 @@ object meta:
GeneralReq -> "Image" -> "A visual representation, picture or diagram.",
GeneralReq -> "Issue" -> "Something needed to be fixed or work to do.",
GeneralReq -> "Req" -> "Something needed or wanted. An abstract term denoting any type of information relevant to the (specification of) intentions behind system development. Short for requirement.",
GeneralReq -> "TestCase" -> "A procedure to check if requirements are met.",
GeneralReq -> "Test" -> "A procedure to check if requirements are met.", // Or TestCase ?
GeneralReq -> "Label" -> "A descriptive tag used to classify something.",


DataReq -> "DataType" -> "A data entity, class, type or record stored or processed by a system.", // OR Data OR DataEntity
DataReq -> "Field" -> "An attribute that is part of a data type.", // Or DataField or DataAttribute
DataReq -> "Data" -> "A data entity, type, class, or record stored or processed by a system.", // OR Data OR DataEntity OR DataType?
DataReq -> "Class" -> "An extensible template for creating objects. A set of objects with certain attributes in common. A category.", // somewhat redundant with Data but the latter is more general
DataReq -> "Member" -> "A data entity that is part of another entity, eg. a field or method in a in a class", // Or DataField or DataAttribute or DataProperty
DataReq -> "Relationship" -> "A specific way that data types are connected.", // Or Association or Relation or DataRelation

DesignReq -> "Component" -> "A composable part of a system architecture. A reusable, interchangeable system unit or functionality.",
// https://softwareengineering.stackexchange.com/questions/178927/is-there-a-difference-between-a-component-and-a-module
DesignReq -> "Design" -> "A specific realization. A description of an implementation.",
DesignReq -> "Module" -> "A collection of coherent functions and interfaces.",
DesignReq -> "Prototype" -> "A system with limited functionality used to demonstrate a design idea.",
DesignReq -> "Screen" -> "A design of (a part of) a user interface.",

FunctionalReq -> "Epic" -> "A coherent collection of stories, use cases or issues. A large part of a release.",
// https://www.atlassian.com/agile/project-management/epics-stories-themes
FunctionalReq -> "Event" -> "Something that can happen in the domain or in the system.",
FunctionalReq -> "Function" -> "A description of how input is mapped to output. A capability of a system to do something specific.",
FunctionalReq -> "Interface" -> "A defined way to interact with a system.",
FunctionalReq -> "State" -> "A mode or condition of something in the domain or in the system. A configuration of data.",
FunctionalReq -> "Task" -> "A piece of work by users, potentially supported by a system.",
FunctionalReq -> "UseCase" -> "A list of steps defining interactions between actors and a system to achieve a goal.",
FunctionalReq -> "UserStory" -> "A short description of what a user does or needs. Short for user story.",
FunctionalReq -> "UseCase" -> "A goal-fulfilling interaction between users and a product in a specific usage context.",
FunctionalReq -> "Story" -> "A description of what a user persona wants in order to achieve a goal. Short for user story.",

QualityReq -> "Barrier" -> "Something that makes it difficult to achieve a goal or a higher quality level.",
QualityReq -> "Breakpoint" -> "A point of change, representing an important shift in the relation between quality and benefit.",
Expand All @@ -58,12 +65,13 @@ object meta:

val strAttrConcepts = ArraySeq[(String,String)](
"Comment" -> "A note with a remark or a discussion on an entity.",
"Constraints" -> "A collection of propositions that constrain a solution space or restrict possible attribute values.",
"Deprecated" -> "A description of why an entity should be avoided, often because it is superseded by another entity, as indicated by a 'deprecates' relation.",
"Example" -> "A description that illustrates some entity by a typical instance.",
"Expectation" -> "A required output of a test in order to be counted as passed.",
"Failure" -> "A description of an error that prevents the normal execution of a system.",
"Failure" -> "An error that prevents the normal execution of a system.",
"Gist" -> "A short and simple description. A summary capturing the essence of an entity.",
"Heading" -> "A title, subtitle, or topic. Use one or more leading # to indicate level 1 to 6.",
"Title" -> "A general or descriptive heading. One or more leading # indicate heading level.",
"Input" -> "Data consumed by an entity, ",
"Location" -> "A location of a resource such as a web address or a path to a file of persistent data.",
"Output" -> "Data produced by an entity, e.g. a function or a test.",
Expand Down Expand Up @@ -94,11 +102,13 @@ object meta:
"has" -> "Expresses containment, substructure, composition or aggregation. An entity contains another entity.",
"helps" -> "Positive influence. A goal supports the fulfillment of another goal.",
"hurts" -> "Negative influence. A goal hinders another goal.",
"impacts" -> "Some unspecific influence. A new feature impacts an existing component.",
"implements" -> "Realisation of an entity, e.g. a component implements a feature.",
"precedes" -> "Temporal ordering. A feature precedes (is implemented before) another feature.",
"relatesTo" -> "Some general relation to another entity.",
"interacts" -> "A communication relation. A user interacts with an interface.",
"precedes" -> "Temporal ordering. A feature precedes (should be implemented before) another feature.",
"relates" -> "Some general, unspecific relation to another entity.",
"requires" -> "A requested combination. One function requires that a another function is also implemented.",
"supertypeOf" -> "Super-typing, generalization, includes another more specific entity. One data entity is a supertype of another.",
"inherits" -> "One entity inherits properties of another entity. A specialization, extension or subtype relation. ",
"verifies" -> "Gives evidence of correctness. A test verifies the implementation of a feature.",
).sorted

Expand Down
22 changes: 14 additions & 8 deletions src/main/scala/03-model-GENERATED.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ final case class Rel(e: Ent, rt: RelType, sub: Model) extends Elem:
def expandSubnodes: Vector[Rel] = sub.elems.collect{ case n: Node => Rel(e, rt, Model(n)) }

enum EntType extends NodeType:
case Barrier, Breakpoint, Component, Configuration, DataType, Design, Event, Feature, Field, Function, Goal, Idea, Image, Interface, Issue, Label, Product, Prototype, Quality, Relationship, Release, Req, Resource, Risk, Screen, Section, Stakeholder, State, System, Target, Task, TestCase, UseCase, User, UserStory, Variant, VariationPoint
case Barrier, Breakpoint, Class, Component, Configuration, Data, Design, Domain, Epic, Event, Feature, Function, Goal, Idea, Image, Interface, Issue, Label, Member, Module, Product, Prototype, Quality, Relationship, Release, Req, Resource, Risk, Screen, Section, Stakeholder, State, Story, System, Target, Task, Term, Test, UseCase, User, Variant, VariationPoint

enum StrAttrType extends AttrType[String]:
case Comment, Deprecated, Example, Expectation, Failure, Gist, Heading, Input, Location, Output, Spec, Text, Why
case Comment, Constraints, Deprecated, Example, Expectation, Failure, Gist, Input, Location, Output, Spec, Text, Title, Why

enum IntAttrType extends AttrType[Int]:
case Benefit, Capacity, Cost, Damage, Frequency, Max, Min, Order, Prio, Probability, Profit, Value

enum RelType extends ElemType:
case Binds, Deprecates, Excludes, Has, Helps, Hurts, Implements, Precedes, RelatesTo, Requires, SupertypeOf, Verifies
case Binds, Deprecates, Excludes, Has, Helps, Hurts, Impacts, Implements, Inherits, Interacts, Precedes, Relates, Requires, Verifies

export EntType.*
export StrAttrType.*
Expand Down Expand Up @@ -79,20 +79,26 @@ extension (e: Ent)
def hurts(sub: Elem*): Rel = Rel(e, Hurts, Model(sub*))
def hurts: EntLink = EntLink(e, Hurts)

def impacts(sub: Elem*): Rel = Rel(e, Impacts, Model(sub*))
def impacts: EntLink = EntLink(e, Impacts)

def implements(sub: Elem*): Rel = Rel(e, Implements, Model(sub*))
def implements: EntLink = EntLink(e, Implements)

def inherits(sub: Elem*): Rel = Rel(e, Inherits, Model(sub*))
def inherits: EntLink = EntLink(e, Inherits)

def interacts(sub: Elem*): Rel = Rel(e, Interacts, Model(sub*))
def interacts: EntLink = EntLink(e, Interacts)

def precedes(sub: Elem*): Rel = Rel(e, Precedes, Model(sub*))
def precedes: EntLink = EntLink(e, Precedes)

def relatesTo(sub: Elem*): Rel = Rel(e, RelatesTo, Model(sub*))
def relatesTo: EntLink = EntLink(e, RelatesTo)
def relates(sub: Elem*): Rel = Rel(e, Relates, Model(sub*))
def relates: EntLink = EntLink(e, Relates)

def requires(sub: Elem*): Rel = Rel(e, Requires, Model(sub*))
def requires: EntLink = EntLink(e, Requires)

def supertypeOf(sub: Elem*): Rel = Rel(e, SupertypeOf, Model(sub*))
def supertypeOf: EntLink = EntLink(e, SupertypeOf)

def verifies(sub: Elem*): Rel = Rel(e, Verifies, Model(sub*))
def verifies: EntLink = EntLink(e, Verifies)
3 changes: 2 additions & 1 deletion src/main/scala/04-ModelMembers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ transparent trait ModelMembers:

case a: Attr[?] =>
if a.at == Text then sb.append(s"$indent${a.value}\n")
else if a.at == Heading && a.value.toString.trim.startsWith("#") then sb.append(s"$indent${a.value}\n")
else if a.at == Title && a.value.toString.trim.startsWith("#") then
sb.append(s"$indent${a.value.toString.trim}\n")
else sb.append(s"$indent* ${a.at} ${a.value}\n")

case e: Ent =>
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/05-MarkdownParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ object MarkdownParser:
val value = if j > i then takeLines(endOfTextBlock).mkString(s"$line\n","\n","") else line
elems.append(sa.apply(value.removeLeadingBullet))

if isFirstHeading then appendUntilEnd(Heading)
if isFirstHeading then appendUntilEnd(Title)
else if !isFirstBulletElem then
debugMsg(s"""isFirstBulletElem==false first=="$first"""")
appendUntilEnd(Text)
Expand Down
51 changes: 18 additions & 33 deletions src/test/scala/generateLang.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,44 +58,29 @@ object showDeprecations:
val migration: Seq[((String, String, String), String)] = Seq(
("Deleted", "Entity", "Actor") -> "use System or User",
("Deleted", "Entity", "App") -> "use Product or System",
("Deleted", "Entity", "Class") -> "use DataType",
("Deleted", "Entity", "Data") -> "use DataType",
("Deleted", "Entity", "Domain") -> "use Section",
("Deleted", "Entity", "Epic") -> "use Section",
("Deleted", "Entity", "Item") -> "use Text or Label",
("Deleted", "Entity", "Member") -> "use Field or Function",
("Deleted", "Entity", "Meta") -> "use DataType",
("Deleted", "Entity", "Item") -> "use Label or Text",
("Deleted", "Entity", "Meta") -> "use Data or Class",
("Deleted", "Entity", "MockUp") -> "use Prototype",
("Deleted", "Entity", "Module") -> "use Component",
("Deleted", "Entity", "Scenario") -> "use UseCase or UserStory",
("Deleted", "Entity", "Service") -> "use Function or Feature",
("Deleted", "Entity", "Story") -> "use UserStory",
("Deleted", "Entity", "Term") -> "use Text or Label",
("Deleted", "Entity", "Test") -> "use TestCase",
("Deleted", "Entity", "Scenario") -> "use UseCase or Story",
("Deleted", "Entity", "Service") -> "use Product, Feature or Function",
("Deleted", "Entity", "Ticket") -> "use Issue",
("Deleted", "Entity", "WorkPackage") -> "use Section or Issue",
("Added", "Entity", "DataType") -> "instead of Class, Data",
("Added", "Entity", "Field") -> "instead of Member",
("Added", "Entity", "Image") -> "use with attribute Location",
("Deleted", "Entity", "WorkPackage") -> "use Issue, Epic or Section",
("Added", "Entity", "Image") -> "was attribute, use with attribute Location",
("Added", "Entity", "Prototype") -> "instead of Mockup",
("Added", "Entity", "TestCase") -> "instead of Test",
("Added", "Entity", "UserStory") -> "instead of Story",
("Deleted", "Attribute", "Code") -> "use Text and markdown code fences",
("Deleted", "Attribute", "Constraints") -> "???",
("Deleted", "Attribute", "FileName") -> "use Location",
("Deleted", "Attribute", "Image") -> "use entity Image with attribute Location",
("Deleted", "Attribute", "Code") -> "use Text with markdown code fences",
("Deleted", "Attribute", "FileName") -> "use Location",
("Deleted", "Attribute", "Image") -> "use entity Image with attribute Location",
("Deleted", "Attribute", "Status") -> "use Label",
("Deleted", "Attribute", "Title") -> "use Heading with # indicating level h1 to h6",
("Added", "Attribute", "Failure") -> "use together with Risk, TestCase",
("Added", "Attribute", "Heading") -> "instead of Title",
("Added", "Attribute", "Failure") -> "use together with Risk, Test",
("Added", "Attribute", "Location") -> "instead of FileName",
("Deleted", "Relation", "impacts") -> "use relatesTo",
("Deleted", "Relation", "interactsWith") -> "use relatesTo or has",
("Deleted", "Relation", "is") -> "use supertypeOf in reverse order",
("Deleted", "Relation", "superOf") -> "use supertypeOf",
("Added", "Relation", "supertypeOf") -> "instead of superOf",

)
("Deleted", "Relation", "interactsWith") -> "use interacts",
("Deleted", "Relation", "is") -> "use inherits",
("Deleted", "Relation", "relatesTo") -> "use relates",
("Deleted", "Relation", "superOf") -> "use inherits",
("Added", "Relation", "interacts") -> "instead of interactsWith",
("Added", "Relation", "inherits") -> "instead of is, superOf",
("Added", "Relation", "relates") -> "instead of relatesTo",
)

def migrationAdvice = for (key, advice) <- migration yield
val (o, t, c) = key
Expand Down

0 comments on commit 02400a8

Please sign in to comment.