Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate away from esy and use OCaml 5 #38

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
91 changes: 37 additions & 54 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [
ubuntu-latest,
macos-latest,
# windows-latest
]
ocaml-compiler:
- 5.1.0

steps:
- uses: actions/checkout@v2
Expand All @@ -32,53 +38,47 @@ jobs:
${{ runner.os }}-build-
${{ runner.os }}-

- name: Install esy
run: npm install -g esy@0.6.12

- name: Restore esy source cache
id: esy-cache
uses: actions/cache@v2
- name: Load opam cache when not Windows
if: runner.os != 'Windows'
id: opam-cache
uses: actions/cache/restore@v3
with:
path: ~/.esy/source
key: source-${{ matrix.os }}-${{ hashFiles('**/index.json') }}

- name: Install
run: esy install
path: ~/.opam
key: opam-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('**.opam') }}

- name: Print esy cache
id: print_esy_cache
run: node scripts/print-esy-cache.js
- name: Load opam cache when Windows
if: runner.os == 'Windows'
id: opam-cache-windows
uses: actions/cache/restore@v3
with:
path: _opam
key: opam-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('**.opam') }}

- name: Try to restore dependencies cache
id: deps-cache
uses: actions/cache@v2
- name: Use OCaml ${{ matrix.ocaml-compiler }}
uses: ocaml/setup-ocaml@d7e9ba90ba3b08308d8379b401c1317dbd443782
with:
path: ${{ steps.print_esy_cache.outputs.esy_cache }}
key: deps-${{ matrix.os }}-${{ hashFiles('**/index.json') }}
restore-keys: deps-${{ matrix.os }}-
ocaml-compiler: ${{ matrix.ocaml-compiler }}
dune-cache: true
opam-disable-sandboxing: true

- name: Install deps
run: opam install . --deps-only --with-doc --with-test

- name: Build dependencies
if: steps.deps-cache.outputs.cache-hit != 'true'
run: esy build-dependencies
- name: Pin some deps
run: make pin

- name: Build
run: esy build
run: make build

- name: Test
if: ${{ matrix.os != 'windows-latest' }}
run: |
rm test/__snapshots__/.gitkeep
esy dune runtest --instrument-with bisect_ppx --force
esy bisect-ppx-report send-to Coveralls
env:
BISECT_SILENT: "ERR"
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
PULL_REQUEST_NUMBER: ${{ github.event.number }}
- name: Check formatting
run: make format-check

- name: Run tests
run: make test

- name: Web build
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
esy b dune build
cd website
npm ci
npm run build-production
Expand Down Expand Up @@ -114,11 +114,6 @@ jobs:
name: bundled
path: _build/default/js/Js.bc.js

# Cleanup build cache if dependencies have changed
- name: Clean build cache
if: steps.deps-cache.outputs.cache-hit != 'true'
run: esy cleanup .

publish:
needs: build
name: Publish
Expand Down Expand Up @@ -184,24 +179,12 @@ jobs:
zip -r ../../query-json-windows-x64.zip .
cd ../..

- name: End to end Test (Linux)
if: ${{ matrix.os == 'ubuntu-latest' }}
run: npx bats ./e2e/test.sh
env:
IS_CI: true

- name: End to end Test (Windows)
if: ${{ matrix.os == 'windows-latest' }}
run: sh -c 'npx bats ./e2e/test.sh' \"$(pwd)/node_modules/bats/bin/bats\"
env:
IS_CI: true

- name: Check if should be published
if: ${{ success() && github.event_name != 'pull_request' }}
id: newVersion
run: |
REMOTE=$(npm view @davesnx/query-json version);
CURRENT=$(jq -r '.version' esy.json);
CURRENT=$(cat dune-project | grep -oE '\(version [0-9]+\.[0-9]+\.[0-9]+\)' | grep -o '\d\+.\d\+.\d\+');
if [ "$REMOTE" != "$CURRENT" ]
then
echo "::set-output name=shouldPublish::true";
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ _coverage
coverage.json

# Website artifacts
website/build
dist
74 changes: 74 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
project_name = query-json

DUNE = opam exec -- dune
opam_file = $(project_name).opam

.PHONY: help
help: ## Print this help message
@echo "";
@echo "List of available make commands";
@echo "";
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}';
@echo "";

.PHONY: build
build: ## Build the project, including non installable libraries and executables
$(DUNE) build @all

.PHONY: build-prod
build-prod: ## Build for production (--profile=prod)
$(DUNE) build --profile=prod @all

.PHONY: dev
dev: ## Build in watch mode
$(DUNE) build -w @all

.PHONY: clean
clean: ## Clean artifacts
$(DUNE) clean

.PHONY: test
test: ## Run the unit tests
$(DUNE) build @runtest

.PHONY: test-watch
test-watch: ## Run the unit tests in watch mode
$(DUNE) build @runtest -w

.PHONY: test-promote
test-promote: ## Updates snapshots and promotes it to correct
$(DUNE) build @runtest --auto-promote

.PHONY: deps
deps: $(opam_file) ## Alias to update the opam file and install the needed deps

.PHONY: format
format: ## Format the codebase with ocamlformat
$(DUNE) build @fmt --auto-promote

.PHONY: format-check
format-check: ## Checks if format is correct
$(DUNE) build @fmt

