all repos

clerk @ e2e9e2b

missing tooling for ledger/hledger
4 files changed, 56 insertions(+), 0 deletions(-)
lint: add duplicated-transaction
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-07-29 19:32:29 +0300
Authored at: 2026-07-28 14:24:23 +0300
Change ID: luqsqtnnxonkqpsnronnwnwqsxuxutsx
Parent: f3b258b
M internal/linter/linter_test.go
···
        22
        22
         	"orderdate":                {&OrderDate{}},

      
        23
        23
         	"duplicated-account":       {&DuplicatedAccount{}},

      
        24
        24
         	"duplicated-commodity":     {&DuplicatedCommodity{}},

      
        
        25
        +	"duplicated-transaction":   {&DuplicatedTransaction{}},

      
        25
        26
         	"undeclared-commodity":     {&UndeclaredCommodity{}},

      
        26
        27
         	"undeclared-account":       {&UndeclaredAccount{}},

      
        27
        28
         	"unbalanced-transaction":   {&UnbalancedTransaction{}},

      
A internal/linter/rule_duplicated_transaction.go
···
        
        1
        +package linter

      
        
        2
        +

      
        
        3
        +import (

      
        
        4
        +	"fmt"

      
        
        5
        +

      
        
        6
        +	"olexsmir.xyz/clerk/internal/analyzer"

      
        
        7
        +)

      
        
        8
        +

      
        
        9
        +// DuplicatedTransaction flags idnetical transactions.

      
        
        10
        +type DuplicatedTransaction struct{}

      
        
        11
        +

      
        
        12
        +func (DuplicatedTransaction) ID() RuleID         { return "duplicated-transaction" }

      
        
        13
        +func (DuplicatedTransaction) Severity() Severity { return SeverityWarning }

      
        
        14
        +func (d *DuplicatedTransaction) CheckJournal(an *analyzer.Analysis) []Find {

      
        
        15
        +	var finds []Find

      
        
        16
        +	for _, txs := range an.TransactionsByKey {

      
        
        17
        +		if len(txs) <= 1 {

      
        
        18
        +			continue

      
        
        19
        +		}

      
        
        20
        +		for _, tx := range txs[1:] {

      
        
        21
        +			finds = append(finds, Find{

      
        
        22
        +				Code:     d.ID(),

      
        
        23
        +				Severity: d.Severity(),

      
        
        24
        +				Message:  fmt.Sprintf("duplicate of transaction at line %d", txs[0].Span.Start.Line),

      
        
        25
        +				Span:     tx.Span,

      
        
        26
        +			})

      
        
        27
        +		}

      
        
        28
        +	}

      
        
        29
        +	return finds

      
        
        30
        +}

      
M internal/linter/rules.go
···
        24
        24
         	&OrderDate{},

      
        25
        25
         	&DuplicatedAccount{},

      
        26
        26
         	&DuplicatedCommodity{},

      
        
        27
        +	&DuplicatedTransaction{},

      
        27
        28
         	&UndeclaredCommodity{},

      
        28
        29
         	&UndeclaredAccount{},

      
        29
        30
         	&UnbalancedTransaction{},

      
A internal/linter/testdata/duplicated-transaction.txtar
···
        
        1
        +-- in.journal --

      
        
        2
        +2024-01-01 groceries

      
        
        3
        +  expenses:food  $10

      
        
        4
        +  assets:cash

      
        
        5
        +

      
        
        6
        +2024-01-01 groceries

      
        
        7
        +  expenses:food  $10

      
        
        8
        +  assets:cash

      
        
        9
        +

      
        
        10
        +2024-01-02 taxi

      
        
        11
        +  expenses:transport  $20

      
        
        12
        +  assets:cash

      
        
        13
        +

      
        
        14
        +2024-01-02 taxi

      
        
        15
        +  expenses:transport  $20

      
        
        16
        +  assets:cash

      
        
        17
        +

      
        
        18
        +2024-01-03 unique

      
        
        19
        +  expenses:misc  $5

      
        
        20
        +  assets:cash

      
        
        21
        +

      
        
        22
        +-- expect --

      
        
        23
        +in.journal:5:1: duplicated-transaction: duplicate of transaction at line 1

      
        
        24
        +in.journal:13:1: duplicated-transaction: duplicate of transaction at line 9