Skip to content
Merged

v7.2 #954

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7b8a6f2
#872 alias shell configuration `--copy`
lmorg Oct 25, 2025
11aac87
`args` support for `StrictFlagPlacement` and `--`
lmorg Oct 25, 2025
c9d40de
core: allow filterable function table
lmorg Oct 25, 2025
9485f10
alias: update doc
lmorg Oct 25, 2025
d5448de
fid-list: rewrite to support filtering
lmorg Oct 25, 2025
a952644
core: args flags package rewrite
lmorg Oct 25, 2025
ca049fa
core: refactoring forks
lmorg Oct 26, 2025
0563c8b
refactor: fid-list, forks, fids
lmorg Oct 26, 2025
638bfcc
foreach: fix regression bug in --parallel after args rewrite
lmorg Oct 26, 2025
3423460
#953 autocomplete: fix panic when JSON struct is zero-length
lmorg Oct 27, 2025
f002473
#864 core: temp directory value is immutable
lmorg Oct 27, 2025
70a01f9
#857 escape builtins should use IsMethod instead of param count
lmorg Oct 27, 2025
fe6a092
#857 escape builtins unit tests updated
lmorg Oct 27, 2025
3328b29
cache.db: dont cache anything with a TTL < 1hr
lmorg Nov 2, 2025
dfff8ac
wasm: support for builds via tinygo
lmorg Nov 2, 2025
1d08fca
integrations: yarn refactor (WIP)
lmorg Nov 2, 2025
50b3943
chore: rename main_GOOS.go -> signals_GOOS.go
lmorg Nov 9, 2025
cab431e
integrations: python: uv + venv.mx
lmorg Nov 9, 2025
012aa40
integrations: uv
lmorg Nov 10, 2025
dca418d
#956 integrations: yarn bug fix
lmorg Nov 10, 2025
3312502
integrations: yarn: don't unit test because there are too many edge c…
lmorg Nov 10, 2025
80f50a6
integrations: python venv improvements (#960)
lmorg Nov 25, 2025
e7e4012
integrations: terraform-docs summary
lmorg Nov 25, 2025
f951aaa
makefile: add tags to `make test`
lmorg Nov 27, 2025
6251e56
chore: update deps
lmorg Nov 27, 2025
6456b12
expressions bugfix: caught error wasn't being returned correctly
lmorg Dec 3, 2025
f3704ff
update copyright date
lmorg Jan 22, 2026
2fee565
update dependencies
lmorg Jan 22, 2026
492d987
docgen: update copyright date
lmorg Jan 22, 2026
c9d41fd
update changelog
lmorg Feb 1, 2026
2bde6c2
dev tools: add AI prompt to generate changelogs
lmorg Feb 1, 2026
47148fd
update changelog
lmorg Feb 1, 2026
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
109 changes: 109 additions & 0 deletions .github/prompts/createChangeLog.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
name: createChangeLog
description: Works through the release PR to compile a change long
argument-hint: versionNumber
---
# Instructions
- Follow EVERY step
- Do NOT start the following step until the previous step has finished
- Do NOT skip any steps
- This project is `Murex`, found on Github at https://github.com/lmorg/murex
- changelogs are found in `gen/changelog/`
- changelogs consist of 2 (two) files with the naming convention:
1. `${VERSION}_doc.yaml`
2. `${VERSION}.inc.md`
- `${VERSION}` is a version number and should follow the format: `v${MAJOR}.{MINOR}` where:
1. `${MAJOR}` is a numeric value
2. `${MINOR}` is a numeric value


# Step 1: Find Github Pull Request (PR)
- Check for open PRs in Github for only the Murex repository. We are only interested in a PR that is named like `v7.1`. Ignore all other PRs.
- There should only be one PR. If there is more than one PRs, or you are unsure which PR to check, then stop all steps and ask which PR to read.
- Do not read multiple PRs
- Do not read other repositories other than `murex`

# Step 2: Read all git commits, then summarize changes
From the selected PR:
- Read every git commit and create a list of changes.
- Use git commit messages as a clue for the change.
- If a commit message has a value like `#123` (`#` followed by a number) then this is a Github Issue. You should also read that Github issue to understand the change.
- Multiple git commits might be part of the same change.
- A git commit might contain multiple changes.

You should output a bullet point list of each change, with a short summary in the following format:
```
- ${COMPONENT}: ${SUMMARY} ([issue](${ISSUE}))
```
1. `${COMPONENT}` is a one word title for the system that is being changed
2. `${SUMMARY}` is the summary you generate
3. `${ISSUE}` is a URL to the Github issue -- if an change has a related Github Issue

Some issues might be links to Github discussions.

Also include a reference to any contributors either creating related Github issues, github discussions, commits or pull requests. These users should be related to this version and who are not `@lmorg`.

# Step 3: Grouping changes

The changes should be grouped into the following groups:
1. **Breaking changes**: these are changes that might impact the users upgrading from previous versions of this project
2. **Features**: these are new features added to the project in this version
3. **Bug Fixes**: these are changes that do not introduce new features but that fix bugs or issues with existing features

# Step 5: Update changelog
This step refers only to `${VERSION}.inc.md`:
- This file should be in `gen/changelog/`.
- If a file does not exist, then you can create one.
- If a file does exist then review the contents of it and add any changes you've identified if they don't already exist in this document
- This is a markdown document.
- It's contents should match the following:
```
## Breaking Changes

- ${COMPONENT}: ${SUMMARY} ([issue](${ISSUE}))

## v${VERSION}.xxxx

### Features

- ${COMPONENT}: ${SUMMARY} ([issue](${ISSUE}))

### Bug Fixes

- ${COMPONENT}: ${SUMMARY} ([issue](${ISSUE}))

## Special Thanks

Thank yous for this release go to ${LIST_OF_USERS_WHO_CONTRIBUTED} for your code, testing and feedback.

Also thank you to everyone in the [discussions group](https://github.com/lmorg/murex/discussions) and all who raise bug reports.

You rock!
```

# Step 6: Update summary

This step refers only to `${VERSION}_doc.yaml`:
- This file should be in `gen/changelog/`.
- If a file does not exist, then you can create one.
- If a file does exist then review the contents of it and add any changes if you think it alters the nature of the version summary.
- This is a YAML document.
- It's contents should match the following:

```
- DocumentID: ${VERSION}
Title: >-
${VERSION}
CategoryID: changelog
DateTime: ${VERSION}
Summary: >-
${VERSION_SUMMARY}
Description: |-
{{ include "gen/changelog/${VERSION}.inc.md" }}
Related:
- CONTRIBUTING
```
- ${VERSION} should be replaced with the version number.
- ${DATE} should be replaced with the current date and time, formatted like the following example: 2025-10-23 22:35
- ${VERSION_SUMMARY} will be a summary of all the changes in this version.

21 changes: 18 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ BUILD_TAGS?=$(shell cat builtins/optional/standard-opts.txt || echo "")

# Default target
.PHONY: all
all: generate
all: build
all: build-wasm

# Build the binary
.PHONY: build
Expand All @@ -39,16 +41,29 @@ run: build-dev

# Build with dev flags
.PHONY: build-dev
build-dev: generate
build-dev: GO_FLAGS += -gcflags="-N -l" -race
build-dev: BUILD_TAGS := "$(BUILD_TAGS),pprof,trace,no_crash_handler"
build-dev: build

# Build with TinyGo instead of default Go binary
.PHONY: build-tinygo
build-tinygo: LDFLAGS=-ldflags "-X github.com/lmorg/murex/app.branch=${BRANCH} -X github.com/lmorg/murex/app.buildDate=${BUILD_DATE}"
build-tinygo: BUILD_TAGS := "$(BUILD_TAGS),tinygo,no_cachedb,no_cmd_select,no_pty"
build-tinygo:
@echo "Building ${BINARY_NAME} using TinyGo..."
tinygo build -x -tags ${BUILD_TAGS}

# Build WASM
.PHONY: build-wasm
build-wasm: export GOOS=js
build-wasm: export GOARCH=wasm
build-wasm: build-tinygo

# Test
.PHONY: test
test: build
test:
@mkdir -p ./test/tmp
go test ./... -count 1 -race -covermode=atomic
go test ./... -count 1 -race -covermode=atomic -tags "$(BUILD_TAGS),no_crash_handler"
${BUILD_DIR}/${BINARY_NAME} -c 'g behavioural/*.mx -> foreach f { source $$f }; test run *'

# Benchmark
Expand Down
6 changes: 3 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const Name = "murex"
// Format of version string should be "$(Major).$(Minor).$(Revision) ($Branch)"
const (
Major = 7
Minor = 1
Revision = 4143
Minor = 2
Revision = 79
)

var (
Expand All @@ -29,7 +29,7 @@ func Branch() string { return branch }
func BuildDate() string { return strings.ReplaceAll(buildDate, "_", " ") }

// Copyright is the copyright owner string
const Copyright = "2018-2025 Laurence Morgan"
const Copyright = "2018-2026 Laurence Morgan"

// License is the projects software license
const License = "GPL v2"
Expand Down
9 changes: 6 additions & 3 deletions builtins/core/autocomplete/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ func cmdAutocomplete(p *lang.Process) error {
case "set":
return set(p)

//case "cache-dynamic":
// return cacheDynamic(p)

default:
p.Stdout.SetDataType(types.Null)
return errors.New("Not a valid mode. Please use `get` or `set`")
Expand All @@ -57,6 +54,8 @@ func get(p *lang.Process) error {
return err
}

var ErrEmptyAutocomplete = errors.New("empty autocomplete")

func set(p *lang.Process) error {
p.Stdout.SetDataType(types.Null)

Expand Down Expand Up @@ -93,6 +92,10 @@ func set(p *lang.Process) error {
return err
}

if len(flags) == 0 {
return ErrEmptyAutocomplete
}

// So we don't have nil values in JSON
if flags[0].CacheTTL == 0 {
flags[0].CacheTTL = 5
Expand Down
18 changes: 18 additions & 0 deletions builtins/core/autocomplete/autocomplete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"testing"

_ "github.com/lmorg/murex/builtins"
cmdautocomplete "github.com/lmorg/murex/builtins/core/autocomplete"
"github.com/lmorg/murex/lang"
"github.com/lmorg/murex/test"
"github.com/lmorg/murex/test/count"
)

Expand Down Expand Up @@ -88,3 +90,19 @@ func TestAutocomplete(t *testing.T) {
t.Logf(" Actual: %s", string(stdout))
}
}

// Bugfix: panic in autocomplete:
// https://github.com/lmorg/murex/issues/953
func TestAutocompleteIssue953(t *testing.T) {
count.Tests(t, 1)

tests := []test.MurexTest{
{
Block: `autocomplete set foobar %[]`,
Stderr: cmdautocomplete.ErrEmptyAutocomplete.Error(),
ExitNum: 1,
},
}

test.RunMurexTestsRx(tests, t)
}
6 changes: 3 additions & 3 deletions builtins/core/dag/fanout.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func cmdFanout(p *lang.Process) error {
return err
}

dt := flags[fDataType]
dt := flags.GetValue(fDataType).String()
if dt == "" {
if p.IsMethod {
dt = p.Stdin.GetDataType()
Expand All @@ -65,7 +65,7 @@ func cmdFanout(p *lang.Process) error {
}
p.Stdout.SetDataType(dt)

parse := flags[fParse] == types.TrueString
parse := flags.GetValue(fParse).Boolean()

switch {
case len(sBlocks) == 0:
Expand Down Expand Up @@ -141,7 +141,7 @@ func cmdFanout(p *lang.Process) error {

wg.Wait()

if flags[fConcatenate] == types.TrueString {
if flags.GetValue(fConcatenate).Boolean() {
for i := range rBlocks {
if errs[i] != nil {
return fmt.Errorf("error returned from vertex %d:\n%v", i+1, err)
Expand Down
115 changes: 55 additions & 60 deletions builtins/core/datatools/count.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,83 +74,78 @@ func cmdCount(p *lang.Process) error {
return err
}

if len(flags) == 0 {
flags[argTotal] = types.TrueString
}

for f := range flags {
switch f {
case argDuplications:
v, err := countDuplications(p)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}

b, err := json.Marshal(v, p.Stdout.IsTTY())
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}
switch {
case flags.GetValue(argDuplications).Boolean():
v, err := countDuplications(p)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}

p.Stdout.SetDataType(types.Json)
_, err = p.Stdout.Write(b)
b, err := json.Marshal(v, p.Stdout.IsTTY())
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}

case argUnique:
v, err := countUnique(p)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}
p.Stdout.SetDataType(types.Json)
_, err = p.Stdout.Write(b)
return err

p.Stdout.SetDataType(types.Integer)
_, err = p.Stdout.Write([]byte(strconv.Itoa(v)))
case flags.GetValue(argUnique).Boolean():
v, err := countUnique(p)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}

case argTotal:
v, err := countTotal(p)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}
p.Stdout.SetDataType(types.Integer)
_, err = p.Stdout.Write([]byte(strconv.Itoa(v)))
return err

p.Stdout.SetDataType(types.Integer)
_, err = p.Stdout.Write([]byte(strconv.Itoa(v)))
case flags.GetValue(argSum).Boolean(), flags.GetValue(argSumStrict).Boolean():
f, err := countSum(p, flags.GetValue(argSumStrict).Boolean())
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}

case argSum, argSumStrict:
f, err := countSum(p, flags[argSumStrict] == types.TrueString)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}
p.Stdout.SetDataType(types.Number)
_, err = p.Stdout.Write([]byte(types.FloatToString(f)))
return err

p.Stdout.SetDataType(types.Number)
_, err = p.Stdout.Write([]byte(types.FloatToString(f)))
case flags.GetValue(argBytes).Boolean():
p.Stdout.SetDataType(types.Integer)
b, err := p.Stdin.ReadAll()
if err != nil {
return err
}
_, err = p.Stdout.Write([]byte(fmt.Sprintf("%d", len(b))))
return err

case argBytes:
p.Stdout.SetDataType(types.Integer)
b, err := p.Stdin.ReadAll()
if err != nil {
return err
}
_, err = p.Stdout.Write([]byte(fmt.Sprintf("%d", len(b))))
case flags.GetValue(argRunes).Boolean():
p.Stdout.SetDataType(types.Integer)
b, err := p.Stdin.ReadAll()
if err != nil {
return err
}
_, err = p.Stdout.Write([]byte(fmt.Sprintf("%d", utf8.RuneCount(b))))
return err

case argRunes:
p.Stdout.SetDataType(types.Integer)
b, err := p.Stdin.ReadAll()
if err != nil {
return err
}
_, err = p.Stdout.Write([]byte(fmt.Sprintf("%d", utf8.RuneCount(b))))
case flags.GetValue(argTotal).Boolean():
fallthrough

default:
v, err := countTotal(p)
if err != nil {
p.Stdout.SetDataType(types.Null)
return err
}
}

return nil
p.Stdout.SetDataType(types.Integer)
_, err = p.Stdout.Write([]byte(strconv.Itoa(v)))
return err
}
}

func countDuplications(p *lang.Process) (map[string]int, error) {
Expand Down
Loading
Loading