.PHONY: pin
pin: ## Pin dependencies
opam pin add jsoo-react.dev "git+https://github.com/ml-in-barcelona/jsoo-react.git#8fda15c39665ac27841c7659422f82ac331e0a01" -y
opam pin add jsoo-css.dev "git+https://github.com/ml-in-barcelona/jsoo-css.git#8169b6764eab18d4cb98ce8f791cd47a54b1e954" -y

.PHONY: create-switch
create-switch: ## Create opam switch
opam switch create . 5.1.0 --deps-only --with-test -y

.PHONY: install
install: create-switch pin ## Install dependencies

.PHONY: init
init: install ## Create a local dev enviroment

.PHONY: subst
subst: ## Run dune substitute
$(DUNE) subst

$(opam_file): dune-project ## Update the package dependencies when new deps are added to dune-project
$(DUNE) build @install
opam install . --deps-only --with-test # Install the new dependencies
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ It was created with mostly two reasons, learning and having fun.

## It brings

- **Great Performance**: Fast, small footprint and minimum run-time. Check [Performance section](#Performance) for a longer explanation.
- **Great Performance**: Fast, small footprint and minimum runtime. Check [Performance section](#Performance) for a longer explanation, but it can be 2x to 5x faster than jq.
- **Delightful errors**:
- Better errors when json types and operation don't match:
```bash
Expand All @@ -53,12 +53,10 @@ Check the content of [scripts/install.sh](./scripts/install.sh) before running a
curl -sfL https://raw.githubusercontent.com/davesnx/query-json/master/scripts/install.sh | bash
```

### Using npm/yarn
### Using npm

```bash
npm install --global @davesnx/query-json
# or
yarn global add @davesnx/query-json
```

### Download zip files from [GitHub](https://github.com/davesnx/query-json/releases)
Expand All @@ -67,7 +65,7 @@ yarn global add @davesnx/query-json

I recommend to write the query in single-quotes inside the terminal, since writting JSON requires double-quotes for accessing properties.

> NOTE: I have aliased query-json to be "q" for short, you can set it in your dotfiles. `alias q="query-json"`.
> NOTE: I have aliased query-json to "q" for short, you can set it in your dotfiles with `alias q="query-json"`.

#### query a json file
```bash
Expand All @@ -77,6 +75,7 @@ q '.' pokemons.json
#### query from stdin
```bash
cat pokemons.json | q '.'
q '.' <<< '{ "bulvasur": { "id": 1, "power": 20 } }'
```

#### query a json inlined
Expand All @@ -91,7 +90,7 @@ q '.' pokemons.json --no-colors

## Performance

[This report](./benchmarks/report.md) is not an exhaustive performance report of both tools, it's a overview for the percieved performance of the user. Here I don't profile each tool and try to see what are the bootlenecks, since I assume that both tools have the penalty of parsing a JSON file. Simply run a bash script and analyze the results.
[This report](./benchmarks/report.md) is not an exhaustive performance report of both tools, it's a overview for the percieved performance of the user. I don't profile each tool and try to see what are the bootlenecks, since I assume that both tools have the penalty of parsing a JSON file.

Aside from that, **query-json** doesn't have feature parity with **jq** which is ok at this point, but **jq** contains a ton of functionality that query-json misses. Adding the missing operations on **query-json** won't affect the performance of it, that could not be true for features like "modules" or "tests", which they will not be implemented in **query-json**.

Expand Down Expand Up @@ -123,7 +122,7 @@ The report shows that **query-json** is between 2x and 5x faster than **jq** in
- Array Index: `.[2]` ✅
- Pipe: `|` ✅
- Array/String Slice: `.[10:15]` ⚠️
- Array/Object Value Iterator: `.[]`
- Array/Object Value Iterator: `.[]` ⚠️
- Comma: `,` ✅
- Parenthesis: `()` ✅️

Expand Down
8 changes: 5 additions & 3 deletions benchmarks/report.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Benchmark Report
The benchmarks run on a 13" MacBook Pro (2020) with a 1.4 GHz Quad-Core i5 and 16GB 2133MHz RAM.

This benchmark consists twoo different steps, the boot time and a timer on a few operations over different (json) file sizes.
This benchmark consists two steps, the boot time and a timer on a few operations over different (json) file sizes.

Executing `$ ./benchmarks/hyper.sh` runs hyperfile.
Executing `$ ./benchmarks/run.sh` runs the timers.
Expand Down Expand Up @@ -83,7 +83,9 @@ fx 6.80 real 10.38 user 0.54 sys

## Explanation

There are a few good asumtions about why **query-json** is faster, there are just speculations since I didn't profile any of the tools listed here, neither query-json.
There are a few good asumptions about why **query-json** is faster, here there's are speculations. I didn't profile any of the tools listed here, neither query-json.

The main reason is that query-json is compiled to native code with OCaml.

Thoughts about jq:

Expand Down Expand Up @@ -112,4 +114,4 @@ Written in JavaScript
https://github.com/antonmedv/fx

## Please open an issue if you want to see here any jq-like tool
If the queries match 1-to-1 to jq would be cool, otherwise could you add some examples.
If the queries match 1-to-1 to jq would be cool, otherwise could you add some examples.
Loading