Compare commits

..

185 commits

Author SHA1 Message Date
Michiel Borkent
8052618fa8
Fix #1818: wrong argument order in clojure.java.io/resource (#1819)
* Fix #1818: wrong argument order in clojure.java.io/resource

* fix
2025-05-13 11:28:44 +02:00
Michiel Borkent
238a98d9b2
Add java.text.BreakIterator (#1817) 2025-05-07 19:58:37 +02:00
Michiel Borkent
57b799e63d Add odoyle-rules to tested libs 2025-05-07 11:06:22 +02:00
Gert Goet
dad646ce38
Make install-script wget-compatible (#1816) 2025-05-04 10:27:03 +02:00
Michiel Borkent
35696b7c0b Bump edamame 2025-05-03 15:35:58 +02:00
Michiel Borkent
00d56900e8
Bump jsoup to 1.20.1 (#1814) 2025-05-02 16:34:03 +02:00
Michiel Borkent
1fc8ef6adb Bump fs 2025-04-30 14:24:49 +02:00
Michiel Borkent
158b36c645 Version bump 2025-04-26 17:27:17 +02:00
Michiel Borkent
b5c65f46e1 changelogs 2025-04-26 17:27:12 +02:00
Michiel Borkent
7e64ce5dd1 export variable 2025-04-26 17:05:55 +02:00
Michiel Borkent
73b806dbd2 v1.12.200 2025-04-26 16:25:47 +02:00
Michiel Borkent
0579d6a0ec disable bulkhead tests 2025-04-26 13:23:02 +02:00
Michiel Borkent
cfee65101f Bump fusefox 2025-04-26 13:03:00 +02:00
Michiel Borkent
4da643cf63 artifact despite failing tests 2025-04-26 12:47:18 +02:00
Michiel Borkent
aa15e5212a disable flaky tests 2025-04-26 12:39:26 +02:00
Michiel Borkent
e23a222fdb
fusebox tests fixed with SCI interop improvements (#1813) 2025-04-26 12:16:36 +02:00
Michiel Borkent
6c0cfde92f Bump process and fs in print-deps 2025-04-21 12:50:20 +02:00
Michiel Borkent
5f6befc577
Add CachedThreadPool interop test (#1811) 2025-04-19 17:29:38 +02:00
Michiel Borkent
d7b0f9155d Add ConcurrentHashmap 2025-04-19 13:52:02 +02:00
Michiel Borkent
28c2f6947f Add ReentrantLock + ThreadLocalRandom 2025-04-19 13:41:37 +02:00
Michiel Borkent
5c4fb1ccc1 Remove run as lein cmd 2025-04-19 12:47:52 +02:00
Michiel Borkent
5b7678f309
Fix virtual thread builder interop (#1810) 2025-04-19 12:12:56 +02:00
Michiel Borkent
f33c68293b Version bump 2025-04-18 11:46:41 +02:00
Michiel Borkent
fd69206933 v1.12.199 2025-04-18 11:25:51 +02:00
Lee Read
689148b99c
Fix #1806: Add cheshire.factory (#1809)
* add cheshire.factory namespace

This will allow bb users to change jackson factory options when using
cheshire.

Took inspiration from other bb lib impls that dealt with dynamic vars.

Brought over cheshire tests, disabling tests for cheshire/jvm features not
included in bb.

Closes #1806

* turf debug stuff

* turf commented code accidentally left in
2025-04-18 11:10:22 +02:00
Michiel Borkent
3db67a5574 Version bump 2025-04-17 15:09:34 +02:00
Michiel Borkent
8191e09314 v1.12.198 2025-04-17 13:00:04 +02:00
Michiel Borkent
e784f4ae8a
Upgrade babashka.cli and cheshire (#1805) 2025-04-16 14:07:58 +02:00
Michiel Borkent
774fe99a83
Bump core.async to 1.8.741 (#1803) 2025-04-08 11:19:04 +02:00
Wes Morgan
f9aafc9d96
Add java.util.regex.PatternSyntaxException (#1802)
* Add java.util.regex.PatternSyntaxException

...to support com.gfredericks/test.chuck library

* Add java.util.regex.PatternSyntaxException addition to CHANGELOG

---------

Co-authored-by: Michiel Borkent <michielborkent@gmail.com>
2025-04-04 21:04:42 +02:00
Michiel Borkent
4037154a28 changelog 2025-04-03 11:50:45 +02:00
Michiel Borkent
35e904b547
Bump core.async to 1.8.735 (#1795) 2025-04-03 11:46:11 +02:00
Michiel Borkent
08d60112ed Bump edamame, throw on triple colon keyword 2025-03-31 16:05:00 +02:00
Michiel Borkent
a9060f0027 Bump process, fixes memory leak 2025-03-31 15:47:51 +02:00
Michiel Borkent
597f180d32 remove debug 2025-03-19 17:40:33 +01:00
Michiel Borkent
007209c0d2 debug windows 2025-03-19 17:23:26 +01:00
Michiel Borkent
1b2682b67a changelog 2025-03-19 16:41:15 +01:00
Michiel Borkent
4a2a305e38
GraalVM 24 (#1800) 2025-03-19 16:38:17 +01:00
Michiel Borkent
e3908a1306
Merge pull request #1799 from lread/lread/badges
docs: readme: badges: reference bb book
2025-03-17 20:04:10 +01:00
lread
f967e10bdd
docs: readme: badges: reference bb book
Give only a quick summary of bb badges in the README, and reference the new
full description in bb book.

Closes #1798
2025-03-17 10:54:07 -04:00
Michiel Borkent
4c6fe98236 Bump deps 2025-03-11 15:07:16 +01:00
Michiel Borkent
28c7c42c2a
Merge pull request #1797 from babashka/jsoup-upgrade
Jsoup upgrade
2025-03-11 11:24:09 +01:00
Michiel Borkent
6d5fc67467 Bump to main branch 2025-03-11 11:21:13 +01:00
Michiel Borkent
50fc2e2582 Upgrade jsoup 2025-03-10 21:02:02 +01:00
Michiel Borkent
a45f76b029 deps.clj 2025-03-10 20:54:49 +01:00
Michiel Borkent
9ed0507030 fix cache 2025-03-06 17:12:58 +01:00
Michiel Borkent
f9935def7e Bump deps.clj 2025-03-06 17:10:34 +01:00
Michiel Borkent
d053a3c0c5 Bump deps.clj 2025-03-04 10:00:38 +01:00
Michiel Borkent
cdcf9deb1c Bump deps.clj 2025-02-28 14:22:23 +01:00
Michiel Borkent
6f43c47f2a Version bump 2025-02-28 12:23:15 +01:00
Michiel Borkent
63a51ff669 v1.12.197 2025-02-28 11:13:20 +01:00
Michiel Borkent
d7c80012b1 v2024.02.28 2025-02-28 11:02:39 +01:00
Michiel Borkent
eddf51529f changelog 2025-02-18 12:36:44 +01:00
Michiel Borkent
d1dbafc49b Bump fs 2025-02-11 21:21:27 +01:00
Michiel Borkent
bc8cd6d358 Bump deps.clj 2025-02-10 17:04:00 +01:00
Michiel Borkent
b01ee6d87d Fix rewrite-clj tests 2025-02-04 20:18:08 +01:00
Michiel Borkent
a43b55bf5c Fix #1793: bump rewrite-clj to 1.1.49 2025-02-04 19:55:25 +01:00
Michiel Borkent
4358428464 Bump deps.clj 2025-01-28 11:17:25 +01:00
Michiel Borkent
7998e50045
Fix #1791: interop problem on Jsoup form element (#1792) 2025-01-23 14:10:36 +01:00
Michiel Borkent
8d3806a6e7 Bump deps.clj 2025-01-23 11:18:32 +01:00
Michiel Borkent
455728092c sync deps.clj and sci 2025-01-16 15:32:49 +01:00
Michiel Borkent
da3eff0305 Bump fs 2025-01-09 21:08:29 +01:00
Michiel Borkent
51b44ba2ed deps.clj bump 2025-01-05 11:24:36 +01:00
Bob
3cddc33334
Fix #1785: allow subclasses of Throwable to have instance methods called via interop (#1786) 2025-01-01 19:36:28 +01:00
Michiel Borkent
d8521888cc sync deps.clj 2024-12-27 16:21:53 +01:00
Michiel Borkent
1a62a619e3 changelog 2024-12-24 10:41:05 +01:00
Michiel Borkent
ecbdbba8d4 Version bump 2024-12-24 10:40:14 +01:00
Michiel Borkent
e186726fd9 v1.12.196 2024-12-24 10:23:11 +01:00
Michiel Borkent
2a50af8f68 Bump org.babashka/cli 2024-12-23 10:55:01 +01:00
Michiel Borkent
c7a5c6c6bc parameterize graalvm install script 2024-12-22 19:47:43 +01:00
Michiel Borkent
024f1d5515
Fix #1771: *e should contain exception thrown by user (#1784) 2024-12-20 17:20:45 +01:00
Ryan Tate
142e9eae06
Add java.nio.file.attribute.UserDefinedFileAttributeView (#1783) 2024-12-20 14:44:52 +01:00
Michiel Borkent
3d909f04b8 Disable test for Windows 2024-12-20 12:43:33 +01:00
Ryan Tate
c9b9ad64fc
Add java.nio.file.attribute.PosixFileAttributes (#1782)
* Add java.nio.file.attribute.PosixFileAttributes

* Update Changelog
2024-12-20 12:17:08 +01:00
Michiel Borkent
9070db46df changelog 2024-12-19 22:50:03 +01:00
Ian Fernandez
b16ecfdf6c
Add RT iter to babashka (#1781) 2024-12-19 22:46:34 +01:00
Michiel Borkent
1874da1d2d
Bump core.async to 1.7.701 (#1778) 2024-12-18 10:42:55 +01:00
Michiel Borkent
c89ac0bd7f Bump github to macos-13 2024-12-12 10:32:07 +01:00
Michiel Borkent
def5d8fd37 Add java.util.concurrent.CompletionStage 2024-12-12 10:17:48 +01:00
Michiel Borkent
2932d82a65 Bump SCI 2024-12-12 10:17:29 +01:00
Michiel Borkent
d8d6876832 Bump fs 2024-12-04 10:56:06 +01:00
Michiel Borkent
c538d5edbd Bump deps.clj 2024-12-03 11:29:57 +01:00
Michiel Borkent
a5ec09087e Changelogs 2024-12-03 10:34:12 +01:00
Michiel Borkent
5e4ce8e093 Fix java.security interop 2024-12-03 10:31:57 +01:00
Michiel Borkent
c1412f9b31 Add java.security.Signature 2024-12-02 20:20:16 +01:00
Michiel Borkent
f5d7c1bb6e
Add more java.security and javax.crypto classes (#1770)
---------

Signed-off-by: Loukas Agorgianitis <loukas@agorgianitis.com>
Co-authored-by: Loukas Agorgianitis <loukas@agorgianitis.com>
2024-12-02 19:49:12 +01:00
Michiel Borkent
1deae725ae Fix #1768: add taoensso.timbre/color-str 2024-11-29 11:32:19 +01:00
Michiel Borkent
42b9ff8f25 Bump clj-yaml 2024-11-25 12:31:39 +01:00
Michiel Borkent
3442f1e505
move locking to SCI (#1765) 2024-11-24 11:58:27 +01:00
Michiel Borkent
f0943d8a14 Bump deps.clj 2024-11-22 13:14:31 +01:00
Michiel Borkent
dff3b526e9 sync process 2024-11-21 20:42:58 +01:00
Kursat Aktas
afb566f600
Introducing Babashka Guru on Gurubase.io (#1763)
Signed-off-by: Kursat Aktas <kursat.ce@gmail.com>
2024-11-18 20:35:50 +01:00
Michiel Borkent
3cc45ec8a7 sync fs 2024-11-18 18:03:08 +01:00
Michiel Borkent
d670bbb245 Bump babashka.cli 2024-11-18 11:07:29 +01:00
Michiel Borkent
62cab79ce6 Bump SCI which has volatile? 2024-11-16 13:58:49 +01:00
Michiel Borkent
f4292e1038
Fix #1760: expose more stuff for fireworks lib (#1762)
Co-authored-by: Jeremiah Coyle <jcoyle@gmail.com>
2024-11-16 10:47:25 +01:00
Michiel Borkent
286e03ee24 Version bump 2024-11-12 10:17:54 +01:00
Michiel Borkent
cd362fbf01 v1.12.195 2024-11-12 09:52:35 +01:00
Michiel Borkent
ccebfa630f Use safer detection of process command 2024-11-11 22:44:02 +01:00
Michiel Borkent
5ab8b3f975 changelogs 2024-11-11 20:55:10 +01:00
Michiel Borkent
2df2e7661b Bump http-client 2024-11-11 20:52:06 +01:00
Michiel Borkent
7121253f75
Add hickory tests (#1758) 2024-11-11 20:10:46 +01:00
Michiel Borkent
e5dde61ba8 sync SCI 2024-11-11 18:26:02 +01:00
Michiel Borkent
6a5c13a6f8 changelog 2024-11-11 10:58:43 +01:00
Michiel Borkent
b981921a00 changelog 2024-11-11 10:57:58 +01:00
Michiel Borkent
eaf760d62f
Add Jsoup (#1756) 2024-11-11 10:51:14 +01:00
Michiel Borkent
b59bfcb7e6
Upgrade timbre (#1755) 2024-10-30 14:41:46 +01:00
Michiel Borkent
0138990139 sync sci 2024-10-30 11:07:12 +01:00
Michael Glaesemann
5acf04dcf1
Include java.lang.SecurityException (#1753)
* Include java.lang.SecurityException

java.net.http.HttpClient, included in Babashak, can throw java.lang.SecurityException

https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html

* Update Changelog for https://github.com/babashka/babashka/issues/1752
2024-10-24 16:25:55 +02:00
lvh
aabd35eeaa
Document that tests should prefer to hit public APIs (#1751) 2024-10-23 18:07:14 +02:00
Michiel Borkent
ec6a6a5cdb Bump SCI 2024-10-17 12:37:54 +02:00
Michiel Borkent
b19d5f9bff Fix compile script, fixex #1750 2024-10-15 19:00:12 +02:00
Michiel Borkent
5902852ff9
Fix #1748: add clojure.core/ensure (#1749) 2024-10-15 15:08:47 +02:00
Rahuλ Dé
24c644d9f0
[describe] add commit SHA to describe (#1747) 2024-10-13 20:07:04 +02:00
dependabot[bot]
01cb6112f9
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows (#1717)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-12 13:05:43 +02:00
Michiel Borkent
7ff62d91a2 Version bump 2024-10-12 11:49:26 +02:00
Michiel Borkent
89eed2ed44 v1.12.194 2024-10-12 11:30:21 +02:00
Michiel Borkent
ed8aa97d34
GraalVM 23 (#1745) 2024-10-12 11:28:58 +02:00
Michiel Borkent
34b5e71465
Fix #1743: fix fully qualified instance method in call pos. with GraalVM 22 (#1744) 2024-10-12 10:41:45 +02:00
Michiel Borkent
1d5a777b81 Version bump 2024-10-11 15:17:09 +02:00
Michiel Borkent
2519a284f4 changelog 2024-10-11 15:17:00 +02:00
Michiel Borkent
0f9a0fe622 v1.12.193 2024-10-11 14:50:35 +02:00
Michiel Borkent
b6f844ba0c Fix #1741 2024-10-11 14:44:01 +02:00
Michiel Borkent
ab1ee96335 Bump SCI [skip ci] 2024-10-11 14:26:14 +02:00
Michiel Borkent
a535a5faec Bump SCI 2024-10-11 14:20:38 +02:00
Michiel Borkent
4715d13f71 Bump SCI, add note 2024-10-11 12:54:30 +02:00
Michiel Borkent
8b46e030ca use new impl-java 2024-10-10 21:04:48 +02:00
Michiel Borkent
6ca28c642c New impl-java with release 8 2024-10-10 21:04:20 +02:00
Michiel Borkent
c3c2c8b108
Clojure 1.12 IFn coercion 2024-10-10 20:54:29 +02:00
Michiel Borkent
bc1c35790e
Bump SCI: support new Clojure 1.12 interop (#1740) 2024-10-10 14:01:22 +02:00
Michiel Borkent
50e8a74321 Bump SCI 2024-10-06 15:04:34 +02:00
Michiel Borkent
70b3e5c999 Bump ubuntu image in docker 2024-10-02 15:33:30 +02:00
Michiel Borkent
31a5ec5c71
Upgrade machine executor (#1736) 2024-10-02 15:01:54 +02:00
Michiel Borkent
96807375e0 Add tools.reader.edn/read 2024-10-02 14:10:09 +02:00
Michiel Borkent
c402c01861 Bump SCI reflector compiled for java8 2024-10-01 11:08:35 +02:00
Michiel Borkent
08a08ef957 Bump SCI reflector 2024-10-01 11:00:21 +02:00
Michiel Borkent
6a420c9bfd Bump SCI 2024-09-30 21:13:30 +02:00
Michiel Borkent
030d6ba889
SCI issue 928: record constructor + opt. meta + ext map (#1732) 2024-09-30 15:13:36 +02:00
Stephan Renatus
15f5918e58
Dockerfile improvements (#1729) 2024-09-20 13:31:52 +02:00
Michiel Borkent
0c6f8b6806 Version bump 2024-09-12 20:20:50 +02:00
Michiel Borkent
7128d65de7 v1.4.192 2024-09-12 18:46:05 +02:00
Michiel Borkent
2bf95f60e7 Fix #1676: support latest release of at-at lib 2024-09-12 18:43:26 +02:00
Michiel Borkent
0685424ac3 Fix #1707: support aset on primitive array 2024-09-12 18:20:51 +02:00
Michiel Borkent
ecb0fa5cac Fix #1716: expose babashka.http-client.interceptors namespace 2024-09-12 16:48:00 +02:00
Michiel Borkent
e0a303c484
Fix #1719: add new clojure 1.12 clojure.repl.deps namespace (#1724) 2024-09-12 16:41:27 +02:00
Michiel Borkent
5bc1df73af Bump rewrite-clj 2024-09-12 16:30:53 +02:00
Michiel Borkent
ca26b22bf9 changelog 2024-09-11 15:37:30 +02:00
Michiel Borkent
aa566ed15c Bump deps.clj 2024-09-11 15:36:21 +02:00
Michiel Borkent
2492e71dcc clj-yaml v1.0.28 2024-09-10 15:45:18 +02:00
Michiel Borkent
bbf9933941 upload artifact 2024-09-10 10:21:36 +02:00
Michiel Borkent
ea660e956f Bump http-client to 0.4.21 2024-09-10 10:16:58 +02:00
Michiel Borkent
bc413b654b
Fix #1722: add new clojure 1.12 vars (#1723) 2024-09-06 18:37:26 +02:00
Michiel Borkent
a415139b3b
Fix #1720: include clojure.java.process (#1721) 2024-09-06 17:32:16 +02:00
Michiel Borkent
0147195e8c
Clojure 1.12 (#1718) 2024-09-06 14:37:00 +02:00
Michiel Borkent
d226fe785a Bump edamame 2024-08-22 20:23:57 +02:00
Michiel Borkent
2bb865917a README 2024-08-16 15:40:34 +02:00
Michiel Borkent
16eebb60a3 Bump http-client 2024-08-13 14:48:36 +02:00
Michiel Borkent
da9fcbf10d
Add java.io.LineNumberReader (#1714) 2024-08-10 13:32:24 +02:00
Michiel Borkent
cdfc664682 Bump sci 2024-08-09 18:25:56 +02:00
Michiel Borkent
93e398f288 readme 2024-08-06 11:21:39 +02:00
Michiel Borkent
880b4ebe3f Bump deps.clj 2024-08-06 11:21:20 +02:00
Michiel Borkent
366cbed689 changelogs 2024-08-05 12:02:29 +02:00
Michiel Borkent
d17a5342d2 Bump fs 2024-08-05 12:00:56 +02:00
Michiel Borkent
1372b3d8a0 Bump process 2024-07-27 00:15:17 +02:00
Michiel Borkent
b144c81fbb Bump process + SCI 2024-07-26 20:08:47 +02:00
Lee Read
0527f6a372
docs: dev: windows set example misleading (#1713)
The example I provided implied that the set applied only to the next
command. I've learned that this is not the case.

Also: mention what shell examples apply to.
2024-07-26 19:50:40 +02:00
Lee Read
e258358170
Support running of new babashka.process tests (#1711)
Default `BABASHKA_TEST_ENV` to `jvm` for libtests
CI already understands this need, but defaulting in-script avoids
having devs to understand/remember it too.

Alter PATH as required for new babashka.process tests.

In support of babashka/process#163, babashka/process#164
2024-07-26 12:56:47 +02:00
Lee Read
58def24712
docs: dev: windows tips (#1712)
Some extra notes for Windows that I expect will benefit others and also
future-me!
2024-07-26 12:56:34 +02:00
Michiel Borkent
f335fe51ff Bump SCI: detect duplicate keys in dynamic set of map literal 2024-07-23 13:01:12 +02:00
Michiel Borkent
83918c4b80
Fix #1598: use Rosetta on CircleCI to build x64 images (#1708) 2024-06-30 09:28:56 +02:00
Michiel Borkent
2da875c8f9 sync sci 2024-06-29 20:52:16 +02:00
Michiel Borkent
7abd0000c7 Version bump 2024-06-19 14:52:35 +02:00
Michiel Borkent
19804e4bc7 v1.3.191 2024-06-19 14:13:31 +02:00
Michiel Borkent
af3ae5fa79 Changelogs 2024-06-19 11:34:44 +02:00
Michiel Borkent
bf183a33a8
Add bytechannel + more tests (#1706)
Co-authored-by: Jarppe <jarppe@metosin.fi>
2024-06-18 09:08:12 +02:00
Michiel Borkent
616de196f8
Bump bencode (#1703) 2024-06-12 19:15:24 +02:00
Bob
c3c0bf3cef
catch exceptions from resolving symbolic links during bb.edn lookup (#1702) 2024-06-08 20:56:07 +02:00
Michiel Borkent
ea2c3f06ec bump sci 2024-06-06 12:15:50 +02:00
Bob
3068428578
Fix #1696: make transcriptor work (#1699) 2024-05-30 15:11:09 +02:00
Michiel Borkent
702fdf8108 Skip curl test until Alpine has working curl again 2024-05-27 23:01:57 +02:00
Michiel Borkent
7e8e51b882 debug 2024-05-27 22:46:37 +02:00
Michiel Borkent
976d0fcb6d Debug Alpine 2024-05-27 22:12:21 +02:00
Michiel Borkent
c60d139dbf Debug alpine 2024-05-27 20:52:49 +02:00
Bob
116ee1191c
Fix #1686: do not fetch deps/invoke java when deps aren't needed (#1698) 2024-05-27 10:38:27 +02:00
Bob
035a8268ba
Fix #1695: make CLI args available to REPL (#1697) 2024-05-26 11:41:47 +02:00
76 changed files with 3193 additions and 1097 deletions

View file

@ -62,6 +62,7 @@
(let [base-cmd ["docker" "buildx" "build"
"-t" (str image-name ":" image-tag)
"--platform" platform
"--progress" "plain"
"--push"
"-f" docker-file]]
(exec (concat base-cmd label-args ["."]))))
@ -75,6 +76,7 @@
(let [base-cmd ["docker" "buildx" "build"
"-t" (str ghcr-image-name ":" image-tag)
"--platform" platform
"--progress" "plain"
"--push"
"-f" docker-file]]
(exec (concat base-cmd label-args ["."]))))

View file

@ -5,7 +5,7 @@
[clojure.string :as str]
[flatland.ordered.map :refer [ordered-map]]))
(def graalvm-version "22")
(def graalvm-version "24")
(defn run
([cmd-name cmd]
@ -58,7 +58,7 @@
(gen-job
shorted?
(ordered-map
:machine {:image "ubuntu-2004:202111-01"}
:machine {:image "ubuntu-2004:2024.05.1"}
:steps
(gen-steps
shorted?
@ -84,7 +84,8 @@
:BABASHKA_PLATFORM "linux"
:GRAALVM_VERSION graalvm-version
:GRAALVM_HOME graalvm-home
:BABASHKA_TEST_ENV "jvm"}
:BABASHKA_TEST_ENV "jvm"
:BABASHKA_SHA (System/getenv "CIRCLE_SHA1")}
:resource_class "large"
:steps
(gen-steps
@ -100,7 +101,6 @@
"export BABASHKA_FEATURE_JDBC=true
export BABASHKA_FEATURE_POSTGRESQL=true
script/test\nscript/run_lib_tests")
(run "Run as lein command" ".circleci/script/lein")
(run
"Create uberjar"
"mkdir -p /tmp/release
@ -128,7 +128,8 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
"macos"
platform)
:BABASHKA_TEST_ENV "native"
:BABASHKA_XMX "-J-Xmx6500m"}
:BABASHKA_XMX "-J-Xmx6500m"
:BABASHKA_SHA (System/getenv "CIRCLE_SHA1")}
env (if (= "aarch64" arch)
(assoc env :BABASHKA_ARCH arch)
env)
@ -163,6 +164,8 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
(run "Pull Submodules" "git submodule init\ngit submodule update")
{:restore_cache
{:keys [cache-key]}}
(when (= "mac" platform)
(run "Install Rosetta" "sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license"))
(run "Install Clojure" "sudo script/install-clojure")
(when (= "mac" platform)
(run "Install Leiningen" "script/install-leiningen"))
@ -176,10 +179,13 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
(run "Build binary" (if (= "aarch64" arch)
"script/uberjar\nscript/compile -H:PageSize=64K # --pgo=default.iprof"
"script/uberjar\nscript/compile # --pgo=default.iprof") "30m")
(run "Run tests" "script/test\nscript/run_lib_tests")
(run "Release" ".circleci/script/release")
{:persist_to_workspace {:root "/tmp"
:paths ["release"]}}
(run "Run tests" "script/test\nscript/run_lib_tests")
(run "Release + publish"
(str/join "\n" ["export BABASHKA_RELEASE=true"
".circleci/script/release"]))
{:save_cache
{:paths ["~/.m2" "~/graalvm"]
:key cache-key}}
@ -191,8 +197,8 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
(defn make-config
[shorted?]
(let [docker-executor-conf {:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]}
machine-executor-conf {:machine {:image "ubuntu-2004:202111-01"}}
mac-executor-conf {:macos {:xcode "12.5.1"}}
machine-executor-conf {:machine {:image "ubuntu-2004:2024.05.1"}}
mac-executor-conf {:macos {:xcode "13.4.1"}}
linux-graalvm-home (str "/home/circleci/graalvm-" graalvm-version)
mac-graalvm-home (format "/Users/distiller/graalvm-%s/Contents/Home" graalvm-version)]
(ordered-map
@ -211,7 +217,7 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
(unix shorted? true true "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-aarch64-static
(unix shorted? true false "aarch64" machine-executor-conf "arm.large" linux-graalvm-home "linux")
:mac (unix shorted? false false "amd64" mac-executor-conf "macos.x86.medium.gen2" mac-graalvm-home "mac")
:mac (unix shorted? false false "amd64" mac-executor-conf "macos.m1.medium.gen1" mac-graalvm-home "mac")
:deploy (deploy shorted?)
:docker (docker shorted?))
:workflows (ordered-map

View file

@ -29,7 +29,9 @@ tar zcvf "$archive" bb # bbk
cd -
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
if [ "$BABASHKA_RELEASE" = "true" ]; then
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
fi
## cleanup

View file

@ -5,7 +5,7 @@ task:
skip: "changesIncludeOnly('logo/*', '**.md')"
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "22"
GRAALVM_VERSION: "24"
GRAALVM_HOME: ${HOME}/graalvm-${GRAALVM_VERSION}/Contents/Home
BABASHKA_PLATFORM: macos # used in release script
BABASHKA_ARCH: aarch64
@ -24,6 +24,8 @@ task:
sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license
java -version
export BABASHKA_SHA=$(git rev-parse HEAD)
script/uberjar
# curl -sLO 'https://github.com/babashka/pgo-profiles/releases/download/2023.10.11/default.iprof'
script/compile # --pgo=default.iprof

99
.github/workflows/build-windows.yml vendored Normal file
View file

@ -0,0 +1,99 @@
name: build
on:
push:
paths-ignore:
- "**.md"
- "logo/**"
pull_request:
paths-ignore:
- "**.md"
- "logo/**"
# TODO: Add deploy if needed
jobs:
native:
if: "!contains(github.event.head_commit.message, 'skip ci')"
strategy:
matrix:
include:
- os: windows-2022
name: windows
static: false
runs-on: ${{ matrix.os }}
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "24"
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
BABASHKA_TEST_ENV: native
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
with:
fetch-depth: 1
submodules: 'true'
- name: Cache deps
uses: actions/cache@v4
id: cache-deps
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('project.clj') }}
restore-keys: ${{ runner.os }}-maven-
- name: Setup GraalVM
if: "matrix.static == false"
uses: graalvm/setup-graalvm@v1.3.3
with:
java-version: '24'
distribution: 'graalvm'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install clojure tools
uses: DeLaGuardo/setup-clojure@13.2
with:
cli: latest
# lein: latest -- skipped because this uses some PS bullshit
- name: Babashka version
id: babashka-version
shell: bash
run: |
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- name: Build
shell: cmd
run: |
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat', 'lein.bat')"
call lein self-install
set GRAALVM_HOME=%JAVA_HOME%
call script/uberjar.bat
call script/compile.bat
echo Creating zip archive
set zip=babashka-%BABASHKA_VERSION%-windows-amd64.zip
jar -cMf %zip% bb.exe
bb --config .build/bb.edn --deps-root . release-artifact %zip%
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
path: bb.exe
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Test binary and libs
shell: cmd
run: |
set BABASHKA_CLASSPATH=
set BABASHKA_TEST_ENV=native
call script/test.bat :windows
call script/run_lib_tests.bat

View file

@ -24,6 +24,7 @@ jobs:
LEIN_ROOT: "true"
BABASHKA_PLATFORM: linux # could be used in jar name
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
@ -32,7 +33,7 @@ jobs:
submodules: 'true'
- name: Cache deps
uses: actions/cache@v2
uses: actions/cache@v4
id: cache-deps
with:
path: ~/.m2/repository
@ -59,9 +60,6 @@ jobs:
script/test
script/run_lib_tests
- name: Run as lein command
run: echo '{:a 1}' | lein bb '(:a *in*)'
- name: Build uberjar
run: |
mkdir -p /tmp/release
@ -80,7 +78,7 @@ jobs:
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v4
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-standalone.jar
path: target/babashka-${{ steps.babashka-version.outputs.version }}-standalone.jar
@ -90,7 +88,7 @@ jobs:
strategy:
matrix:
include:
- os: macos-12
- os: macos-13
name: macos
static: false
#- os: ubuntu-latest
@ -102,11 +100,12 @@ jobs:
runs-on: ${{ matrix.os }}
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "22"
GRAALVM_VERSION: "24"
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
BABASHKA_TEST_ENV: native
BABASHKA_XMX: "-J-Xmx6500m"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
@ -115,7 +114,7 @@ jobs:
submodules: 'true'
- name: Cache deps
uses: actions/cache@v2
uses: actions/cache@v4
id: cache-deps
with:
path: ~/.m2/repository
@ -126,7 +125,7 @@ jobs:
if: "matrix.static == false"
uses: graalvm/setup-graalvm@v1
with:
java-version: '22'
java-version: '24'
distribution: 'graalvm'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
@ -135,7 +134,7 @@ jobs:
if: "matrix.static == true"
uses: graalvm/setup-graalvm@v1
with:
version: '22'
version: '24'
distribution: 'graalvm'
components: 'native-image'
native-image-musl: true
@ -173,6 +172,19 @@ jobs:
BABASHKA_MUSL: "true"
run: script/compile
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Upload static artifact
if: "matrix.static == true"
uses: actions/upload-artifact@v4
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-static-amd64
- name: Test binary and libs
run: |
script/test
@ -181,19 +193,6 @@ jobs:
- name: Release
run: .circleci/script/release
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Upload static artifact
if: "matrix.static == true"
uses: actions/upload-artifact@v2
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-static-amd64
docker:
if: ${{ false }} # Disabled
# if: "!contains(github.event.head_commit.message, 'skip ci') && github.event_name == 'push' && github.ref == 'refs/heads/master'"
@ -217,13 +216,13 @@ jobs:
run: mkdir -p /tmp/release
- name: Download linux binary
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4.1.7
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-linux-amd64.zip
path: /tmp/release
- name: Download static linux binary
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4.1.7
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-linux-static-amd64.zip
path: /tmp/release-static

1
.gitignore vendored
View file

@ -38,3 +38,4 @@ target
.DS_Store
.portal
default.iprof
scratch.clj

View file

@ -9,9 +9,162 @@ A preview of the next release can be installed from
## Unreleased
- Fix [#1688](https://github.com/babashka/babashka/issues/1688): use-fixtures should add metadata to `*ns*`
- Fix [#1692](https://github.com/babashka/babashka/issues/1692): Add support for ITransientSet and org.flatland/ordered-set
- [#1818](https://github.com/babashka/babashka/issues/1818): wrong argument order in `clojure.java.io/resource` implementation
- Add `java.text.BreakIterator`
- Bump `fs` to `0.5.25`
- Bump `jsoup` to `1.20.1`
- Bump `edamame` to `1.4.30`
- [#1815](https://github.com/babashka/babashka/issues/1815): Make install-script wget-compatible ([@eval](https://github.com/eval))
## 1.12.200 (2025-04-26)
- Improve Java reflection based on provided type hints (read blog post [here](https://blog.michielborkent.nl/babashka-java-reflection-type-hints.html))
- Add compatibility with the [fusebox](https://github.com/potetm/fusebox) library
- Fix virtual `ThreadBuilder` interop
- Add `java.util.concurrent.ThreadLocalRandom`
- Add `java.util.concurrent.locks.ReentrantLock`
- Add classes:
- `java.time.chrono.ChronoLocalDate`
- `java.time.temporal.TemporalUnit`
- `java.time.chrono.ChronoLocalDateTime`
- `java.time.chrono.ChronoZonedDateTime`
- `java.time.chrono.Chronology`
## 1.12.199 (2025-04-18)
- [#1806](https://github.com/babashka/babashka/issues/1806): Add `cheshire.factory` namespace ([@lread](https://github.com/lread))
## 1.12.198 (2025-04-17)
- Bump GraalVM to `24`
- Bump SCI to `0.9.45`
- Bump edamame to `1.4.28`
- [#1801](https://github.com/babashka/babashka/issues/1801): Add `java.util.regex.PatternSyntaxException`
- Bump core.async to `1.8.735`
- Bump cheshire to `6.0.0`
- Bump babashka.cli to `0.8.65`
## 1.12.197 (2025-02-28)
- [#1785](https://github.com/babashka/babashka/issues/1785): Allow subclasses of `Throwable` to have instance methods invoked ([@bobisageek](https://github.com/bobisageek))
- [#1791](https://github.com/babashka/babashka/issues/1791): interop problem on Jsoup form element
- [#1793](https://github.com/babashka/babashka/issues/1793): Bump `rewrite-clj` to `1.1.49` (fixes parsing of `foo//` among other things)
- Bump `deps.clj`
- Bump `fs`
## 1.12.196 (2024-12-24)
- [#1771](https://github.com/babashka/babashka/issues/1771): `*e*` in REPL should contain exception thrown by user, not a wrapped one
- [#1777](https://github.com/babashka/babashka/issues/1777) Add `java.nio.file.attribute.UserDefinedFileAttributeView`
- [#1776](https://github.com/babashka/babashka/issues/1776) `Add java.nio.file.attribute.PosixFileAttributes`
- [#1761](https://github.com/babashka/babashka/issues/1761) Support calling `clojure.lang.RT/iter`
- [#1760](https://github.com/babashka/babashka/issues/1760) For compatibility with [Fireworks v0.10.3](https://github.com/paintparty/fireworks), added the following to `:instance-checks` entry in `babashka.impl.classes/classes`([@paintparty](https://github.com/paintparty))
- `clojure.lang.PersistentArrayMap$TransientArrayMap`
- `clojure.lang.PersistentHashMap$TransientHashMap`
- `clojure.lang.PersistentVector$TransientVector`
- `java.lang.NoSuchFieldException`
- `java.util.AbstractMap`
- `java.util.AbstractSet`
- `java.util.AbstractList`
- [#1760](https://github.com/babashka/babashka/issues/1760) For compatibility with [Fireworks v0.10.3](https://github.com/paintparty/fireworks), added `volatile?` entry to `babashka.impl.clojure.core/core-extras`([@paintparty](https://github.com/paintparty))
- Bump `babashka.cli` to `0.8.61`
- Bump `clj-yaml` to `1.0.29`
- [#1768](https://github.com/babashka/babashka/issues/1768): Add `taoensso.timbre` `color-str` function
- Add classes:
- `javax.crypto.KeyAgreement`
- `java.security.KeyPairGenerator`
- `java.security.KeyPair`
- `java.security.spec.ECGenParameterSpec`
- `java.security.spec.PKCS8EncodedKeySpec`
- `java.security.spec.X509EncodedKeySpec`
- `java.security.Signature`
- Add `java.util.concurrent.CompletionStage`
- Bump `core.async` to `1.7.701`
- Bump `org.babashka/cli` to `0.8.162`
## 1.12.195 (2024-11-12)
- Include [jsoup](https://jsoup.org/) for HTML parsing. This makes bb compatible with the [hickory](https://github.com/clj-commons/hickory) library (and possibly other libraries?).
- [#1752](https://github.com/babashka/babashka/issues/1752): include `java.lang.SecurityException` for `java.net.http.HttpClient` support ([@grzm](https://github.com/grzm))
- [#1748](https://github.com/babashka/babashka/issues/1748): add `clojure.core/ensure`
- Upgrade `taoensso/timbre`to `v6.6.0`
- Upgrade `babashka.http-client` to `v0.4.22`
- Add `:git/sha` from build to `bb describe` output ([@lispyclouds](https://github.com/lispyclouds))
- Fix NPE with determining if executing from self-contained executable
## 1.12.194 (2024-10-12)
- Upgrade to GraalVM 23
- [#1743](https://github.com/babashka/babashka/issues/1743): fix new fully qualified instance method in call position with GraalVM 23
## 1.12.193 (2024-10-11)
- Clojure 1.12 interop: method thunks, FI coercion, array notation (see below)
- Upgrade SCI reflector based on clojure 1.12 and remove specific workaround for
`Thread/sleep` interop
- Add `tools.reader.edn/read`
- Fix [#1741](https://github.com/babashka/babashka/issues/1741): `(taoensso.timbre/spy)` now relies on macros from `taoensso.encore` previously not available in bb
Examples of the new Clojure interop:
``` clojure
;; Qualified methods in call position:
(String/.length "123") ;;=> 3
(String/new "123") ;;=> "123"
;; Qualified methods in value position, as functions:
(map Integer/parseInt ["1" "22" "333"]) ;;=> (1 22 333)
(map String/.length ["1" "22" "333"]) ;;=> (1 2 3)
(map String/new ["1" "22" "333"]) ;;=> ("1" "22" "333")
;; Typed multi-dimensional array class notation:
long/1 ;;=> 1-dimensional long array class
String/2 ;;=> 2-dimensional String array class
;; Pass Clojure IFn to Java where `java.util.function.Predicate`, etc. is expected:
(into [] (doto (java.util.ArrayList. [1 2 3]) (.removeIf even?))) ;;=> [1 3]
(.computeIfAbsent (java.util.HashMap.) "abc" #(str % %)) ;;=> "abcabc"
```
## 1.4.192 (2024-09-12)
- Upgrade Clojure to `1.12.0`
- [#1722](https://github.com/babashka/babashka/issues/1722): add new clojure 1.12 vars
- [#1720](https://github.com/babashka/babashka/issues/1720): include new clojure 1.12's `clojure.java.process`
- [#1719](https://github.com/babashka/babashka/issues/1719): add new clojure 1.12 `clojure.repl.deps` namespace. Only calls with explicit versions are supported.
- [#1598](https://github.com/babashka/babashka/issues/1598): use Rosetta on CircleCI to build x64 images
- [#1716](https://github.com/babashka/babashka/issues/1716): expose `babashka.http-client.interceptors` namespace
- [#1707](https://github.com/babashka/babashka/issues/1707): support `aset` on primitive array
- [#1676](https://github.com/babashka/babashka/issues/1676): restore compatibility with newest [at-at](https://github.com/overtone/at-at/) version (1.3.58)
- Bump SCI
- Bump `fs`
- Bump `process`
- Bump `deps.clj`
- Bump `http-client`
- Bump `clj-yaml`
- Bump `edamame`
- Bump `rewrite-clj`
- Add `java.io.LineNumberReader`
## 1.3.191 (2024-06-19)
- Fix [#1688](https://github.com/babashka/babashka/issues/1688): `use-fixtures` should add metadata to `*ns*`
- Fix [#1692](https://github.com/babashka/babashka/issues/1692): Add support for `ITransientSet` and `org.flatland/ordered-set`
- Bump org.flatland/ordered to `1.15.12`.
- Partially Fix [#1695](https://github.com/babashka/babashka/issues/1695): `--repl` arg handling should consume only one arg (itself) ([@bobisageek](https://github.com/bobisageek))
- Partially Fix [#1695](https://github.com/babashka/babashka/issues/1695): make `*command-line-args*` value available in the REPL ([@bobisageek](https://github.com/bobisageek))
- Fix [#1686](https://github.com/babashka/babashka/issues/1686): do not fetch dependencies/invoke java for `version`, `help`, and `describe` options ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.lang.DynamicClassLoader` constructors ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.core/*source-path*` (points to the same sci var as `*file*`) ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.main/with-read-known` ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.core.server/repl-read` ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): make the `cognitect-labs/transcriptor` library work ([@bobisageek](https://github.com/bobisageek))
- [#1700](https://github.com/babashka/babashka/issues/1700): catch exceptions from resolving symbolic links during `bb.edn` lookup ([@bobisageek](https://github.com/bobisageek))
- Support `java.nio.channels.ByteChannel` + several other related interop
- Bump `nrepl/bencode` to `1.2.0`
- Bump `babashka/fs`
- Bump `org.babashka/http-client` to `0.4.18`
## 1.3.190 (2024-04-17)

View file

@ -5,7 +5,7 @@ RUN apt update
RUN apt install --no-install-recommends -yy build-essential zlib1g-dev
WORKDIR "/opt"
ENV GRAALVM_VERSION="22"
ENV GRAALVM_VERSION="24"
ARG TARGETARCH
# Do not set those directly, use TARGETARCH instead
ENV BABASHKA_ARCH=
@ -16,9 +16,9 @@ RUN if [ "${TARGETARCH}" = "" ] || [ "${TARGETARCH}" = "amd64" ]; then \
export GRAALVM_ARCH=aarch64; \
fi && \
echo "Installing GraalVM for ${GRAALVM_ARCH}" && \
curl -sLO https://download.oracle.com/graalvm/21/archive/graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz
mkdir "graalvm-$GRAALVM_VERSION"
tar -xzf graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz -C graalvm --strip-components 1
curl -sLO https://download.oracle.com/graalvm/${GRAALVM_VERSION}/archive/graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz && \
mkdir "graalvm-$GRAALVM_VERSION" && \
tar -xzf graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz -C graalvm-$GRAALVM_VERSION --strip-components 1
ARG BABASHKA_XMX="-J-Xmx4500m"

View file

@ -13,7 +13,10 @@ RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswit
# TODO: Run actual native tests when they are ported
RUN bb -e "(curl/get \"https://clojure.org\")" # cURL http test
RUN curl --version
# RUN bb -e '(prn (java.io.File/createTempFile "babashka.curl" ".headers"))'
# RUN bb -e '(spit (java.io.File/createTempFile "babashka.curl" ".headers") "hello")'
# RUN bb -e "(curl/get \"https://clojure.org\")" # cURL http test
RUN bb -e "(require '[org.httpkit.client :as http]) (when-let [error (:error @(http/get \"https://clojure.org\"))] (throw error))" # JVM http test
RUN bb -e "(.length \"Hello, Babashka\")" # Java interop test
RUN bb -e "(require '[babashka.pods :as pods]) (pods/load-pod 'org.babashka/go-sqlite3 \"0.0.1\") (require '[pod.babashka.go-sqlite3 :as sqlite]) (sqlite/execute! \"/tmp/foo.db\" [\"SELECT 1 + 1\"])" # Pod test

114
README.md
View file

@ -4,7 +4,7 @@
[![project chat](https://img.shields.io/badge/slack-join_chat-brightgreen.svg)](https://app.slack.com/client/T03RZGPFR/CLX41ASCS)
[![Financial Contributors on Open Collective](https://opencollective.com/babashka/all/badge.svg?label=financial+contributors)](https://opencollective.com/babashka) [![Clojars Project](https://img.shields.io/clojars/v/babashka/babashka.svg)](https://clojars.org/babashka/babashka)
[![twitter](https://img.shields.io/badge/twitter-%23babashka-blue)](https://twitter.com/search?q=%23babashka&src=typed_query&f=live)
[![docs](https://img.shields.io/badge/website-docs-blue)](https://book.babashka.org)
[![docs](https://img.shields.io/badge/website-docs-blue)](https://book.babashka.org) [![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20Babashka%20Guru-006BFF)](https://gurubase.io/g/babashka)
<blockquote class="twitter-tweet" data-lang="en">
<p lang="en" dir="ltr">Life's too short to remember how to write Bash code. I feel liberated.</p>
@ -40,10 +40,10 @@ As one user described it:
## Quickstart
For installation options check [Installation](https://github.com/babashka/babashka#installation).
For quick installation use:
For quick installation using `bash`, use:
``` shell
$ bash < <(curl -s https://raw.githubusercontent.com/babashka/babashka/master/install)
bash < <(curl -s https://raw.githubusercontent.com/babashka/babashka/master/install)
```
or grab a binary from [Github
@ -53,9 +53,12 @@ anywhere on the path.
Then you're ready to go:
``` shellsession
$ ls | bb -i '(filter fs/directory? *input*)'
("doc" "resources" "sci" "script" "src" "target" "test")
bb took 4ms.
time bb -e '(->> (fs/list-dir ".") (filter fs/directory?) (map fs/normalize) (map str) (take 3))'
```
``` clojure
(".build" "feature-lanterna" ".repl")
bb -e 0,01s user 0,01s system 70% cpu 0,017 total
```
## Support :heart:
@ -120,46 +123,6 @@ by Daniel Higginbotham, who has also helped a lot of people learn Clojure with
[Clojure for the Brave and
True](https://www.braveclojure.com/clojure-for-the-brave-and-true/).
## Examples
Read the output from a shell command as a lazy seq of strings:
``` shell
$ ls | bb -i '(take 2 *input*)'
("CHANGES.md" "Dockerfile")
```
Read EDN from stdin and write the result to stdout:
``` shell
$ bb '(vec (dedupe *input*))' <<< '[1 1 1 1 2]'
[1 2]
```
Read more about `*input*` and in- and output flags
[here](https://book.babashka.org/#_input_and_output_flags).
Execute a script. E.g. print the current time in California using the
`java.time` API:
File `pst.clj`:
``` clojure
#!/usr/bin/env bb
(def now (java.time.ZonedDateTime/now))
(def LA-timezone (java.time.ZoneId/of "America/Los_Angeles"))
(def LA-time (.withZoneSameInstant now LA-timezone))
(def pattern (java.time.format.DateTimeFormatter/ofPattern "HH:mm"))
(println (.format LA-time pattern))
```
``` shell
$ bb pst.clj
05:17
```
More examples can be found [here](examples/README.md).
## Try online
You can try babashka online with Nextjournal's babashka [notebook
@ -269,6 +232,8 @@ Install via the installer script for linux and macOS:
``` shell
$ curl -sLO https://raw.githubusercontent.com/babashka/babashka/master/install
# or
$ wget -qO install https://raw.githubusercontent.com/babashka/babashka/master/install
$ chmod +x install
$ ./install
```
@ -340,63 +305,16 @@ Go [here](https://book.babashka.org/#built-in-namespaces) to see the full list o
A list of projects (scripts, libraries, pods and tools) known to work with babashka.
## Badges
<!-- note to editor: it seems a blank line must appear before code blocks within <details> -->
[![bb compatible](/logo/badge.svg)](https://babashka.org)
The babashka compatible badge indicates that a [library can be used as babashka dependency](doc/projects.md).
[![bb compatible](/logo/badge.svg)](https://book.babashka.org#badges)
The babashka compatible badge indicates that a library can be used as babashka dependency.
If this is the case for your library, we encourage you to proudly display this badge.
<details><summary>Markdown</summary>
```markdown
[![bb compatible](https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg)](https://babashka.org)
```
</details>
<details><summary>AsciiDoc</summary>
```asciidoc
https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg[bb compatible]]
```
</details>
<details><summary>HTML</summary>
```html
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/badge.svg" alt="bb compatible" style="max-width: 100%;"></a>
```
</details>
<br/>
[![bb built-in](/logo/built-in-badge.svg)](https://babashka.org)
The babashka built-in badge means that a [library has been built directly into babashka](https://book.babashka.org/#built-in-namespaces) and requires no extra dependencies to use it.
[![bb built-in](/logo/built-in-badge.svg)](https://book.babashka.org#badges)
The babashka built-in badge means that a library has been built directly into babashka and requires no extra dependencies to use it.
If this rare honor belongs to your library, you should display this badge.
<details><summary>Markdown</summary>
```markdown
[![bb built-in](https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg)](https://babashka.org)
```
</details>
<details><summary>AsciiDoc</summary>
```asciidoc
https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg[bb built-in]]
```
</details>
<details><summary>HTML</summary>
```html
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/built-in-badge.svg" alt="bb built-in" style="max-width: 100%;"></a>
```
</details>
</br>
See [the babashka book for details](https://book.babashka.org#badges).
## Swag

View file

@ -7,8 +7,8 @@ image: Visual Studio 2022
clone_folder: C:\projects\babashka
environment:
GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-jdk-22+36.1
JAVA_HOME: C:\projects\babashka\graalvm\graalvm-jdk-22+36.1
GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-jdk-24+36.1
JAVA_HOME: C:\projects\babashka\graalvm\graalvm-jdk-24+36.1
BABASHKA_XMX: "-J-Xmx5g"
skip_commits:
@ -44,7 +44,7 @@ clone_script:
build_script:
# TODO: Extract the zip by removing the top level folder to remove the hardcoded path for GRAALVM_HOME
- cmd: >-
powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://download.oracle.com/graalvm/22/archive/graalvm-jdk-22_windows-x64_bin.zip', 'graalvm.zip') }"
powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://download.oracle.com/graalvm/24/archive/graalvm-jdk-24_windows-x64_bin.zip', 'graalvm.zip') }"
powershell -Command "if (Test-Path('graalvm')) { return } else { Expand-Archive graalvm.zip graalvm }"
@ -61,6 +61,8 @@ build_script:
# see https://github.com/quarkusio/quarkus/pull/7663
- cmd: >-
set BABASHKA_SHA=%APPVEYOR_REPO_COMMIT%
call script/uberjar.bat
call script/compile.bat

@ -1 +1 @@
Subproject commit aa143f015469884d91f812e16b977ecccdcc2c04
Subproject commit 976cf7b0e54901ada3f7e83f12a4c0aed039adc9

View file

@ -18,23 +18,22 @@
"deps.clj/src" "deps.clj/resources"
"resources" "sci/resources"
"impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.11.2"},
:deps {org.clojure/clojure {:mvn/version "1.12.0"},
org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.java {:mvn/version "0.1.8"}
org.babashka/babashka.impl.java {:mvn/version "0.1.10"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"}
babashka/babashka.core {:local/root "babashka.core"}
borkdude/graal.locking {:mvn/version "0.0.2"},
org.clojure/core.async {:mvn/version "1.6.673"},
org.clojure/core.async {:mvn/version "1.8.741"},
org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "5.13.0"}
cheshire/cheshire {:mvn/version "6.0.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "1.0.27"}
clj-commons/clj-yaml {:mvn/version "1.0.29"}
com.cognitect/transit-clj {:mvn/version "1.0.333"}
org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.1.0"}
nrepl/bencode {:mvn/version "1.2.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
@ -43,16 +42,17 @@
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.47"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.5.0"}
com.taoensso/timbre {:mvn/version "6.6.0"}
org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.8.59"}
org.babashka/http-client {:mvn/version "0.4.18"}
org.flatland/ordered {:mvn/version "1.15.12"}}
org.babashka/cli {:mvn/version "0.8.65"}
org.babashka/http-client {:mvn/version "0.4.22"}
org.flatland/ordered {:mvn/version "1.15.12"}
org.jsoup/jsoup {:mvn/version "1.20.1"}}
:aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]}
:profile
@ -172,7 +172,13 @@
:git/sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6"
:deps/manifest :deps}
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}}
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
:classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}}
:clj-nvd

View file

@ -3,7 +3,7 @@
## Prerequisites
- Install [lein](https://leiningen.org/) for producing uberjars
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *jdk-22*.
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *Oracle GraalVM 24*.
- For Windows, installing Visual Studio 2019 with the "Desktop development
with C++" workload is recommended.
- Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like:

View file

@ -22,6 +22,9 @@ agreement, the PR will be merged.
Each bug fix, change or new feature should be tested well to prevent future
regressions.
If possible, tests should use public APIs. If the bug is in private/internal
code, try to trigger it from a public API.
### Force-push
Please do not use `git push --force` on your PR branch for the following
@ -37,7 +40,7 @@ reasons:
## Requirements
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use jdk-21.0.0.1
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use Oracle GraalVM 24.
## Clone repository
@ -111,6 +114,47 @@ If the library you want to add doesn't work automatically, you can manually do t
Note: If you have to modify any test file or configuration to have it work with
bb, add an inline comment with prefix `BB-TEST-PATCH:` explaining what you did.
## Windows
We have corresponding `.bat` scripts for Windows, examples from a CMD Shell:
```shell
script\test.bat
script\run_lib_tests.bat
set BABASHKA_TEST_ENV=native
script\run_lib_tests.bat
```
### Enable Windows Symbolic Links
You'll need to **enable symbolic links**.
You must do this before you git clone babashka otherwise some tests will fail.
There seems to be many ways to achieve this; I found the following worked from PowerShell:
```shell
Install-Module -Name Carbon -Force
Import-Module Carbon
Grant-CPrivilege -Identity lee -Privilege SeCreateSymbolicLinkPrivilege
```
You'll need to reboot:
```shell
shutdown /r /t 0
```
After reboot, verify the new privilege via:
```shell
whoami /priv
```
Test if you can create a symbolic link via:
```
mklink foofoo barbar
```
> **TIP**: Symbolic links are not supported in some folder-sharing technologies.
For example, if you are running Windows as a VirtualBox guest, sharing babashka
source folders from your host OS will not share the symbolic links as symbolic links.
One solution is to re-clone babashka to a non-shared folder on Windows.
### Git for Windows
Install [Git for Windows](https://gitforwindows.org/).
It includes a version of `cat` that babashka tests currently rely on.
## Build
See [build.md](build.md).

View file

@ -9,6 +9,7 @@ borkdude/missing.test.assertions,https://github.com/borkdude/missing.test.assert
borkdude/rewrite-edn,https://github.com/borkdude/rewrite-edn
camel-snake-kebab/camel-snake-kebab,https://github.com/clj-commons/camel-snake-kebab
cc.qbits/auspex,https://github.com/mpenet/auspex
cheshire/cheshire,https://github.com/dakrone/cheshire
circleci/bond,https://github.com/circleci/bond
cli-matic/cli-matic,https://github.com/l3nz/cli-matic.git
clj-commons/clj-yaml,https://github.com/clj-commons/clj-yaml

1 maven-name git-url
9 borkdude/rewrite-edn https://github.com/borkdude/rewrite-edn
10 camel-snake-kebab/camel-snake-kebab https://github.com/clj-commons/camel-snake-kebab
11 cc.qbits/auspex https://github.com/mpenet/auspex
12 cheshire/cheshire https://github.com/dakrone/cheshire
13 circleci/bond https://github.com/circleci/bond
14 cli-matic/cli-matic https://github.com/l3nz/cli-matic.git
15 clj-commons/clj-yaml https://github.com/clj-commons/clj-yaml

View file

@ -3,9 +3,8 @@
[clojure.tools.logging.impl :as impl]
[clojure.tools.logging.readable]
[sci.core :as sci]
[taoensso.encore :as enc :refer [have]]
[taoensso.timbre :as timbre]
[taoensso.timbre.appenders.core :as appenders]))
[taoensso.encore :as encore :refer [have]]
[taoensso.timbre :as timbre]))
;;;; timbre
@ -14,7 +13,7 @@
(defn- fline [and-form] (:line (meta and-form)))
(defonce callsite-counter
(enc/counter))
(encore/counter))
(defmacro log! ; Public wrapper around `-log!`
"Core low-level log macro. Useful for tooling/library authors, etc.
@ -60,7 +59,9 @@
;; Note pre-resolved expansion
`(taoensso.timbre/-log! ~config ~level ~ns ~file ~line ~column ~msg-type ~?err
(delay ~vargs-form) ~?base-data ~callsite-id ~spying?)))))
(delay ~vargs-form) ~?base-data ~callsite-id ~spying?
~(get opts :instant)
~(get opts :may-log?))))))
([level msg-type args & [opts]]
(let [{:keys [line column]} (merge (meta &form))
@ -114,7 +115,7 @@
:*err* @sci/err
stream)]
(binding [*out* stream]
(enc/println-atomic (force output_)))))}))
(encore/println-atomic (force output_)))))}))
(def default-config (assoc-in timbre/*config* [:appenders :println]
(println-appender {:stream :auto})))
@ -127,7 +128,7 @@
(defn set-level! [level] (swap-config! (fn [m] (assoc m :min-level level))))
(defn merge-config! [m] (swap-config! (fn [old] (enc/nested-merge old m))))
(defn merge-config! [m] (swap-config! (fn [old] (encore/nested-merge old m))))
(defmacro -log-and-rethrow-errors [?line & body]
`(try (do ~@body)
@ -142,7 +143,8 @@
'info 'infof 'warn 'warnf
'error 'errorf
'-log! 'with-level
'spit-appender '-spy 'spy])
'spit-appender '-spy 'spy
'color-str])
'log! (sci/copy-var log! tns)
'*config* config
'swap-config! (sci/copy-var swap-config! tns)
@ -150,7 +152,13 @@
'set-level! (sci/copy-var set-level! tns)
'println-appender (sci/copy-var println-appender tns)
'-log-and-rethrow-errors (sci/copy-var -log-and-rethrow-errors tns)
'-ensure-vec (sci/copy-var enc/ensure-vec tns)))
'-ensure-vec (sci/copy-var encore/ensure-vec tns)))
(def enc-ns (sci/create-ns 'taoensso.encore))
(def encore-namespace
{'catching (sci/copy-var encore/catching enc-ns)
'try* (sci/copy-var encore/try* enc-ns)})
(def timbre-appenders-namespace
(let [tan (sci/create-ns 'taoensso.timbre.appenders.core nil)]
@ -188,7 +196,7 @@
#'clojure.tools.logging/*logger-factory*
(fn [_]
(LoggerFactory.
(enc/memoize (fn [logger-ns] (Logger. (str logger-ns) config))))))
(encore/memoize (fn [logger-ns] (Logger. (str logger-ns) config))))))
(def lns (sci/create-ns 'clojure.tools.logging nil))

2
fs

@ -1 +1 @@
Subproject commit 8658cab4981158dfd439b55b5932a276c4b65bf2
Subproject commit fdd5780bc4df4931332b56082c6c3a5c3c85066d

View file

@ -3,7 +3,7 @@
[clojure.tools.build.api :as b]))
(def lib 'org.babashka/babashka.impl.java)
(def version "0.1.8")
(def version "0.1.10")
(def class-dir "target/classes")
(def basis (b/create-basis {:project "deps.edn"}))
(def jar-file (format "target/%s-%s.jar" (name lib) version))
@ -17,7 +17,8 @@
(defn compile-java [_]
(b/javac {:src-dirs ["src-java"]
:class-dir class-dir
:basis basis}))
:basis basis
:javac-opts ["--release" "8"]}))
(defn jar [_]
(compile-java nil)
@ -26,7 +27,12 @@
:lib lib
:version version
:basis basis
:src-dirs ["src"]})
:src-dirs ["src"]
:pom-data
[[:licenses
[:license
[:name "MIT License"]
[:url "https://opensource.org/license/mit/"]]]]})
(b/copy-dir {:src-dirs ["src"]
:target-dir class-dir})
(b/jar {:class-dir class-dir

View file

@ -2,7 +2,7 @@
:aliases
{:build ;; added by neil
{:paths ["." "build" "src"]
:deps {io.github.clojure/tools.build {:git/tag "v0.8.1" :git/sha "7d40500"}
:deps {io.github.clojure/tools.build {:git/tag "v0.9.6" :git/sha "8e78bcc"}
slipset/deps-deploy {:mvn/version "0.2.0"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
;; insn/insn {:mvn/version "0.5.3"}

View file

@ -1,6 +1,7 @@
(ns babashka.impl.reify2.interfaces)
(def interfaces [java.nio.file.FileVisitor
java.nio.file.DirectoryStream$Filter
java.io.FileFilter
java.io.FilenameFilter
clojure.lang.Associative

36
install
View file

@ -29,6 +29,32 @@ print_help() {
exit 1
}
has() {
command -v "$1" >/dev/null 2>&1
}
fetch() {
local url=$1
local outfile=${2:-}
if has wget; then
if [[ -n $outfile ]]; then
wget -qO "$outfile" "$url"
else
wget -qO - "$url"
fi
elif has curl; then
if [[ -n $outfile ]]; then
curl -fsSL "$url" -o "$outfile"
else
curl -fsSL "$url"
fi
else
>&2 echo "Either 'wget' or 'curl' needs to be on PATH!"
exit 1
fi
}
while [[ $# -gt 0 ]]
do
key="$1"
@ -80,9 +106,9 @@ fi
if [[ "$version" == "" ]]; then
if [[ "$dev_build" == "true" ]]; then
version="$(curl -sL https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_VERSION)"
version="$(fetch https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_VERSION)"
else
version="$(curl -sL https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_RELEASED_VERSION)"
version="$(fetch https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_RELEASED_VERSION)"
fi
fi
@ -144,9 +170,9 @@ download_url="https://github.com/babashka/$repo/releases/download/v$version/$fil
# macOS only have shasum available by default
# Some Linux distros (RHEL-like) only have sha256sum available by default (others have both)
if command -v sha256sum >/dev/null; then
if has sha256sum; then
sha256sum_cmd="sha256sum"
elif command -v shasum >/dev/null; then
elif has shasum; then
sha256sum_cmd="shasum -a 256"
else
>&2 echo "Either 'sha256sum' or 'shasum' needs to be on PATH for '--checksum' flag!"
@ -159,7 +185,7 @@ mkdir -p "$download_dir" && (
cd "$download_dir"
echo -e "Downloading $download_url to $download_dir"
curl -o "$filename" -sL "$download_url"
fetch "$download_url" "$filename"
if [[ -n "$checksum" ]]; then
if ! echo "$checksum *$filename" | $sha256sum_cmd --check --status; then
>&2 echo "Failed checksum on $filename"

@ -1 +1 @@
Subproject commit 7b02584145992832c4a50f4f571b009ff093585d
Subproject commit 2058c79fb63f80ca71917432eddea73e0c58717c

View file

@ -21,28 +21,29 @@
:non-flaky (complement :flaky)
:flaky :flaky}
:jvm-opts ["--enable-preview"]
:dependencies [[org.clojure/clojure "1.11.2"]
[borkdude/edamame "1.4.24"]
[borkdude/graal.locking "0.0.2"]
:dependencies [[org.clojure/clojure "1.12.0"]
[borkdude/edamame "1.4.30"]
[org.clojure/tools.cli "1.0.214"]
[cheshire "5.13.0"]
[nrepl/bencode "1.1.0"]
[borkdude/sci.impl.reflector "0.0.1"]
[cheshire "6.0.0"]
[nrepl/bencode "1.2.0"]
[borkdude/sci.impl.reflector "0.0.4"]
[org.babashka/sci.impl.types "0.0.2"]
[org.babashka/babashka.impl.java "0.1.8"]
[org.clojure/core.async "1.6.673"]
[org.babashka/babashka.impl.java "0.1.10"]
[org.clojure/core.async "1.8.741"]
[org.clojure/test.check "1.1.1"]
[com.github.clj-easy/graal-build-time "0.1.0"]
[rewrite-clj/rewrite-clj "1.1.47"]
[rewrite-clj/rewrite-clj "1.1.49"]
[insn/insn "0.5.2"]
[org.babashka/cli "0.8.59"]
[org.babashka/http-client "0.4.18"]]
[org.babashka/cli "0.8.65"]
[org.babashka/http-client "0.4.22"]
[org.jsoup/jsoup "1.20.1"]
[borkdude/graal.locking "0.0.2"]]
:plugins [[org.kipz/lein-meta-bom "0.1.1"]]
:metabom {:jar-name "metabom.jar"}
:profiles {:feature/xml {:source-paths ["feature-xml"]
:dependencies [[org.clojure/data.xml "0.2.0-alpha8"]]}
:feature/yaml {:source-paths ["feature-yaml"]
:dependencies [[clj-commons/clj-yaml "1.0.27"
:dependencies [[clj-commons/clj-yaml "1.0.29"
:exclusions [org.flatland/ordered]#_#_clj-commons/clj-yaml "0.7.110"]
[org.flatland/ordered "1.15.12"]]}
:feature/jdbc {:source-paths ["feature-jdbc"]
@ -73,7 +74,7 @@
:feature/selmer {:source-paths ["feature-selmer"]
:dependencies [[selmer/selmer "1.12.59"]]}
:feature/logging {:source-paths ["feature-logging"]
:dependencies [[com.taoensso/timbre "6.5.0"]
:dependencies [[com.taoensso/timbre "6.6.0"]
[org.clojure/tools.logging "1.1.0"]]}
:feature/priority-map {:source-paths ["feature-priority-map"]
:dependencies [[org.clojure/data.priority-map "1.1.0"]]}

View file

@ -1 +1 @@
1.3.190
1.12.200

View file

@ -1 +1 @@
1.3.191-SNAPSHOT
1.12.201-SNAPSHOT

View file

@ -18,23 +18,22 @@
"deps.clj/src" "deps.clj/resources"
"resources" "sci/resources"
"impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.11.2"},
:deps {org.clojure/clojure {:mvn/version "1.12.0"},
org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.java {:mvn/version "0.1.8"}
org.babashka/babashka.impl.java {:mvn/version "0.1.10"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"}
babashka/babashka.core {:local/root "babashka.core"}
borkdude/graal.locking {:mvn/version "0.0.2"},
org.clojure/core.async {:mvn/version "1.6.673"},
org.clojure/core.async {:mvn/version "1.8.741"},
org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "5.13.0"}
cheshire/cheshire {:mvn/version "6.0.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "1.0.27"}
clj-commons/clj-yaml {:mvn/version "1.0.29"}
com.cognitect/transit-clj {:mvn/version "1.0.333"}
org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.1.0"}
nrepl/bencode {:mvn/version "1.2.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
@ -43,16 +42,17 @@
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.47"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.5.0"}
com.taoensso/timbre {:mvn/version "6.6.0"}
org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.8.58"}
org.babashka/http-client {:mvn/version "0.4.16"}
org.flatland/ordered {:mvn/version "1.15.12"}}
org.babashka/cli {:mvn/version "0.8.65"}
org.babashka/http-client {:mvn/version "0.4.22"}
org.flatland/ordered {:mvn/version "1.15.12"}
org.jsoup/jsoup {:mvn/version "1.20.1"}}
:aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]}
:profile
@ -172,7 +172,13 @@
:git/sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6"
:deps/manifest :deps}
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}}
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
:classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}}
:clj-nvd

View file

@ -53,4 +53,5 @@ Args=-H:+ReportExceptionStackTraces \
-EBABASHKA_FEATURE_LANTERNA \
-EBABASHKA_FEATURE_SPEC_ALPHA \
-EBABASHKA_FEATURE_RRB_VECTOR \
-EBABASHKA_REQUIRE_SCAN
-EBABASHKA_REQUIRE_SCAN \
-EBABASHKA_SHA

View file

@ -0,0 +1,31 @@
[{
"interfaces": [
"java.util.function.Predicate"
]
},
{
"interfaces": [
"java.util.function.Function"
]
},
{
"interfaces": [
"java.io.FileFilter"
]
},
{
"interfaces": [
"java.nio.file.DirectoryStream$Filter"
]
},
{
"interfaces": [
"java.util.function.Supplier"
]
},
{
"interfaces": [
"java.util.function.UnaryOperator"
]
}
]

View file

@ -0,0 +1,31 @@
(ns clojure.repl.deps
(:require [babashka.deps :as deps]))
(defn add-libs
"Given lib-coords, a map of lib to coord, will resolve all transitive deps for the libs
together and add them to the repl classpath, unlike separate calls to add-lib."
{:added "1.12"}
[lib-coords]
(deps/add-deps {:deps lib-coords})
nil)
(defn add-lib
"Given a lib that is not yet on the repl classpath, make it available by
downloading the library if necessary and adding it to the classloader.
Libs already on the classpath are not updated. Requires a valid parent
DynamicClassLoader.
lib - symbol identifying a library, for Maven: groupId/artifactId
coord - optional map of location information specific to the procurer,
or latest if not supplied
Returns coll of libs loaded, including transitive (or nil if none).
For info on libs, coords, and versions, see:
https://clojure.org/reference/deps_and_cli"
{:added "1.12"}
([lib coord]
(add-libs {lib coord}))
([lib]
(throw (ex-info "add-lib without explicit version isn't supported in babashka (yet)" {:lib lib}))))

2
sci

@ -1 +1 @@
Subproject commit bf6a0f1e00313a902c62c59e440266612725b926
Subproject commit e85433a0214114fdceb4ca896e1b9c27b1bdf713

View file

@ -45,8 +45,8 @@
"appveyor.yml"
"project.clj"
"script/bump_graal_version.clj"
".circleci/script/short_ci.clj"
".cirrus.yml"])
".cirrus.yml"
"script/install-graalvm"])
;; We might have to keep changing these from
;; time to time whenever the version is bumped
@ -54,8 +54,7 @@
;; OR
;;
;; We could have them as environment variables
(def current-graal-version "22.3.1")
(def current-java-version "java19")
(def current-graal-version "24")
(def cl-options
[["-g" "--graal VERSION" "graal version"]
@ -91,19 +90,12 @@
[args]
(when (empty? args)
(display-help))
(let [new-graal-version (:graal args)
new-java-version (:java args)]
(let [new-graal-version (:graal args)]
(when (not (nil? new-graal-version))
(if (is-valid-bump? new-graal-version nil)
(do
(println "Performing Graal bump...")
(bump-current current-graal-version new-graal-version))
(show-error new-graal-version)))
(when (not (nil? new-java-version))
(if (is-valid-bump? new-java-version nil)
(do
(println "Performing Java bump...")
(bump-current current-java-version new-java-version))
(show-error new-java-version)))))
(show-error new-graal-version)))))
(exec-script cl-args)

View file

@ -39,7 +39,7 @@ args=("-jar" "$BABASHKA_JAR"
# "-H:DashboardDump=reports/dump"
# "-H:+DashboardPretty"
# "-H:+DashboardJson"
"-H:ReportAnalysisForbiddenType=java.awt.Toolkit:InHeap,Allocated"
# "-H:ReportAnalysisForbiddenType=java.awt.Toolkit:Instantiated"
"--verbose"
"--no-fallback"
"--native-image-info"
@ -54,13 +54,14 @@ BABASHKA_STATIC=${BABASHKA_STATIC:-}
BABASHKA_MUSL=${BABASHKA_MUSL:-}
if [ "$BABASHKA_STATIC" = "true" ]; then
args+=("--static")
if [ "$BABASHKA_MUSL" = "true" ]; then
args+=("--static")
args+=("--libc=musl"
# see https://github.com/oracle/graal/issues/3398
"-H:CCompilerOption=-Wl,-z,stack-size=2097152")
else
# see https://github.com/oracle/graal/issues/3737
args+=("-H:+UnlockExperimentalVMOptions")
args+=("-H:+StaticExecutableWithDynamicLibC")
fi
fi
@ -106,4 +107,14 @@ then
export BABASHKA_FEATURE_PRIORITY_MAP="${BABASHKA_FEATURE_PRIORITY_MAP:-false}"
fi
if [[ -z "${BABASHKA_SHA:-}" ]]
then
sha=$(git rev-parse HEAD)
if [[ $? -eq 0 ]]; then
export BABASHKA_SHA=$sha
fi
fi
"$GRAALVM_HOME/bin/native-image" "${args[@]}" "$@"
./"$BABASHKA_BINARY" describe

View file

@ -23,6 +23,13 @@ Rem -H:EnableURLProtocols=jar,http,https is also not supported.
call %GRAALVM_HOME%\bin\gu.cmd install native-image
if "%BABASHKA_SHA%"=="" (
for /f %%i in ('git rev-parse HEAD') do set sha=%%i
if not errorlevel 1 (
set BABASHKA_SHA=%sha%
)
)
call %GRAALVM_HOME%\bin\native-image.cmd ^
"-jar" "target/babashka-%BABASHKA_VERSION%-standalone.jar" ^
"-H:Name=bb" ^
@ -39,3 +46,4 @@ call %GRAALVM_HOME%\bin\native-image.cmd ^
if %errorlevel% neq 0 exit /b %errorlevel%
call bb "(+ 1 2 3)"
call bb describe

View file

@ -4,7 +4,7 @@ set -euo pipefail
INSTALL_DIR="${1:-$HOME}"
GRAALVM_VERSION="${GRAALVM_VERSION:-22}"
GRAALVM_VERSION="${GRAALVM_VERSION:-24}"
GRAALVM_PLATFORM=$BABASHKA_PLATFORM
@ -19,7 +19,7 @@ esac
GRAALVM_DIR_NAME="graalvm-$GRAALVM_VERSION"
GRAALVM_FILENAME="graalvm-jdk-${GRAALVM_VERSION}_${GRAALVM_PLATFORM}-${GRAALVM_ARCH}_bin.tar.gz"
DOWNLOAD_URL="https://download.oracle.com/graalvm/22/archive/${GRAALVM_FILENAME}"
DOWNLOAD_URL="https://download.oracle.com/graalvm/${GRAALVM_VERSION}/archive/${GRAALVM_FILENAME}"
pushd "$INSTALL_DIR" >/dev/null

View file

@ -2,12 +2,18 @@
set -eo pipefail
: "${BABASHKA_TEST_ENV:=jvm}"
export BABASHKA_TEST_ENV
if [ "$BABASHKA_TEST_ENV" = "native" ]; then
BB_CMD="./bb"
else
BB_CMD="lein bb"
fi
export PATH
PATH=$(pwd)/process/target/test/on-path:$PATH
export BABASHKA_CLASSPATH
BABASHKA_CLASSPATH=$(clojure -Spath -A:lib-tests)

View file

@ -1,7 +1,11 @@
if not defined BABASHKA_TEST_ENV set BABASHKA_TEST_ENV=jvm
if "%BABASHKA_TEST_ENV%" EQU "native" (set BB_CMD=.\bb) else (set BB_CMD=lein bb)
set EDN=lib_tests.edn
set PATH=%CD%\process\target\test\on-path;%PATH%
.\bb -f script/lib_tests/bb_edn_from_deps.clj %EDN%
%BB_CMD% --config %EDN% --deps-root . -f test-resources/lib_tests/babashka/run_all_libtests.clj %*

View file

@ -175,6 +175,9 @@ else
BABASHKA_LEIN_PROFILES+=",-feature/rrb-vector"
fi
#lein with-profiles "$BABASHKA_LEIN_PROFILES,+reflection,-uberjar" deps :tree
#exit 0
mkdir -p resources/META-INF/babashka
cp deps.edn resources/META-INF/babashka/deps.edn

View file

@ -1,7 +1,8 @@
(ns aaaa-this-has-to-be-first.because-patches
;; we need pprint loaded first, it patches pprint to not bloat the GraalVM binary
(:require [babashka.impl.patches.datafy]
[babashka.impl.pprint]))
[babashka.impl.pprint]
))
;; Enable this for scanning requiring usage:
(def enable-require-scan

View file

@ -1,25 +1,120 @@
(ns babashka.impl.cheshire
{:no-doc true}
(:require [cheshire.core :as json]
[cheshire.factory :as fact]
[sci.core :as sci :refer [copy-var]]))
(def tns (sci/create-ns 'cheshire.core nil))
(def fns (sci/create-ns 'cheshire.factory nil))
(def json-factory (sci/new-dynamic-var '*json-factory* nil {:ns fns}))
;; wrap cheshire fns to support `*json-factory*` dynamic var
(defn generate-string
([obj]
(binding [fact/*json-factory* @json-factory]
(json/generate-string obj)))
([obj opt-map]
(binding [fact/*json-factory* @json-factory]
(json/generate-string obj opt-map))))
(defn generate-stream
([obj writer]
(binding [fact/*json-factory* @json-factory]
(json/generate-stream obj writer)))
([obj writer opt-map]
(binding [fact/*json-factory* @json-factory]
(json/generate-stream obj writer opt-map))))
(defn parse-string
([string]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string string))))
([string key-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string string key-fn))))
([^String string key-fn array-coerce-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string string key-fn array-coerce-fn)))))
(defn parse-string-strict
([string]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string-strict string))))
([string key-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string-strict string key-fn))))
([^String string key-fn array-coerce-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string-strict string key-fn array-coerce-fn)))))
(defn parse-stream
([rdr]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream rdr))))
([rdr key-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream rdr key-fn))))
([rdr key-fn array-coerce-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream rdr key-fn array-coerce-fn)))))
(defn parse-stream-strict
([rdr]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream-strict rdr))))
([rdr key-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream-strict rdr key-fn))))
([rdr key-fn array-coerce-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream-strict rdr key-fn array-coerce-fn)))))
(defn parsed-seq
([reader]
(binding [fact/*json-factory* @json-factory]
(json/parsed-seq reader)))
([reader key-fn]
(binding [fact/*json-factory* @json-factory]
(json/parsed-seq reader key-fn)))
([reader key-fn array-coerce-fn]
(binding [fact/*json-factory* @json-factory]
(json/parsed-seq reader key-fn array-coerce-fn))))
(def cheshire-core-namespace
{'encode (copy-var json/encode tns)
'generate-string (copy-var json/generate-string tns)
'encode-stream (copy-var json/encode-stream tns)
'generate-stream (copy-var json/generate-stream tns)
{'encode (copy-var generate-string tns)
'generate-string (copy-var generate-string tns)
'encode-stream (copy-var generate-stream tns)
'generate-stream (copy-var generate-stream tns)
;;'encode-smile (copy-var json/encode-smile tns)
;;'generate-smile (copy-var json/generate-smile tns)
'decode (copy-var json/decode tns)
'parse-string (copy-var json/parse-string tns)
'parse-string-strict (copy-var json/parse-string-strict tns)
'decode (copy-var parse-string tns)
'parse-string (copy-var parse-string tns)
'parse-string-strict (copy-var parse-string-strict tns)
;;'parse-smile (copy-var json/parse-smile tns)
'parse-stream (copy-var json/parse-stream tns)
'parse-stream-strict (copy-var json/parse-stream-strict tns)
'parsed-seq (copy-var json/parsed-seq tns)
'parse-stream (copy-var parse-stream tns)
'parse-stream-strict (copy-var parse-stream-strict tns)
'parsed-seq (copy-var parsed-seq tns)
;;'parsed-smile-seq (copy-var json/parsed-smile-seq tns)
;;'decode-smile (copy-var json/decode-smile tns)
'default-pretty-print-options (copy-var json/default-pretty-print-options tns)
'create-pretty-printer (copy-var json/create-pretty-printer tns)})
(def cheshire-factory-namespace
{'*json-factory* json-factory
'default-factory-options (copy-var fact/default-factory-options fns)
'json-factory (copy-var fact/json-factory fns)
'make-json-factory (copy-var fact/make-json-factory fns)})

View file

@ -128,6 +128,7 @@
{:methods [{:name "aget"}
{:name "aset"}
{:name "aclone"}
{:name "iter"}
;; we expose this via the Compiler/LOADER dynamic var
{:name "baseLoader"}]}
clojure.lang.Compiler
@ -223,7 +224,9 @@
java.net.http.WebSocket$Listener
java.security.cert.X509Certificate
java.security.cert.CertificateFactory
java.security.Signature
javax.crypto.Cipher
javax.crypto.KeyAgreement
javax.crypto.Mac
javax.crypto.SecretKey
javax.crypto.SecretKeyFactory
@ -252,6 +255,10 @@
jdk.internal.net.http.websocket.BuilderImpl
jdk.internal.net.http.websocket.WebSocketImpl])
(def thread-builder
(try (Class/forName "java.lang.Thread$Builder")
(catch Exception _ nil)))
(def classes
`{:all [clojure.lang.ArityException
clojure.lang.BigInt
@ -276,10 +283,10 @@
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
java.io.LineNumberReader
java.io.RandomAccessFile
java.io.InputStream
java.io.IOException
java.io.LineNumberReader
java.io.OutputStream
java.io.InputStreamReader
java.io.OutputStreamWriter
@ -328,6 +335,7 @@
java.lang.ProcessBuilder$Redirect
java.lang.Runtime
java.lang.RuntimeException
java.lang.SecurityException
java.lang.Short
java.lang.StackTraceElement
java.lang.String
@ -336,6 +344,8 @@
java.lang.Throwable
java.lang.ThreadLocal
java.lang.Thread$UncaughtExceptionHandler
~@(when thread-builder
'[java.lang.Thread$Builder])
java.lang.UnsupportedOperationException
java.lang.ref.WeakReference
java.lang.ref.ReferenceQueue
@ -373,8 +383,12 @@
java.nio.MappedByteBuffer
java.nio.file.OpenOption
java.nio.file.StandardOpenOption
java.nio.channels.ByteChannel
java.nio.channels.Channels
java.nio.channels.FileChannel
java.nio.channels.FileChannel$MapMode
java.nio.channels.ReadableByteChannel
java.nio.channels.WritableByteChannel
java.nio.channels.ServerSocketChannel
java.nio.channels.SocketChannel
java.nio.charset.Charset
@ -390,6 +404,7 @@
java.nio.file.FileVisitOption
java.nio.file.FileVisitResult
java.nio.file.Files
java.nio.file.DirectoryStream$Filter
java.nio.file.LinkOption
java.nio.file.NoSuchFileException
java.nio.file.Path
@ -399,21 +414,28 @@
java.nio.file.attribute.BasicFileAttributes
java.nio.file.attribute.FileAttribute
java.nio.file.attribute.FileTime
java.nio.file.attribute.PosixFileAttributes
java.nio.file.attribute.PosixFilePermission
java.nio.file.attribute.PosixFilePermissions])
java.security.spec.PKCS8EncodedKeySpec
java.security.MessageDigest
java.nio.file.attribute.PosixFilePermissions
java.nio.file.attribute.UserDefinedFileAttributeView])
java.security.DigestInputStream
java.security.Provider
java.security.KeyFactory
java.security.KeyPairGenerator
java.security.KeyPair
java.security.KeyStore
java.security.MessageDigest
java.security.Provider
java.security.SecureRandom
java.security.Security
java.security.spec.ECGenParameterSpec
java.security.spec.PKCS8EncodedKeySpec
java.security.spec.X509EncodedKeySpec
java.sql.Date
java.text.ParseException
java.text.ParsePosition
;; adds about 200kb, same functionality provided by java.time:
java.text.SimpleDateFormat
java.text.BreakIterator
~@(when features/java-time?
`[java.time.format.DateTimeFormatter
java.time.Clock
@ -455,7 +477,12 @@
java.time.temporal.TemporalAccessor
java.time.temporal.TemporalAdjuster
java.time.temporal.TemporalQuery
~(symbol "[Ljava.time.temporal.TemporalQuery;")])
~(symbol "[Ljava.time.temporal.TemporalQuery;")
java.time.chrono.ChronoLocalDate
java.time.temporal.TemporalUnit
java.time.chrono.ChronoLocalDateTime
java.time.chrono.ChronoZonedDateTime
java.time.chrono.Chronology])
java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicReference
@ -485,6 +512,10 @@
java.util.concurrent.CompletableFuture
java.util.concurrent.Executors
java.util.concurrent.TimeUnit
java.util.concurrent.CompletionStage
java.util.concurrent.locks.ReentrantLock
java.util.concurrent.ThreadLocalRandom
java.util.concurrent.ConcurrentHashMap
java.util.jar.Attributes
java.util.jar.Attributes$Name
java.util.jar.JarFile
@ -499,6 +530,7 @@
java.util.Random
java.util.regex.Matcher
java.util.regex.Pattern
java.util.regex.PatternSyntaxException
java.util.ArrayDeque
java.util.ArrayList
java.util.Collections
@ -545,8 +577,6 @@
java.util.zip.ZipFile
sun.misc.Signal
sun.misc.SignalHandler
org.objectweb.asm.Type
java.lang.Void
~(symbol "[B")
~(symbol "[I")
~(symbol "[Ljava.lang.Object;")
@ -562,8 +592,22 @@
~(symbol "[Ljava.util.regex.Pattern;")
~(symbol "[Lclojure.core$range;")])
~@(when features/yaml? '[org.yaml.snakeyaml.error.YAMLException])
~@(when features/hsqldb? '[org.hsqldb.jdbcDriver])]
~@(when features/hsqldb? '[org.hsqldb.jdbcDriver])
org.jsoup.Jsoup
org.jsoup.nodes.Attribute
org.jsoup.nodes.Attributes
org.jsoup.nodes.Comment
org.jsoup.nodes.DataNode
org.jsoup.nodes.Document
org.jsoup.nodes.DocumentType
org.jsoup.nodes.Element
org.jsoup.nodes.Node
org.jsoup.nodes.TextNode
org.jsoup.nodes.XmlDeclaration
org.jsoup.parser.Tag
org.jsoup.parser.Parser]
:constructors [clojure.lang.Delay
clojure.lang.DynamicClassLoader
clojure.lang.LineNumberingPushbackReader
java.io.EOFException]
:methods [borkdude.graal.LockFix] ;; support for locking
@ -586,8 +630,6 @@
clojure.lang.Counted
clojure.lang.Cycle
clojure.lang.IObj
clojure.lang.IType
clojure.lang.IReference
clojure.lang.Fn ;; to distinguish fns from maps, etc.
clojure.lang.IPending
;; clojure.lang.IDeref ;; implemented as protocol in sci
@ -613,7 +655,10 @@
clojure.lang.Named
clojure.lang.Keyword
clojure.lang.PersistentArrayMap
clojure.lang.PersistentArrayMap$TransientArrayMap
clojure.lang.PersistentHashMap$TransientHashMap
clojure.lang.PersistentHashSet
clojure.lang.PersistentHashSet$TransientHashSet
clojure.lang.PersistentList
clojure.lang.PersistentList$EmptyList
clojure.lang.PersistentQueue
@ -621,6 +666,7 @@
clojure.lang.PersistentTreeMap
clojure.lang.PersistentTreeSet
clojure.lang.PersistentVector
clojure.lang.PersistentVector$TransientVector
clojure.lang.Range
clojure.lang.Ratio
clojure.lang.ReaderConditional
@ -639,10 +685,14 @@
java.lang.LinkageError
java.lang.ThreadDeath
java.lang.VirtualMachineError
java.lang.NoSuchFieldException
java.sql.Timestamp
java.util.concurrent.TimeoutException
java.util.Collection
java.util.Map$Entry
java.util.AbstractMap
java.util.AbstractSet
java.util.AbstractList
~@(when features/xml? ['clojure.data.xml.node.Element])]
:custom ~custom-map})
@ -663,25 +713,14 @@
([_# ^String class-name#]
(Class/forName class-name#))
([_# ^String class-name# initialize# ^java.lang.ClassLoader clazz-loader#]
(Class/forName class-name#)))})
(= 'java.lang.Thread c)
(assoc :static-methods
{(list 'quote 'sleep)
`(fn
([_# x#]
(if (instance? Number x#)
(let [x# (long x#)]
(Thread/sleep x#))
(let [^java.time.Duration x# x#]
(Thread/sleep x#))))
([_# ^java.lang.Long millis# ^java.lang.Long nanos#]
(Thread/sleep millis# nanos#)))}))]]
(Class/forName class-name#)))}))]]
c))
m (assoc m :public-class
(fn [v]
;; (prn :v v)
;; NOTE: a series of instance check, so far, is still cheaper
;; than piggybacking on defmulti or defprotocol
(cond (instance? java.lang.Process v)
(let [res (cond (instance? java.lang.Process v)
java.lang.Process
(instance? java.lang.ProcessHandle v)
java.lang.ProcessHandle
@ -708,6 +747,8 @@
java.nio.file.FileSystem
(instance? java.nio.file.PathMatcher v)
java.nio.file.PathMatcher
(instance? java.util.stream.Stream v)
java.util.stream.Stream
(instance? java.util.stream.IntStream v)
java.util.stream.IntStream
(instance? java.util.stream.BaseStream v)
@ -737,8 +778,12 @@
java.net.URLClassLoader
(instance? java.lang.ClassLoader v)
java.lang.ClassLoader
(instance? java.nio.file.attribute.PosixFileAttributes v)
java.nio.file.attribute.PosixFileAttributes
(instance? java.nio.file.attribute.BasicFileAttributes v)
java.nio.file.attribute.BasicFileAttributes
(instance? java.nio.file.attribute.UserDefinedFileAttributeView v)
java.nio.file.attribute.UserDefinedFileAttributeView
(instance? java.util.concurrent.Future v)
java.util.concurrent.Future
(instance? java.util.concurrent.ScheduledExecutorService v)
@ -755,16 +800,37 @@
javax.net.ssl.SSLSocket
(instance? java.lang.Thread v)
java.lang.Thread
(instance? java.util.concurrent.ThreadFactory v)
java.util.concurrent.ThreadFactory
(instance? java.security.cert.X509Certificate v)
java.security.cert.X509Certificate
(instance? java.io.Console v)
java.io.Console
(instance? java.security.KeyPairGenerator v)
java.security.KeyPairGenerator
(instance? java.security.Signature v)
java.security.Signature
(instance? java.security.Key v)
java.security.Key
(instance? java.util.Set v)
java.util.Set
(instance? java.io.Closeable v)
java.io.Closeable
(instance? java.util.Collection v)
java.util.Collection
(instance? java.lang.Throwable v)
java.lang.Throwable
(instance? org.jsoup.nodes.Element v)
org.jsoup.nodes.Element
(and thread-builder
(instance? thread-builder v))
thread-builder
(instance? java.text.BreakIterator v)
java.text.BreakIterator
;; keep commas for merge friendliness
)))
,)]
;; (prn :res res)
res)))
m (assoc m (list 'quote 'clojure.lang.Var) 'sci.lang.Var)
m (assoc m (list 'quote 'clojure.lang.Namespace) 'sci.lang.Namespace)]
m))
@ -816,6 +882,8 @@
Integer java.lang.Integer
InterruptedException java.lang.InterruptedException
Iterable java.lang.Iterable
;; NOTE: in hindsight File never belonged to the default imports of Clojure,
;; but it's been here to long to remove probably
File java.io.File
Float java.lang.Float
Long java.lang.Long
@ -830,6 +898,7 @@
RuntimeException java.lang.RuntimeException
Process java.lang.Process
ProcessBuilder java.lang.ProcessBuilder
SecurityException java.lang.SecurityException
Short java.lang.Short
StackTraceElement java.lang.StackTraceElement
String java.lang.String
@ -841,9 +910,9 @@
Throwable java.lang.Throwable
VirtualMachineError java.lang.VirtualMachineError
ThreadDeath java.lang.ThreadDeath
Void java.lang.Void
UnsupportedOperationException java.lang.UnsupportedOperationException
})
UnsupportedOperationException java.lang.UnsupportedOperationException})
;; (eval (vec (keys imports)))
(defn reflection-file-entries []
(let [entries (vec (for [c (sort (concat (:all classes)

View file

@ -84,8 +84,8 @@
cp)))
(defn resource
(^URL [path] (resource @the-url-loader path))
(^URL [loader path]
(^URL [path] (resource path @the-url-loader))
(^URL [path loader]
(if (str/starts-with? path "/") nil ;; non-relative paths always return nil
(getResource loader [path] true))))

View file

@ -3,7 +3,6 @@
(:refer-clojure :exclude [future read+string clojure-version with-precision
send-via send send-off sync into-array])
(:require [babashka.impl.common :as common]
[borkdude.graal.locking :as locking]
[clojure.core :as c]
[clojure.string :as str]
[sci.core :as sci]
@ -12,9 +11,6 @@
[sci.impl.utils :refer [clojure-core-ns]]
[sci.impl.vars :as vars]))
(defn locking* [form bindings v f & args]
(apply @#'locking/locking form bindings v f args))
(defn core-dynamic-var
([sym] (core-dynamic-var sym nil))
([sym init-val] (sci/new-dynamic-var sym init-val {:ns clojure-core-ns})))
@ -27,6 +23,7 @@
(def math-context (core-dynamic-var '*math-context*))
(def compile-path (core-dynamic-var '*compile-path* *compile-path*))
(def compiler-options (core-dynamic-var '*compiler-options*))
(def repl (core-dynamic-var '*repl* true)) ;; set to true, basically just a dummy for now
(defn read+string
"Added for compatibility. Must be used with
@ -55,7 +52,7 @@
The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN,
HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP."
[precision & exprs]
(let [[body rm] (if (= (first exprs) :rounding)
(let [[body rm] (if (= :rounding (first exprs))
[(next (next exprs))
`((. java.math.RoundingMode ~(second exprs)))]
[exprs nil])]
@ -121,7 +118,7 @@
:static true}
([aseq]
(try (clojure.lang.RT/seqToTypedArray (seq aseq))
(catch IllegalArgumentException _
(catch Throwable _
(clojure.lang.RT/seqToTypedArray Object (seq aseq)))))
([type aseq]
(clojure.lang.RT/seqToTypedArray type (seq aseq))))
@ -147,7 +144,6 @@
'file-seq (copy-core-var file-seq)
'promise (copy-core-var promise)
'deliver (copy-core-var deliver)
'locking (macrofy 'locking locking*)
'shutdown-agents (copy-core-var shutdown-agents)
'slurp (copy-core-var slurp)
'spit (copy-core-var spit)
@ -167,6 +163,7 @@
'*math-context* math-context
'*compiler-options* compiler-options
'*compile-path* compile-path
'*source-path* sci/file
'with-precision (sci/copy-var with-precision clojure-core-ns)
'-with-precision (sci/copy-var -with-precision clojure-core-ns)
;; STM
@ -177,6 +174,8 @@
'sync (sci/copy-var sync clojure-core-ns)
'ref (sci/copy-var ref clojure-core-ns)
'ref-set (sci/copy-var ref-set clojure-core-ns)
'ensure (sci/copy-var ensure clojure-core-ns)
;; end STM
'update-vals (sci/copy-var update-vals clojure-core-ns)
'update-keys (sci/copy-var update-keys clojure-core-ns)
'parse-boolean (sci/copy-var parse-boolean clojure-core-ns)
@ -195,5 +194,14 @@
'PrintWriter-on (sci/copy-var PrintWriter-on clojure-core-ns)
'set-agent-send-executor! (sci/copy-var set-agent-send-executor! clojure-core-ns)
'set-agent-send-off-executor! (sci/copy-var set-agent-send-off-executor! clojure-core-ns)
;; 1.12
'splitv-at (sci/copy-var splitv-at clojure-core-ns)
'stream-transduce! (sci/copy-var stream-transduce! clojure-core-ns)
'partitionv (sci/copy-var partitionv clojure-core-ns)
'stream-into! (sci/copy-var stream-into! clojure-core-ns)
'stream-reduce! (sci/copy-var stream-reduce! clojure-core-ns)
'stream-seq! (sci/copy-var stream-seq! clojure-core-ns)
'partitionv-all (sci/copy-var partitionv-all clojure-core-ns)
'*repl* repl
}
)

View file

@ -2,13 +2,39 @@
{:no-doc true}
(:require [clojure.core.async :as async]
[clojure.core.async.impl.protocols :as protocols]
[clojure.core.async.impl.dispatch :as dispatch]
[sci.core :as sci :refer [copy-var]]
[sci.impl.copy-vars :refer [macrofy]]
[sci.impl.vars :as vars]))
[sci.impl.vars :as vars])
(:import [java.util.concurrent Executors ExecutorService ThreadFactory]))
(set! *warn-on-reflection* true)
(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
#_(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
(def executor-for
"Given a workload tag, returns an ExecutorService instance and memoizes the result. By
default, core.async will defer to a user factory (if provided via sys prop) or construct
a specialized ExecutorService instance for each tag :io, :compute, and :mixed. When
given the tag :core-async-dispatch it will default to the executor service for :io."
(memoize
(fn ^ExecutorService [workload]
(let [sysprop-factory nil #_(when-let [esf (System/getProperty "clojure.core.async.executor-factory")]
(requiring-resolve (symbol esf)))
sp-exec (and sysprop-factory (sysprop-factory workload))]
(or sp-exec
(if (= workload :core-async-dispatch)
(executor-for :io)
(@#'dispatch/create-default-executor workload)))))))
(alter-var-root #'dispatch/executor-for (constantly executor-for))
#_#_(defn exec
[^Runnable r workload]
(prn :r r :w workload)
(let [^ExecutorService e (executor-for workload)]
(.execute e r)))
(alter-var-root #'dispatch/exec (constantly exec))
(def ^java.util.concurrent.Executor virtual-executor
(try (eval '(java.util.concurrent.Executors/newVirtualThreadPerTaskExecutor))
@ -17,20 +43,25 @@
(defn thread-call
"Executes f in another thread, returning immediately to the calling
thread. Returns a channel which will receive the result of calling
f when completed, then close."
[f]
(let [c (async/chan 1)]
(let [binds (vars/get-thread-binding-frame)]
(.execute executor
(fn []
(vars/reset-thread-binding-frame binds)
(try
(let [ret (f)]
(when-not (nil? ret)
(async/>!! c ret)))
(finally
(async/close! c))))))
c))
f when completed, then close. workload is a keyword that describes
the work performed by f, where:
:io - may do blocking I/O but must not do extended computation
:compute - must not ever block
:mixed - anything else (default)
when workload not supplied, defaults to :mixed"
([f] (thread-call f :mixed))
([f workload]
(let [c (async/chan 1)
returning-to-chan (fn [bf]
#(try
(when-some [ret (bf)]
(async/>!! c ret))
(finally (async/close! c))))
f (vars/binding-conveyor-fn f)]
(-> f #_bound-fn* returning-to-chan (dispatch/exec workload))
c)))
(defn -vthread-call
"Executes f in another virtual thread, returning immediately to the calling
@ -38,21 +69,23 @@
f when completed, then close."
[f]
(let [c (async/chan 1)]
(let [binds (vars/get-thread-binding-frame)]
(let [returning-to-chan (fn [bf]
#(try
(when-some [ret (bf)]
(async/>!! c ret))
(finally (async/close! c))))
f (vars/binding-conveyor-fn f)]
(.execute virtual-executor
(fn []
(vars/reset-thread-binding-frame binds)
(try
(let [ret (f)]
(when-not (nil? ret)
(async/>!! c ret)))
(finally
(async/close! c))))))
(-> f returning-to-chan)))
c))
(defn thread
[_ _ & body]
`(~'clojure.core.async/thread-call (fn [] ~@body)))
`(~'clojure.core.async/thread-call (fn [] ~@body) :mixed))
(defn io-thread
[_ _ & body]
`(~'clojure.core.async/thread-call (fn [] ~@body) :io))
(defn -vthread
[_ _ & body]
@ -128,6 +161,7 @@
'take! (copy-var async/take! core-async-namespace)
'tap (copy-var async/tap core-async-namespace)
'thread (macrofy 'thread thread core-async-namespace)
'io-thread (macrofy 'io-thread io-thread core-async-namespace)
'thread-call (copy-var thread-call core-async-namespace)
'-vthread-call (copy-var -vthread-call core-async-namespace)
'timeout (copy-var timeout core-async-namespace)

View file

@ -0,0 +1,6 @@
(ns babashka.impl.clojure.java.process
(:require [clojure.java.process]
[sci.core :as sci]))
(def cjp (sci/create-ns 'clojure.java.process nil))
(def cjp-namespace (sci/copy-ns clojure.java.process cjp))

View file

@ -55,6 +55,13 @@ by default when a new command-line REPL is started."} repl-requires
'[[clojure.repl :refer (source apropos pst dir doc find-doc)]
[clojure.pprint :refer (pp pprint)]])
(defmacro with-read-known
"Evaluates body with *read-eval* set to a \"known\" value,
i.e. substituting true for :unknown if necessary."
[& body]
`(binding [*read-eval* (if (= :unknown *read-eval*) true *read-eval*)]
~@body))
(defn repl
"Generic, reusable, read-eval-print loop. By default, reads from *in*,
writes to *out*, and prints exception summaries to *err*. If you use the
@ -111,8 +118,9 @@ by default when a new command-line REPL is started."} repl-requires
:file "<repl>"
:type :sci/error) e)))))))
(catch Throwable e
(let [e' (ex-cause e)]
(caught e)
(set! *e e))))]
(set! *e e')))))]
(with-bindings
(try
(init)

View file

@ -3,12 +3,14 @@
[clojure.tools.reader.reader-types :as rt]
[sci.core :as sci]))
(def edn-namespace {'read-string (sci/copy-var edn/read-string (sci/create-ns 'clojure.tools.reader.edn))})
(def tr-edn-ns (sci/create-ns 'clojure.tools.reader.edn))
(def edn-namespace {'read-string (sci/copy-var edn/read-string tr-edn-ns)
'read (sci/copy-var edn/read tr-edn-ns)})
(def rtns (sci/create-ns 'clojure.tools.reader.reader-types))
(def reader-types-namespace {'indexing-reader? (sci/copy-var rt/indexing-reader? rtns)
'indexing-push-back-reader (sci/copy-var rt/indexing-push-back-reader rtns)
'get-line-number (sci/copy-var rt/get-line-number rtns)
'get-column-number (sci/copy-var rt/get-column-number rtns)
'peek-char (sci/copy-var rt/peek-char rtns)

View file

@ -1,11 +1,13 @@
(ns babashka.impl.http-client
(:require
[babashka.http-client]
[babashka.http-client.interceptors]
[babashka.http-client.websocket]
[sci.core :as sci]))
(def hns (sci/create-ns 'babashka.http-client))
(def wns (sci/create-ns 'babashka.http-client.websocket))
(def ins (sci/create-ns 'babashka.http-client.interceptors))
(def http-client-namespace
(sci/copy-ns babashka.http-client hns))
@ -13,3 +15,5 @@
(def http-client-websocket-namespace
(sci/copy-ns babashka.http-client.websocket wns))
(def http-client-interceptors-namespace
(sci/copy-ns babashka.http-client.interceptors ins))

View file

@ -2,7 +2,8 @@
{:no-doc true}
(:require [clojure.pprint :as pprint]
[sci.core :as sci]
[sci.pprint]))
[sci.pprint]
[babashka.impl.clojure.core.async]))
(defonce patched? (volatile! false))

View file

@ -14,11 +14,11 @@
edn/read-string)
deps (:deps deps)
deps (assoc deps
'babashka/fs {:mvn/version "0.4.19"}
'babashka/fs {:mvn/version "0.5.25"}
'babashka/babashka.curl {:mvn/version "0.1.2"}
'babashka/babashka.core {:git/url "https://github.com/babashka/babashka.core"
:git/sha "52a6037bd4b632bffffb04394fb4efd0cdab6b1e"}
'babashka/process {:mvn/version "0.5.21"})
'babashka/process {:mvn/version "0.6.23"})
deps (dissoc deps
'borkdude/sci
'org.babashka/sci

View file

@ -79,6 +79,18 @@
(handle [sig]
((method-or-bust methods 'handle) this sig)))
["java.io.InputStream" #{}]
(proxy [java.io.InputStream] []
(available [] ((method-or-bust methods 'available) this))
(close [] ((method-or-bust methods 'close) this))
(read
([]
((method-or-bust methods 'read) this))
([bs]
((method-or-bust methods 'read) this bs))
([bs off len]
((method-or-bust methods 'read) this bs off len))))
["java.io.PipedInputStream" #{}]
(proxy [java.io.PipedInputStream] []
(available [] ((method-or-bust methods 'available) this))

View file

@ -187,5 +187,4 @@
sun.misc.SignalHandler
{handle [[this signal]]}
}))

View file

@ -43,9 +43,19 @@
"Inspired by skip-if-eol from clojure.main."
[s]
(let [c (r/read-char s)]
(when-not (= c \newline)
(when-not (= \newline c )
(r/unread s c))))
(defn repl-read [sci-ctx in-stream _request-prompt request-exit]
(if (nil? (r/peek-char in-stream))
request-exit
(let [v (parser/parse-next sci-ctx in-stream)]
(skip-if-eol in-stream)
(if (or (identical? :repl/quit v)
(identical? :repl/exit v))
request-exit
v))))
(defn repl
"REPL with predefined hooks for attachable socket server."
([sci-ctx] (repl sci-ctx nil))
@ -68,15 +78,8 @@
(sio/println))
(eval-form sci-ctx `(apply require (quote ~m/repl-requires)))))
:read (or read
(fn [_request-prompt request-exit]
(if (nil? (r/peek-char in))
request-exit
(let [v (parser/parse-next sci-ctx in)]
(skip-if-eol in)
(if (or (identical? :repl/quit v)
(identical? :repl/exit v))
request-exit
v)))))
(fn [request-prompt request-exit]
(repl-read sci-ctx in request-prompt request-exit)))
:eval (or eval
(fn [expr]
(sci/with-bindings {sci/file "<repl>"

View file

@ -1,6 +1,7 @@
(ns babashka.impl.server
(:require [babashka.impl.clojure.core.server :as server]
[babashka.impl.common :as common]
[babashka.impl.repl :as repl]
[babashka.impl.socket-repl :as socket-repl]
[sci.core :as sci]))
@ -17,9 +18,14 @@
(fn [& args]
(apply server/start-server (common/ctx) args)))
(def repl-read
(fn [& args]
(apply repl/repl-read (common/ctx) @sci/in args)))
(def clojure-core-server-namespace
{'repl (sci/copy-var socket-repl/repl sns)
'prepl (sci/copy-var prepl sns)
'io-prepl (sci/copy-var io-prepl sns)
'start-server (sci/copy-var start-server sns)
'stop-server (sci/copy-var server/stop-server sns)})
'stop-server (sci/copy-var server/stop-server sns)
'repl-read (sci/copy-var repl-read sns)})

View file

@ -10,5 +10,4 @@
'summarize (copy-var tools.cli/summarize cli-ns)
'get-default-options (copy-var tools.cli/get-default-options cli-ns)
'parse-opts (copy-var tools.cli/parse-opts cli-ns)
'make-summary-part (copy-var tools.cli/make-summary-part cli-ns)
'cli (copy-var tools.cli/cli cli-ns)})
'make-summary-part (copy-var tools.cli/make-summary-part cli-ns)})

View file

@ -6,7 +6,7 @@
[babashka.deps :as bdeps]
[babashka.fs :as fs]
[babashka.impl.bencode :refer [bencode-namespace]]
[babashka.impl.cheshire :refer [cheshire-core-namespace]]
[babashka.impl.cheshire :refer [cheshire-core-namespace cheshire-factory-namespace]]
[babashka.impl.classes :as classes :refer [classes-namespace]]
[babashka.impl.classpath :as cp :refer [classpath-namespace]]
[babashka.impl.cli :as cli]
@ -16,6 +16,7 @@
[babashka.impl.clojure.instant :as instant]
[babashka.impl.clojure.java.browse :refer [browse-namespace]]
[babashka.impl.clojure.java.io :refer [io-namespace]]
[babashka.impl.clojure.java.process :refer [cjp-namespace]]
[babashka.impl.clojure.java.shell :refer [shell-namespace]]
[babashka.impl.clojure.main :as clojure-main :refer [demunge]]
[babashka.impl.clojure.math :refer [math-namespace]]
@ -35,7 +36,9 @@
[babashka.impl.error-handler :refer [error-handler]]
[babashka.impl.features :as features]
[babashka.impl.fs :refer [fs-namespace]]
[babashka.impl.http-client :refer [http-client-namespace http-client-websocket-namespace]]
[babashka.impl.http-client :refer [http-client-namespace
http-client-websocket-namespace
http-client-interceptors-namespace]]
[babashka.impl.nrepl-server :refer [nrepl-server-namespace]]
[babashka.impl.pods :as pods]
[babashka.impl.pprint :refer [pprint-namespace]]
@ -107,6 +110,8 @@
(def version common/version)
(def build-commit-sha (or (System/getenv "BABASHKA_SHA") ""))
(defn parse-version [version]
(mapv #(Integer/parseInt %)
(-> version
@ -139,7 +144,7 @@
(binding [*out* *err*]
(apply println msgs)))
(defn print-help [_ctx _command-line-args]
(defn print-help []
(println (str "Babashka v" version))
(println "
Usage: bb [svm-opts] [global-opts] [eval opts] [cmdline args]
@ -215,8 +220,7 @@ Tooling:
File names take precedence over subcommand names.
Remaining arguments are bound to *command-line-args*.
Use -- to separate script command line args from bb command line args.
When no eval opts or subcommand is provided, the implicit subcommand is repl.")
[nil 0])
When no eval opts or subcommand is provided, the implicit subcommand is repl."))
(defn print-doc [ctx command-line-args]
(let [arg (first command-line-args)
@ -259,6 +263,7 @@ Use bb run --help to show this help output.
(format
(str/trim "
{:babashka/version \"%s\"
:git/sha \"%s\"
:feature/csv %s
:feature/java-nio %s
:feature/java-time %s
@ -279,6 +284,7 @@ Use bb run --help to show this help output.
:feature/logging %s
:feature/priority-map %s}")
version
build-commit-sha
features/csv?
features/java-nio?
features/java-time?
@ -358,8 +364,6 @@ Use bb run --help to show this help output.
(def main-var (sci/new-var 'main nil {:ns clojure-main-ns}))
(require '[clojure.reflect] '[clojure.core.memoize :as memoize])
(def namespaces
(cond->
{'user {'*input* (reify
@ -375,6 +379,7 @@ Use bb run --help to show this help output.
'babashka.signal signal-ns
'clojure.java.io io-namespace
'cheshire.core cheshire-core-namespace
'cheshire.factory cheshire-factory-namespace
'clojure.data data/data-namespace
'clojure.instant instant/instant-namespace
'clojure.stacktrace stacktrace-namespace
@ -388,9 +393,11 @@ Use bb run --help to show this help output.
(repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns})
'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns)
'repl-caught (sci/copy-var repl/repl-caught clojure-main-ns)
'with-read-known (sci/copy-var clojure-main/with-read-known clojure-main-ns)
'main main-var}
'clojure.test t/clojure-test-namespace
'clojure.math math-namespace
'clojure.java.process cjp-namespace
'babashka.classpath classpath-namespace
'babashka.classes classes-namespace
'clojure.pprint pprint-namespace
@ -424,7 +431,8 @@ Use bb run --help to show this help output.
'sci.core sci-core-namespace
'babashka.cli cli/cli-namespace
'babashka.http-client http-client-namespace
'babashka.http-client.websocket http-client-websocket-namespace}
'babashka.http-client.websocket http-client-websocket-namespace
'babashka.http-client.interceptors http-client-interceptors-namespace}
features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace)
'clojure.data.xml.event @(resolve 'babashka.impl.xml/xml-event-namespace)
'clojure.data.xml.tree @(resolve 'babashka.impl.xml/xml-tree-namespace))
@ -479,6 +487,7 @@ Use bb run --help to show this help output.
@(resolve 'babashka.impl.selmer/selmer-validator-namespace))
features/logging? (assoc 'taoensso.timbre @(resolve 'babashka.impl.logging/timbre-namespace)
'taoensso.timbre.appenders.core @(resolve 'babashka.impl.logging/timbre-appenders-namespace)
'taoensso.encore @(resolve 'babashka.impl.logging/encore-namespace)
'clojure.tools.logging
@(resolve 'babashka.impl.logging/tools-logging-namespace)
'clojure.tools.logging.impl
@ -486,12 +495,7 @@ Use bb run --help to show this help output.
'clojure.tools.logging.readable
@(resolve 'babashka.impl.logging/tools-logging-readable-namespace))
features/priority-map? (assoc 'clojure.data.priority-map
@(resolve 'babashka.impl.priority-map/priority-map-namespace))
true (assoc 'clojure.reflect {'type-reflect clojure.reflect/type-reflect
'->JavaReflector clojure.reflect/->JavaReflector})
true (assoc 'clojure.core.cache {})
true (assoc 'clojure.core.memoize {'lru memoize/lru
'memo-clear! memoize/memo-clear!})))
@(resolve 'babashka.impl.priority-map/priority-map-namespace))))
(def edn-readers (cond-> {}
features/yaml?
@ -620,7 +624,7 @@ Use bb run --help to show this help output.
:uberjar (first options))))
("--repl")
(let [options (next options)]
(recur (next options)
(recur options
(assoc opts-map
:repl true)))
("--socket-repl")
@ -839,13 +843,12 @@ Use bb run --help to show this help output.
sci/print-length @sci/print-length
;; when adding vars here, also add them to repl.clj and nrepl_server.clj
]
(let [{version-opt :version
:keys [:shell-in :edn-in :shell-out :edn-out
:help :file :command-line-args
(let [{:keys [:shell-in :edn-in :shell-out :edn-out
:file :command-line-args
:expressions :stream? :init
:repl :socket-repl :nrepl
:debug :classpath :force?
:main :uberscript :describe?
:main :uberscript
:jar :uberjar :clojure
:doc :run :list-tasks
:print-deps :prepare]
@ -919,7 +922,7 @@ Use bb run --help to show this help output.
res)))
(let [rps (cp/resource-paths namespace)
rps (mapv #(str "src/babashka/" %) rps)]
(when-let [url (some #(io/resource %) rps)]
(when-let [url (some io/resource rps)]
(let [source (slurp url)]
{:file (str url)
:source source})))
@ -1022,13 +1025,9 @@ Use bb run --help to show this help output.
exit-code
(or exit-code
(second
(cond version-opt
[(print-version) 0]
help (print-help sci-ctx command-line-args)
doc (print-doc sci-ctx command-line-args)
describe?
[(print-describe) 0]
repl [(repl/start-repl! sci-ctx) 0]
(cond doc (print-doc sci-ctx command-line-args)
repl (sci/binding [core/command-line-args command-line-args]
[(repl/start-repl! sci-ctx) 0])
nrepl [(start-nrepl! nrepl) 0]
uberjar [nil 0]
list-tasks [(tasks/list-tasks sci-ctx) 0]
@ -1076,7 +1075,8 @@ Use bb run --help to show this help output.
clojure [nil (if-let [proc (bdeps/clojure command-line-args)]
(-> @proc :exit)
0)]
:else [(repl/start-repl! sci-ctx) 0]))
:else (sci/binding [core/command-line-args command-line-args]
[(repl/start-repl! sci-ctx) 0])))
1)]
(flush)
(when uberscript
@ -1114,6 +1114,15 @@ Use bb run --help to show this help output.
(uberjar/run uber-params))))))
exit-code))))
(defn exec-without-deps [cli-opts]
(let [{version-opt :version
:keys [help describe?]} cli-opts]
(cond
version-opt (print-version)
help (print-help)
describe? (print-describe)))
0)
(defn satisfies-min-version? [min-version]
(let [[major-current minor-current patch-current] version-data
[major-min minor-min patch-min] (parse-version min-version)]
@ -1134,11 +1143,11 @@ Use bb run --help to show this help output.
(defn binary-invoked-as-jar []
(and (= "executable" (System/getProperty "org.graalvm.nativeimage.kind"))
(let [bin (-> (java.lang.ProcessHandle/current)
(when-let [bin (-> (java.lang.ProcessHandle/current)
.info
.command
.get)
fn (fs/file-name bin)]
(.orElse nil))]
(let [fn (fs/file-name bin)]
(if (= "bb" fn)
false
(if (and (fs/windows?)
@ -1147,12 +1156,19 @@ Use bb run --help to show this help output.
(when (try (with-open [_ (java.util.zip.ZipFile. (fs/file bin))])
true
(catch Exception _ false))
bin))))))
bin)))))))
(defn resolve-symbolic-link [f]
(if (and f (fs/exists? f))
(try
(str (fs/real-path f))
(catch Exception _
f))
f))
(defn deps-not-needed [opts]
(let [fast-path-opts [:version :help :describe?]]
(some #(contains? opts %) fast-path-opts)))
(defn main [& args]
(let [bin-jar (binary-invoked-as-jar)
@ -1174,7 +1190,7 @@ Use bb run --help to show this help output.
(println "[babashka] WARNING: config file does not exist:" config))
nil))
jar (let [jar (resolve-symbolic-link jar)]
(some-> [jar] cp/new-loader (cp/resource "META-INF/bb.edn") .toString))
(some->> [jar] cp/new-loader (cp/resource "META-INF/bb.edn") .toString))
:else (if (and file (fs/exists? file))
;; file relative to bb.edn
(let [file (abs-path file) ;; follow symlink
@ -1210,7 +1226,9 @@ Use bb run --help to show this help output.
(binding [*out* *err*]
(println (str "WARNING: this project requires babashka "
min-bb-version " or newer, but you have: " version)))))
(exec opts)))
(if (deps-not-needed opts)
(exec-without-deps opts)
(exec opts))))
(def musl?
"Captured at compile time, to know if we are running inside a

View file

@ -0,0 +1,22 @@
(ns bytechannel-and-related-classes
(:require [clojure.java.io :as io])
(:import (java.nio.file OpenOption
StandardOpenOption)
(java.nio.channels ByteChannel
FileChannel
ReadableByteChannel
WritableByteChannel
Channels)))
(when (and (let [ch (-> (.getBytes "Hello")
(java.io.ByteArrayInputStream.)
(Channels/newChannel))]
(instance? ReadableByteChannel ch))
(let [ch (-> (java.io.ByteArrayOutputStream.)
(Channels/newChannel))]
(instance? WritableByteChannel ch))
(with-open [ch (FileChannel/open (-> (io/file "README.md")
(.toPath))
(into-array OpenOption [StandardOpenOption/READ]))]
(instance? ByteChannel ch)))
(println :success))

View file

@ -0,0 +1 @@
42

View file

@ -191,4 +191,30 @@
prismatic/plumbing {:git-url "https://github.com/plumatic/plumbing",
:git-sha "424bc704f2db422de34269c139a5494314b3a43b",
:test-namespaces [plumbing.core-test],
:test-paths ["test"]}}
:test-paths ["test"]}
org.clj-commons/hickory {:git-url "https://github.com/clj-commons/hickory"
:git-sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"
:test-paths ["test/cljc"]
:test-namespaces [hickory.test.core
hickory.test.convert
hickory.test.hiccup-utils
hickory.test.render
hickory.test.select
hickory.test.zip]}
cheshire/cheshire {:git-url "https://github.com/dakrone/cheshire", :test-namespaces [cheshire.test.core], :manually-added true}
com.potetm/fusebox {:git-url "https://github.com/potetm/fusebox"
:git-sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"
:test-paths ["test"]
:test-namespaces [#_com.potetm.fusebox.bulkhead-test
com.potetm.fusebox.bulwark-test
com.potetm.fusebox.circuit-breaker-test
com.potetm.fusebox.fallback-test
com.potetm.fusebox.memoize-test
#_com.potetm.fusebox.rate-limit-test
com.potetm.fusebox.registry-test
com.potetm.fusebox.retry-test
#_com.potetm.fusebox.timeout-test]}
net.sekao/odoyle-rules {:git-url "https://github.com/oakes/odoyle-rules"
:git-sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"
:test-paths ["test"]
:test-namespaces [odoyle.rules-test]}}

View file

@ -0,0 +1,793 @@
(ns cheshire.test.core
(:require [clojure.test :refer [deftest testing is are]]
[clojure.java.io :as io]
[clojure.string :as str]
[cheshire.core :as json]
;; BB-TEST-PATCH: bb does not include cheshire.exact
#_[cheshire.exact :as json-exact]
;; BB-TEST-PATCH: bb does not include cheshire.gen
#_[cheshire.generate :as gen]
[cheshire.factory :as fact]
;; BB-TEST-PATCH: bb does not include cheshire.parse
#_[cheshire.parse :as parse])
(:import ;; BB-TEST-PATCH: tests adjusted to check for general Exception instead of specific jackson exceptions
#_(com.fasterxml.jackson.core JsonGenerationException
JsonParseException)
#_(com.fasterxml.jackson.core.exc StreamConstraintsException)
(java.io StringReader StringWriter
BufferedReader BufferedWriter
IOException)
;; BB-TEST-PATCH: bb does not support creating java.sql.Timestamps
#_(java.sql Timestamp)
(java.util Date UUID)))
(defn- str-of-len
([len]
(str-of-len len "x"))
([len val]
(apply str (repeat len val))))
(defn- nested-map [depth]
(reduce (fn [acc n] {(str n) acc})
{"0" "foo"}
(range 1 depth)))
(defn- encode-stream->str [obj opts]
(let [sw (StringWriter.)
bw (BufferedWriter. sw)]
(json/generate-stream obj bw opts)
(.toString sw)))
(def test-obj {"int" 3 "long" (long -2147483647) "boolean" true
"LongObj" (Long/parseLong "2147483647") "double" 1.23
"nil" nil "string" "string" "vec" [1 2 3] "map" {"a" "b"}
"list" (list "a" "b") "short" (short 21) "byte" (byte 3)})
(deftest t-ratio
(let [n 1/2]
(is (= (double n) (:num (json/decode (json/encode {:num n}) true))))))
(deftest t-long-wrap-around
(is (= 2147483648 (json/decode (json/encode 2147483648)))))
(deftest t-bigint
(let [n 9223372036854775808]
(is (= n (:num (json/decode (json/encode {:num n}) true))))))
(deftest t-biginteger
(let [n (BigInteger. "42")]
(is (= n (:num (json/decode (json/encode {:num n}) true))))))
(deftest t-bigdecimal
(let [n (BigDecimal. "42.5")]
(is (= (.doubleValue n) (:num (json/decode (json/encode {:num n}) true))))
;; BB-TEST-PATCH:
#_(binding [parse/*use-bigdecimals?* true]
(is (= n (:num (json/decode (json/encode {:num n}) true)))))))
(deftest test-string-round-trip
(is (= test-obj (json/decode (json/encode test-obj)))))
(deftest test-generate-accepts-float
(is (= "3.14" (json/encode 3.14))))
(deftest test-keyword-encode
(is (= {"key" "val"}
(json/decode (json/encode {:key "val"})))))
(deftest test-generate-set
(is (= {"set" ["a" "b"]}
(json/decode (json/encode {"set" #{"a" "b"}})))))
(deftest test-generate-empty-set
(is (= {"set" []}
(json/decode (json/encode {"set" #{}})))))
(deftest test-generate-empty-array
(is (= {"array" []}
(json/decode (json/encode {"array" []})))))
(deftest test-key-coercion
(is (= {"foo" "bar" "1" "bat" "2" "bang" "3" "biz"}
(json/decode
(json/encode
{:foo "bar" 1 "bat" (long 2) "bang" (bigint 3) "biz"})))))
(deftest test-keywords
(is (= {:foo "bar" :bat 1}
(json/decode (json/encode {:foo "bar" :bat 1}) true))))
(deftest test-symbols
(is (= {"foo" "clojure.core/map"}
(json/decode (json/encode {"foo" 'clojure.core/map})))))
(deftest test-accepts-java-map
(is (= {"foo" 1}
(json/decode
(json/encode (doto (java.util.HashMap.) (.put "foo" 1)))))))
(deftest test-accepts-java-list
(is (= [1 2 3]
(json/decode (json/encode (doto (java.util.ArrayList. 3)
(.add 1)
(.add 2)
(.add 3)))))))
(deftest test-accepts-java-set
(is (= {"set" [1 2 3]}
(json/decode (json/encode {"set" (doto (java.util.HashSet. 3)
(.add 1)
(.add 2)
(.add 3))})))))
(deftest test-accepts-empty-java-set
(is (= {"set" []}
(json/decode (json/encode {"set" (java.util.HashSet. 3)})))))
(deftest test-nil
(is (nil? (json/decode nil true))))
(deftest test-parsed-seq
(let [br (BufferedReader. (StringReader. "1\n2\n3\n"))]
(is (= (list 1 2 3) (json/parsed-seq br)))))
;; BB-TEST-PATCH: bb does not support smile
#_(deftest test-smile-round-trip
(is (= test-obj (json/parse-smile (json/generate-smile test-obj)))))
(def bin-obj {"byte-array" (byte-array (map byte [1 2 3]))})
;; BB-TEST-PATCH: bb does not support smile/cbor
#_(deftest test-round-trip-binary
(doseq [[p g] {json/parse-string json/generate-string
json/parse-smile json/generate-smile
json/parse-cbor json/generate-cbor}]
(is (let [roundtripped (p (g bin-obj))]
;; test value equality
(is (= (->> bin-obj (get "byte-array") seq)
(->> roundtripped (get "byte-array") seq)))))))
;; BB-TEST-PATCH: bb does not support smile
#_(deftest test-smile-factory
(binding [fact/*smile-factory* (fact/make-smile-factory {})]
(is (= {"a" 1} (-> {:a 1}
json/generate-smile
json/parse-smile)))))
;; BB-TEST-PATCH: bb does not support smile/cbor
#_(deftest test-smile-duplicate-detection
(let [smile-data (byte-array [0x3a 0x29 0x0a 0x01 ;; smile header
0xFa ;; object start
0x80 0x61 ;; key a
0xC2 ;; value 1
0x80 0x61 ;; key a (again)
0xC4 ;; value 2
0xFB ;; object end
])]
(binding [fact/*smile-factory* (fact/make-smile-factory {:strict-duplicate-detection false})]
(is (= {"a" 2} (json/parse-smile smile-data))))
(binding [fact/*smile-factory* (fact/make-smile-factory {:strict-duplicate-detection true})]
(is (thrown? JsonParseException (json/parse-smile smile-data))))))
;; BB-TEST-PATCH: bb does not support cbor
#_(deftest test-cbor-factory
(binding [fact/*cbor-factory* (fact/make-cbor-factory {})]
(is (= {"a" 1} (-> {:a 1}
json/generate-cbor
json/parse-cbor)))))
;; BB-TEST-PATCH: bb does not support cbor
#_(deftest test-cbor-duplicate-detection
(let [cbor-data (byte-array [0xbf ;; object begin
0x61 0x61 ;; key a
0x01 ;; value 1
0x61 0x61 ;; key a (again)
0x02 ;; value 2
0xff ;; object end
])]
(binding [fact/*cbor-factory* (fact/make-cbor-factory {:strict-duplicate-detection false})]
(is (= {"a" 2} (json/parse-cbor cbor-data))))
(binding [fact/*cbor-factory* (fact/make-cbor-factory {:strict-duplicate-detection true})]
(is (thrown? JsonParseException (json/parse-cbor cbor-data))))))
(deftest test-aliases
(is (= {"foo" "bar" "1" "bat" "2" "bang" "3" "biz"}
(json/decode
(json/encode
{:foo "bar" 1 "bat" (long 2) "bang" (bigint 3) "biz"})))))
(deftest test-date
(is (= {"foo" "1970-01-01T00:00:00Z"}
(json/decode (json/encode {:foo (Date. (long 0))}))))
(is (= {"foo" "1970-01-01"}
(json/decode (json/encode {:foo (Date. (long 0))}
{:date-format "yyyy-MM-dd"})))
"encode with given date format"))
;; BB-TEST-PATCH: bb does not support creating java.sql.Timestamps
#_(deftest test-sql-timestamp
(is (= {"foo" "1970-01-01T00:00:00Z"}
(json/decode (json/encode {:foo (Timestamp. (long 0))}))))
(is (= {"foo" "1970-01-01"}
(json/decode (json/encode {:foo (Timestamp. (long 0))}
{:date-format "yyyy-MM-dd"})))
"encode with given date format"))
(deftest test-uuid
(let [id (UUID/randomUUID)
id-str (str id)]
(is (= {"foo" id-str} (json/decode (json/encode {:foo id}))))))
(deftest test-char-literal
(is (= "{\"foo\":\"a\"}" (json/encode {:foo \a}))))
(deftest test-streams
(testing "parse-stream"
(are [parsed parse parsee] (= parsed
(parse (BufferedReader. (StringReader. parsee))))
{"foo" "bar"} json/parse-stream "{\"foo\":\"bar\"}\n"
{"foo" "bar"} json/parse-stream-strict "{\"foo\":\"bar\"}\n")
(are [parsed parse parsee] (= parsed
(with-open [rdr (StringReader. parsee)]
(parse rdr true)))
{(keyword "foo baz") "bar"} json/parse-stream "{\"foo baz\":\"bar\"}\n"
{(keyword "foo baz") "bar"} json/parse-stream-strict "{\"foo baz\":\"bar\"}\n"))
(testing "generate-stream"
(let [sw (StringWriter.)
bw (BufferedWriter. sw)]
(json/generate-stream {"foo" "bar"} bw)
(is (= "{\"foo\":\"bar\"}" (.toString sw))))))
;; BB-TEST-PATCH: bb does not include with-writer
#_(deftest serial-writing
(is (= "[\"foo\",\"bar\"]"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write [] :start)
(json/write "foo")
(json/write "bar")
(json/write [] :end)))))
(is (= "[1,[2,3],4]"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write [1 [2]] :start-inner)
(json/write 3)
(json/write [] :end)
(json/write 4)
(json/write [] :end)))))
(is (= "{\"a\":1,\"b\":2,\"c\":3}"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write {:a 1} :start)
(json/write {:b 2} :bare)
(json/write {:c 3} :end)))))
(is (= (str "[\"start\",\"continue\",[\"implicitly-nested\"],"
"[\"explicitly-nested\"],\"flatten\",\"end\"]")
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write ["start"] :start)
(json/write "continue")
(json/write ["implicitly-nested"])
(json/write ["explicitly-nested"] :all)
(json/write ["flatten"] :bare)
(json/write ["end"] :end)))))
(is (= "{\"head\":\"head info\",\"data\":[1,2,3],\"tail\":\"tail info\"}"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write {:head "head info" :data []} :start-inner)
(json/write 1)
(json/write 2)
(json/write 3)
(json/write [] :end)
(json/write {:tail "tail info"} :end))))))
;; BB-TEST-PATCH: modified so that json files could be found
(deftest test-multiple-objs-in-file
(is (= {"one" 1, "foo" "bar"}
(first (json/parsed-seq (io/reader (io/resource "cheshire/test/multi.json"))))))
(is (= {"two" 2, "foo" "bar"}
(second (json/parsed-seq (io/reader (io/resource "cheshire/test/multi.json"))))))
(with-open [r (io/reader (io/resource "cheshire/test/multi.json"))]
(is (= [{"one" 1, "foo" "bar"} {"two" 2, "foo" "bar"}]
(json/parsed-seq r)))))
(deftest test-jsondotorg-pass1
(let [;; BB-TEST-PATCH: modified so that json files could be found
string (slurp (io/resource "cheshire/test/pass1.json"))
decoded-json (json/decode string)
encoded-json (json/encode decoded-json)
re-decoded-json (json/decode encoded-json)]
(is (= decoded-json re-decoded-json))))
(deftest test-namespaced-keywords
(is (= "{\"foo\":\"user/bar\"}"
(json/encode {:foo :user/bar})))
(is (= {:foo/bar "baz/eggplant"}
(json/decode (json/encode {:foo/bar :baz/eggplant}) true))))
(deftest test-array-coerce-fn
(is (= {"set" #{"a" "b"} "array" ["a" "b"] "map" {"a" 1}}
(json/decode
(json/encode {"set" #{"a" "b"} "array" ["a" "b"] "map" {"a" 1}}) false
(fn [field-name] (if (= "set" field-name) #{} []))))))
(deftest t-symbol-encoding-for-non-resolvable-symbols
(is (= "{\"bar\":\"clojure.core/pam\",\"foo\":\"clojure.core/map\"}"
(json/encode (sorted-map :foo 'clojure.core/map :bar 'clojure.core/pam))))
(is (= "{\"bar\":\"clojure.core/pam\",\"foo\":\"foo.bar/baz\"}"
(json/encode (sorted-map :foo 'foo.bar/baz :bar 'clojure.core/pam)))))
(deftest t-bindable-factories-auto-close-source
(binding [fact/*json-factory* (fact/make-json-factory
{:auto-close-source false})]
(let [br (BufferedReader. (StringReader. "123"))]
(is (= 123 (json/parse-stream br)))
(is (= -1 (.read br)))))
(binding [fact/*json-factory* (fact/make-json-factory
{:auto-close-source true})]
(let [br (BufferedReader. (StringReader. "123"))]
(is (= 123 (json/parse-stream br)))
(is (thrown? IOException (.read br))))))
(deftest t-bindable-factories-allow-comments
(let [s "{\"a\": /* comment */ 1, // comment\n \"b\": 2}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-comments true})]
(is (= {"a" 1 "b" 2} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-comments false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-unquoted-field-names
(let [s "{a: 1, b: 2}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-field-names true})]
(is (= {"a" 1 "b" 2} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-field-names false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-single-quotes
(doseq [s ["{'a': \"one\", 'b': \"two\"}"
"{\"a\": 'one', \"b\": 'two'}"
"{'a': 'one', 'b': 'two'}"]]
(testing s
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-single-quotes true})]
(is (= {"a" "one" "b" "two"} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-single-quotes false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s)))))))
(deftest t-bindable-factories-allow-unquoted-control-chars
(let [s "{\"a\": \"one\ntwo\"}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-control-chars true})]
(is (= {"a" "one\ntwo"} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-control-chars false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-backslash-escaping-any-char
(let [s "{\"a\": 00000000001}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-numeric-leading-zeros true})]
(is (= {"a" 1} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-numeric-leading-zeros false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-numeric-leading-zeros
(let [s "{\"a\": \"\\o\\n\\e\"}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-backslash-escaping true})]
(is (= {"a" "o\ne"} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-backslash-escaping false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-non-numeric-numbers
(let [s "{\"foo\":NaN}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-non-numeric-numbers true})]
(is (= (type Double/NaN)
(type (:foo (json/decode s true))))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-non-numeric-numbers false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s true))))))
(deftest t-bindable-factories-optimization-opts
(let [s "{\"a\": \"foo\"}"]
(doseq [opts [{:intern-field-names true}
{:intern-field-names false}
{:canonicalize-field-names true}
{:canonicalize-field-names false}]]
(binding [fact/*json-factory* (fact/make-json-factory opts)]
(is (= {"a" "foo"} (json/decode s)))))))
(deftest t-bindable-factories-escape-non-ascii
;; includes testing legacy fn opt of same name can override factory
(let [edn {:foo "It costs £100"}
expected-esc "{\"foo\":\"It costs \\u00A3100\"}"
expected-no-esc "{\"foo\":\"It costs £100\"}"
opt-esc {:escape-non-ascii true}
opt-no-esc {:escape-non-ascii false}]
(testing "default factory"
(doseq [[fn-opts expected]
[[{} expected-no-esc]
[opt-esc expected-esc]
[opt-no-esc expected-no-esc]]]
(testing fn-opts
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts))))))
(testing (str "factory: " opt-esc)
(binding [fact/*json-factory* (fact/make-json-factory opt-esc)]
(doseq [[fn-opts expected]
[[{} expected-esc]
[opt-esc expected-esc]
[opt-no-esc expected-no-esc]]]
(testing (str "fn: " fn-opts)
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts)))))))
(testing (str "factory: " opt-no-esc)
(binding [fact/*json-factory* (fact/make-json-factory opt-no-esc)]
(doseq [[fn-opts expected]
[[{} expected-no-esc]
[opt-esc expected-esc]
[opt-no-esc expected-no-esc]]]
(testing (str "fn: " fn-opts)
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts)))))))))
(deftest t-bindable-factories-quoteless
(binding [fact/*json-factory* (fact/make-json-factory
{:quote-field-names true})]
(is (= "{\"a\":\"foo\"}" (json/encode {:a "foo"}))))
(binding [fact/*json-factory* (fact/make-json-factory
{:quote-field-names false})]
(is (= "{a:\"foo\"}" (json/encode {:a "foo"})))))
(deftest t-bindable-factories-strict-duplicate-detection
(binding [fact/*json-factory* (fact/make-json-factory
{:strict-duplicate-detection true})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_ JsonParseException Exception
(json/decode "{\"a\": 1, \"b\": 2, \"a\": 3}"))))
(binding [fact/*json-factory* (fact/make-json-factory
{:strict-duplicate-detection false})]
(is (= {"a" 3 "b" 2}
(json/decode "{\"a\": 1, \"b\": 2, \"a\": 3}")))))
(deftest t-bindable-factories-max-input-document-length
(let [edn {"a" (apply str (repeat 10000 "x"))}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-document-length (count sample-data)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
;; as per Jackson docs, limit is inexact, so dividing input length by 2 should do the trick
{:max-input-document-length (/ (count sample-data) 2)})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)document length .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-token-count
;; A token is a single unit of input, such as a number, a string, an object start or end, or an array start or end.
(let [edn {"1" 2 "3" 4}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-token-count 6})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-token-count 5})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)token count .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-name-length
(let [k "somekey"
edn {k 1}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-name-length (count k)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-name-length (dec (count k))})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)name .* exceeds"
(json/decode sample-data)))))
(let [default-limit (:max-input-name-length fact/default-factory-options)]
(let [k (str-of-len default-limit)
edn {k 1}
sample-data (json/encode edn)]
(is (= edn (json/decode sample-data))))
(let [k (str-of-len (inc default-limit))
sample-data (json/encode {k 1})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)name .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-input-nesting-depth
(let [edn (nested-map 100)
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-nesting-depth 100})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-nesting-depth 99})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)nesting depth .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-number-length
(let [num 123456789
edn {"foo" num}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-number-length (-> num str count)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-number-length (-> num str count dec)})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)number value length .* exceeds"
(json/decode sample-data)))))
(let [default-limit (:max-input-number-length fact/default-factory-options)]
(let [num (bigint (str-of-len default-limit 2))
edn {"foo" num}
sample-data (json/encode edn)]
(is (= edn (json/decode sample-data))))
(let [num (bigint (str-of-len (inc default-limit) 2))
sample-data (json/encode {"foo" num})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)number value length .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-string-length
(let [big-string (str-of-len 40000000)
edn {"big-string" big-string}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-string-length (count big-string)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-string-length (dec (count big-string))})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)string value length .* exceeds"
(json/decode sample-data)))))
(let [default-limit (:max-input-string-length fact/default-factory-options)]
(let [big-string (str-of-len default-limit)
edn {"big-string" big-string}
sample-data (json/encode edn)]
(is (= edn (json/decode sample-data))))
(let [big-string (str-of-len (inc default-limit))
sample-data (json/encode {"big-string" big-string})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)string value length .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-output-nesting-depth
(let [edn (nested-map 100)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-output-nesting-depth 100})]
(is (.contains (json/encode edn) "\"99\"")))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-output-nesting-depth 99})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)nesting depth .* exceeds"
(json/encode edn))))))
(deftest t-persistent-queue
(let [q (conj clojure.lang.PersistentQueue/EMPTY 1 2 3)]
(is (= q (json/decode (json/encode q))))))
(deftest t-pretty-print
(is (= (str/join (System/lineSeparator)
["{"
" \"bar\" : [ {"
" \"baz\" : 2"
" }, \"quux\", [ 1, 2, 3 ] ],"
" \"foo\" : 1"
"}"])
(json/encode (sorted-map :foo 1 :bar [{:baz 2} :quux [1 2 3]])
{:pretty true}))))
(deftest t-pretty-print-custom-linebreak
(is (= (str/join "foo"
["{"
" \"bar\" : [ {"
" \"baz\" : 2"
" }, \"quux\", [ 1, 2, 3 ] ],"
" \"foo\" : 1"
"}"])
(json/encode (sorted-map :foo 1 :bar [{:baz 2} :quux [1 2 3]])
{:pretty {:line-break "foo"}}))))
(deftest t-pretty-print-illegal-argument
; just expecting this not to throw
(json/encode {:foo "bar"}
{:pretty []})
(json/encode {:foo "bar"}
{:pretty nil}))
(deftest t-custom-pretty-print-with-defaults
(let [test-obj (sorted-map :foo 1 :bar {:baz [{:ulu "mulu"} {:moot "foo"} 3]} :quux :blub)
pretty-str-default (json/encode test-obj {:pretty true})
pretty-str-custom (json/encode test-obj {:pretty {}})]
(is (= pretty-str-default pretty-str-custom))
(when-not (= pretty-str-default pretty-str-custom)
; print for easy comparison
(println "; default pretty print")
(println pretty-str-default)
(println "; custom pretty print with default options")
(println pretty-str-custom))))
(deftest t-custom-pretty-print-with-non-defaults
(let [test-obj (sorted-map :foo 1 :bar {:baz [{:ulu "mulu"} {:moot "foo"} 3]} :quux :blub)
test-opts {:pretty {:indentation 4
:indent-arrays? false
:before-array-values ""
:after-array-values ""
:object-field-value-separator ": "}}
expected (str/join (System/lineSeparator)
["{"
" \"bar\": {"
" \"baz\": [{"
" \"ulu\": \"mulu\""
" }, {"
" \"moot\": \"foo\""
" }, 3]"
" },"
" \"foo\": 1,"
" \"quux\": \"blub\""
"}"])
pretty-str (json/encode test-obj test-opts)]
; just to be easy on the eyes in case of error
(when-not (= expected pretty-str)
(println "; pretty print with options - actual")
(println pretty-str)
(println "; pretty print with options - expected")
(println expected))
(is (= expected pretty-str))))
(deftest t-custom-pretty-print-with-noident-objects
(let [test-obj [{:foo 1 :bar 2} {:foo 3 :bar 4}]
test-opts {:pretty {:indent-objects? false}}
expected (str "[ { \"foo\" : 1, \"bar\" : 2 }, "
"{ \"foo\" : 3, \"bar\" : 4 } ]")
pretty-str (json/encode test-obj test-opts)]
; just to be easy on the eyes in case of error
(when-not (= expected pretty-str)
(println "; pretty print with options - actual")
(println pretty-str)
(println "; pretty print with options - expected")
(println expected))
(is (= expected pretty-str))))
(deftest t-custom-keyword-fn
(is (= {:FOO "bar"} (json/decode "{\"foo\": \"bar\"}"
(fn [k] (keyword (.toUpperCase k))))))
(is (= {"foo" "bar"} (json/decode "{\"foo\": \"bar\"}" nil)))
(is (= {"foo" "bar"} (json/decode "{\"foo\": \"bar\"}" false)))
(is (= {:foo "bar"} (json/decode "{\"foo\": \"bar\"}" true))))
(deftest t-custom-encode-key-fn
(is (= "{\"FOO\":\"bar\"}"
(json/encode {:foo :bar}
{:key-fn (fn [k] (.toUpperCase (name k)))}))))
;; BB-TEST-PATCH: bb does nto include cheshire.generate ns
#_(deftest test-add-remove-encoder
(gen/remove-encoder java.net.URL)
(gen/add-encoder java.net.URL gen/encode-str)
(is (= "\"http://foo.com\""
(json/encode (java.net.URL. "http://foo.com"))))
(gen/remove-encoder java.net.URL)
(is (thrown? JsonGenerationException
(json/encode (java.net.URL. "http://foo.com")))))
#_(defprotocol TestP
(foo [this] "foo method"))
#_(defrecord TestR [state])
#_(extend TestR
TestP
{:foo (constantly "bar")})
#_(deftest t-custom-protocol-encoder
(let [rec (TestR. :quux)]
(is (= {:state "quux"} (json/decode (json/encode rec) true)))
(gen/add-encoder cheshire.test.core.TestR
(fn [obj jg]
(.writeString jg (foo obj))))
(is (= "bar" (json/decode (json/encode rec))))
(gen/remove-encoder cheshire.test.core.TestR)
(is (= {:state "quux"} (json/decode (json/encode rec) true)))))
#_(defprotocol CTestP
(thing [this] "thing method"))
#_(defrecord CTestR [state])
#_(extend CTestR
CTestP
{:thing (constantly "thing")})
#_(deftest t-custom-helpers
(let [thing (CTestR. :state)
remove #(gen/remove-encoder CTestR)]
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-nil nil jg)))
(is (= nil (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-str "foo" jg)))
(is (= "foo" (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-number 5 jg)))
(is (= 5 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-long 4 jg)))
(is (= 4 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-int 3 jg)))
(is (= 3 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-ratio 1/2 jg)))
(is (= 0.5 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-seq [:foo :bar] jg)))
(is (= ["foo" "bar"] (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-date (Date. (long 0)) jg)))
(binding [gen/*date-format* "yyyy-MM-dd'T'HH:mm:ss'Z'"]
(is (= "1970-01-01T00:00:00Z" (json/decode (json/encode thing) true))))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-bool true jg)))
(is (= true (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-named :foo jg)))
(is (= "foo" (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-map {:foo "bar"} jg)))
(is (= {:foo "bar"} (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-symbol 'foo jg)))
(is (= "foo" (json/decode (json/encode thing) true)))
(remove)))
(deftest t-float-encoding
(is (= "{\"foo\":0.01}" (json/encode {:foo (float 0.01)}))))
(deftest t-non-const-bools
(is (= {:a 1} (json/decode "{\"a\": 1}" (Boolean. true)))))
;; BB-TEST-PATCH: bb does not include cheshire.exact ns
#_(deftest t-invalid-json
(let [invalid-json-message "Invalid JSON, expected exactly one parseable object but multiple objects were found"]
(are [x y] (= x (try
y
(catch Exception e
(.getMessage e))))
invalid-json-message (json-exact/decode "{\"foo\": 1}asdf")
invalid-json-message (json-exact/decode "{\"foo\": 123}null")
invalid-json-message (json-exact/decode "\"hello\" : 123}")
{"foo" 1} (json/decode "{\"foo\": 1}")
invalid-json-message (json-exact/decode-strict "{\"foo\": 1}asdf")
invalid-json-message (json-exact/decode-strict "{\"foo\": 123}null")
invalid-json-message (json-exact/decode-strict "\"hello\" : 123}")
{"foo" 1} (json/decode-strict "{\"foo\": 1}"))))

View file

@ -0,0 +1,2 @@
{"one":1,"foo":"bar"}
{"two":2,"foo":"bar"}

View file

@ -0,0 +1,58 @@
[
"JSON Test Pattern pass1",
{"object with 1 member":["array with 1 element"]},
{},
[],
-42,
true,
false,
null,
{
"integer": 1234567890,
"real": -9876.543210,
"e": 0.123456789e-12,
"E": 1.234567890E+34,
"": 23456789012E66,
"zero": 0,
"one": 1,
"space": " ",
"quote": "\"",
"backslash": "\\",
"controls": "\b\f\n\r\t",
"slash": "/ & \/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
"0123456789": "digit",
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
"true": true,
"false": false,
"null": null,
"array":[ ],
"object":{ },
"address": "50 St. James Street",
"url": "http://www.JSON.org/",
"comment": "// /* <!-- --",
"# -- --> */": " ",
" s p a c e d " :[1,2 , 3
,
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
: "A key can be any string"
},
0.5 ,98.6
,
99.44
,
1066,
1e1,
0.1e1,
1e-1,
1e00,2e+00,2e-00
,"rosebud"]

View file

@ -341,7 +341,7 @@
(is (= ::response r))))
(try (get "https://httpbin.org/gzip" {:timeout 1000})
(catch java.net.http.HttpTimeoutException _
(catch Exception _
(doseq [v (vals (ns-publics *ns*))]
(when (:integration (meta v))
(println "Removing test from" v "because httpbin is slow.")

View file

@ -1,5 +1,6 @@
(ns httpkit.client-test
(:require [cheshire.core :as json]
[clojure.string :as str]
[clojure.test :refer [deftest is testing #_*report-counters*]]
[org.httpkit.client :as client]))
@ -16,12 +17,14 @@
(deftest get-test
(is (= 200 (:status @(client/get "https://postman-echo.com/get"))))
(is (= "https://postman-echo.com/get"
(is (str/includes?
(-> @(client/get "https://postman-echo.com/get"
{:headers {"Accept" "application/json"}})
:body
(json/parse-string true)
:url)))
:url)
"postman-echo.com/get"))
;; BB-TEST-PATCH: postman started responding with http:// instead of https://
(testing "query params"
(is (= {:foo1 "bar1", :foo2 "bar2"}
(-> @(client/get "https://postman-echo.com/get" {:query-params {"foo1" "bar1" "foo2" "bar2"}})

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
42

View file

@ -0,0 +1,111 @@
(ns proxy-inputstream-outputstream
(:import (java.io InputStream OutputStream)
(java.nio ByteBuffer)))
;;
;; Accept a ByteBuffer and return an InputStream that reads data from
;; the given buffer.
;;
(defn buffer->input-stream ^InputStream [^ByteBuffer buffer]
(proxy [InputStream] []
(read
([]
(if (.hasRemaining buffer)
(-> (.get buffer)
(bit-and 0xff))
-1))
([b]
(.read this b 0 (alength b)))
([b off len]
(if (.hasRemaining buffer)
(let [len (min (alength b)
(.remaining buffer))]
(.get buffer b off len)
len)
-1)))))
;;
;; Accept a ByteBuffer and return an OutputStream that writes into the
;; buffer.
;;
(defn buffer->output-stream ^OutputStream [^ByteBuffer buffer]
(proxy [OutputStream] []
(write
([v]
(if (bytes? v)
(.put buffer ^bytes v)
(.put buffer (-> (Integer. v) (.byteValue)))))
([v off len]
(.put buffer ^bytes v 0 (alength v))))))
;;
;; Tests:
;;
(defn read-byte-by-byte-test []
(let [in (-> (.getBytes "Hello")
(ByteBuffer/wrap)
(buffer->input-stream))]
(and (= (.read in) (int \H))
(= (.read in) (int \e))
(= (.read in) (int \l))
(= (.read in) (int \l))
(= (.read in) (int \o))
(= (.read in) -1))))
(defn read-byte-array []
(let [in (-> (.getBytes "Hello")
(ByteBuffer/wrap)
(buffer->input-stream))
buffer (byte-array 10)
len (.read in buffer)]
(and (= len 5)
(= (String. buffer 0 len) "Hello"))))
(defn read-all []
(let [in (-> (.getBytes "Hello")
(ByteBuffer/wrap)
(buffer->input-stream))
data (.readAllBytes in)]
(= (String. data) "Hello")))
(defn write-byte-by-byte []
(let [buffer (ByteBuffer/allocate 10)
out (buffer->output-stream buffer)]
(.write out (int \H))
(.write out (int \e))
(.write out (int \l))
(.write out (int \l))
(.write out (int \o))
(= (String. (.array buffer)
0
(.position buffer))
"Hello")))
(defn write-byte-array []
(let [buffer (ByteBuffer/allocate 10)
out (buffer->output-stream buffer)]
(.write out (.getBytes "Hello"))
(= (String. (.array buffer)
0
(.position buffer))
"Hello")))
;;
;; Run all tests:
;;
(when (and (read-byte-by-byte-test)
(read-byte-array)
(read-all)
(write-byte-by-byte)
(write-byte-array))
(println ":success"))

View file

@ -531,6 +531,12 @@ even more stuff here\"
(testing "symlink"
(is (= {1 {:id 1}} (bb (str (fs/file "test-resources" "symlink-adjacent-bb")))))))
; symlinks that resolve in the /proc fs cause fs/real-path to throw when figuring out bb.edn path (issue #1700)
(deftest redirection-test
(testing "main doesn't throw when input file symlink resolves to 'not real' file"
(when (and test-utils/native? (not test-utils/windows?))
(is (str/starts-with? (test-utils/bb "(println \"hi\")" "/dev/stdin") "hi")))))
(deftest non-existing-tasks-in-run-gives-exit-code-1
(is (thrown? Exception (bb "-Sdeps" "{:tasks {foo {:task (run (quote bar))}}}" "foo"))))

View file

@ -11,7 +11,8 @@
(-> line str/trimr
;; take into account JDK14+ and native image differences
(str/replace "class clojure.lang" "clojure.lang")
(str/replace #" \(.*\)$" "")))
(str/replace #" \(.*\)$" "")
(str/replace #"--\d\d\d\d" "")))
(defmacro multiline-equals [s1 s2]
`(let [lines-s1# (str/split-lines ~s1)
@ -92,7 +93,7 @@ clojure.core// - <built-in>
foo - foo.clj:1:10"))))
(deftest static-call-test
(let [output (try (tu/bb nil "-e" "File/x")
#_(let [output (try (tu/bb nil "-e" "File/x")
(catch Exception e (ex-message e)))]
(is (str/includes? (tu/normalize output)
"----- Error --------------------------------------------------------------------
@ -105,7 +106,7 @@ Location: <expr>:1:1
^--- No matching field found: x for class java.io.File
----- Stack trace --------------------------------------------------------------
user - <expr>:1:1"))
user - <expr>:1:1")))
(let [output (try (tu/bb nil "-e" "(File/x)")
(catch Exception e (ex-message e)))]
(is (str/includes? (tu/normalize output)
@ -119,7 +120,7 @@ Location: <expr>:1:1
^--- No matching method x found taking 0 args
----- Stack trace --------------------------------------------------------------
user - <expr>:1:1")))))
user - <expr>:1:1"))))
(deftest error-while-macroexpanding-test

View file

@ -0,0 +1,18 @@
(ns babashka.impl.clojure.main-test
(:require [babashka.test-utils :as tu]
[clojure.edn :as edn]
[clojure.test :as t :refer [deftest is testing]]))
(def bb
(comp edn/read-string tu/bb))
(deftest with-read-known-test
(testing ":unknown gets set to true"
(is (true? (bb nil (pr-str '(binding [*read-eval* :unknown]
(clojure.main/with-read-known *read-eval*)))))))
(testing "other values don't change"
(t/are [read-eval-value]
(= read-eval-value
(bb nil (str "(binding [*read-eval* " read-eval-value "]"
" (clojure.main/with-read-known *read-eval*))")))
false true 5)))

View file

@ -26,15 +26,15 @@
(sci/with-in-str (str expr "\n:repl/quit")
(repl!)))) expected)))
(defn assert-repl-error [expr expected]
(is (str/includes?
(defmacro assert-repl-error [expr expected]
`(is (str/includes?
(tu/normalize
(let [sw (java.io.StringWriter.)]
(let [sw# (java.io.StringWriter.)]
(sci/binding [sci/out (java.io.StringWriter.)
sci/err sw]
(sci/with-in-str (str expr "\n:repl/quit")
sci/err sw#]
(sci/with-in-str (str ~expr "\n:repl/quit")
(repl!)))
(str sw))) expected)))
(str sw#))) ~expected)))
(deftest repl-test
(assert-repl "1" "1")
@ -52,7 +52,9 @@
(assert-repl-error "(+ 1 nil)" "NullPointerException")
(assert-repl-error "(/ 1 0) (pst 1)" "Divide by zero\n\tclojure.lang.Numbers")
(assert-repl-error "(partition (range 5) 3)"
"Don't know how to create ISeq from: java.lang.Long"))
"Don't know how to create ISeq from: java.lang.Long")
(assert-repl "(throw (ex-info \"foo\" {:a (+ 1 2 3)})) (ex-data *e)"
"{:a 6}"))
;;;; Scratch

View file

@ -0,0 +1,20 @@
(ns babashka.impl.server-test
(:require [babashka.test-utils :as tu]
[clojure.edn :as edn]
[clojure.test :as t :refer [deftest is testing]]))
(def bb
(comp edn/read-string tu/bb))
(deftest repl-read-test
(testing "arbitrary values can be read"
(t/are [input result]
(= result (bb input "(let [request-exit (Object.)]
(loop [acc []]
(let [v (clojure.core.server/repl-read nil request-exit)]
(if (= v request-exit)
acc
(recur (conj acc v))))))"))
"abc" '[abc]
"123 456" [123 456]
"(nil ns/symbol (true))\n (+ 1 2 3)" '[(nil ns/symbol (true)) (+ 1 2 3)])))

View file

@ -18,11 +18,20 @@
(bb nil (pr-str '(do
(def t (Thread. (fn [])))
(def vt (Thread/startVirtualThread (fn [])))
[(.isVirtual t) (.isVirtual vt)]))))))
[(.isVirtual t) (.isVirtual vt)])))))
(is (bb nil (pr-str '(instance?
java.util.concurrent.Executor
(java.util.concurrent.Executors/newThreadPerTaskExecutor (-> (Thread/ofVirtual) (.name "fusebox-thread-" 1) (.factory))))))))
(deftest domain-sockets-test
(is (= :success (bb nil (slurp "test-resources/domain_sockets.bb")))))
(deftest byte-channels-test
(is (= :success (bb nil (slurp "test-resources/bytechannel_and_related_classes.bb")))))
(deftest proxy-inputstream-outputstream-test
(is (= :success (bb nil (slurp "test-resources/proxy_inputstream_outputstream.bb")))))
(deftest map-entry-create-test
(is (true? (bb nil "(= (first {1 2})
(clojure.lang.MapEntry. 1 2)
@ -42,12 +51,54 @@
(some? (.getSubjectX500Principal cert))
"))))
(deftest ECDH-test
(is (true? (bb nil "
(import
'[java.security KeyPairGenerator MessageDigest]
'[java.security.spec ECGenParameterSpec]
'[javax.crypto KeyAgreement]
'[javax.crypto.spec SecretKeySpec])
(def keypair-algo \"EC\")
(def keypair-curve \"secp256r1\")
(def key-agreement-algo \"ECDH\") ; Elliptic Curve Diffie-Hellman
(def key-digest-algo \"SHA-256\")
(def key-encryption-algo \"AES\")
(defn keypair
\"Generates a new key pair with the given alias, using the keypair-algo and keypair-curve\"
[]
(let [keygen (KeyPairGenerator/getInstance keypair-algo)]
(.initialize keygen (ECGenParameterSpec. keypair-curve))
(.generateKeyPair keygen)))
(defn symmetric-key
\"Generates a symmetric key using Elliptic Curve Diffie-Hellman based on a given local private and a remote public key\"
[private-key public-key]
; Derive shared secret
(let [shared-secret
(let [key-agreement (KeyAgreement/getInstance key-agreement-algo)]
(.init key-agreement private-key)
(.doPhase key-agreement public-key true)
(.generateSecret key-agreement))
symmetric-key
(let [message-digest (MessageDigest/getInstance key-digest-algo)
hash-bytes (.digest message-digest shared-secret)
key-bytes (byte-array (subvec (vec hash-bytes) 0 32))] ; extracts the first 256 bits for AES key
(SecretKeySpec. key-bytes key-encryption-algo))]
symmetric-key))
(let [[kp1 kp2] [(keypair) (keypair)]
[private public] [(.getPrivate kp1) (.getPublic kp2)]
symmetric (symmetric-key private public)]
(some? (.getAlgorithm symmetric)))
"))))
(deftest IntStream-test
(is (pos? (bb nil "(.count (.codePoints \"woof🐕\"))"))))
(deftest Thread-sleep-test
(is (bb nil "(Thread/sleep (/ 1 200))
(Thread/sleep (/ 1 200) (/ 1 200))
(is (bb nil "(Thread/sleep (int 1))
(Thread/sleep (java.time.Duration/ofMillis 1))
true")))
@ -55,3 +106,163 @@
(is (= :user/success
(bb nil "(try (.createSocket (javax.net.ssl.SSLSocketFactory/getDefault) \"localhost\" 4444) (catch java.net.ConnectException e ::success))")))
(is (bb nil " (.startHandshake (.createSocket (javax.net.ssl.SSLSocketFactory/getDefault) \"clojure.org\" 443)) ::success")))
(deftest jio-line-number-reader-test
(is (= 2 (bb nil "(def rdr (java.io.LineNumberReader. (java.io.StringReader. \"foo\nbar\")))
(binding [*in* rdr] (read-line) (read-line)) (.getLineNumber rdr)"))))
(deftest FI-coercion
(is (true? (bb nil "(= [1 3] (into [] (doto (java.util.ArrayList. [1 2 3]) (.removeIf even?))))")))
(is (true? (bb nil "(= \"abcabc\" (.computeIfAbsent (java.util.HashMap.) \"abc\" #(str % %)))")))
(is (true? (bb nil "(= '(\\9) (-> \"a9-\" seq .stream (.filter Character/isDigit) stream-seq!))")))
(is (true? (bb nil "(require (quote [clojure.java.io :as jio])) (import [java.io File] [java.nio.file Path Files DirectoryStream$Filter]) (pos? (count (seq (Files/newDirectoryStream (.toPath (jio/file \".\"))
#(-> ^Path % .toFile .isDirectory)))))")))
(is (true? (bb nil "(import [java.util Collection] [java.util.stream Stream] [java.util.function Predicate])
(= '(100 100 100 100 100) (->> (Stream/generate (constantly 100)) stream-seq! (take 5)))")))
(is (true? (bb nil "(import [java.util Collection] [java.util.stream Stream] [java.util.function Predicate])
(= '(1 2 3 4 5 6 7 8 9 10) (->> (Stream/iterate 1 inc) stream-seq! (take 10)))"))))
(deftest regression-test
(is (true? (bb nil "(let [x \"f\"] (String/.startsWith \"foo\" x))"))))
(deftest clojure-1_12-interop-test
(is (= [1 2 3] (bb nil "(map Integer/parseInt [\"1\" \"2\" \"3\"])")))
(is (= [1 2 3] (bb nil "(map String/.length [\"1\" \"22\" \"333\"])")))
(is (= ["1" "22" "333"] (bb nil "(map String/new [\"1\" \"22\" \"333\"])")))
(is (= 3 (bb nil "(String/.length \"123\")")))
(is (= "123" (bb nil "(String/new \"123\")"))))
(deftest clojure-1_12-array-test
(is (true? (bb nil "(instance? Class long/1)"))))
(deftest keygen-test
(is (true?
(bb nil
'(do (ns keygen
(:import [java.security KeyPairGenerator Signature]))
(defn generate-key-pair
"Generates a public/private key pair."
[]
(let [keygen (KeyPairGenerator/getInstance "RSA")]
(.initialize keygen 2048)
(.generateKeyPair keygen)))
(defn create-signature
"Signs the given message using the private key."
[private-key message]
(let [signature (Signature/getInstance "SHA256withRSA")]
(.initSign signature private-key)
(.update signature (.getBytes message "UTF-8"))
(.sign signature)))
(defn verify-signature
"Verifies the given signed data using the public key."
[public-key message signed-data]
(let [signature (Signature/getInstance "SHA256withRSA")]
(.initVerify signature public-key)
(.update signature (.getBytes message "UTF-8"))
(.verify signature signed-data)))
(let [key-pair (generate-key-pair)
private-key (.getPrivate key-pair)
public-key (.getPublic key-pair)
message "This is a secret message"
signed-data (create-signature private-key message)]
(verify-signature public-key message signed-data))))))
(is (true?
(bb nil '(do (import
'[java.security KeyPairGenerator]
'[java.security.spec ECGenParameterSpec])
(def keypair-algo "EC")
(def keypair-curve "secp256r1")
(defn keypair
"Generates a new key pair with the given alias, using the keypair-algo and keypair-curve"
[]
(let [keygen (KeyPairGenerator/getInstance keypair-algo)]
(.initialize keygen (ECGenParameterSpec. keypair-curve))
(.generateKeyPair keygen)))
(let [kp (keypair)
pk (.getPublic kp)]
(bytes? (.getEncoded pk))))))))
;; RT iter test
(deftest clojure-RT-iter-test
(is (= (iterator-seq (.iterator [1 2 3]))
(bb nil '(do (ns test
(:import [clojure.lang RT]))
(iterator-seq (clojure.lang.RT/iter [1 2 3])))))))
(deftest posix-file-attributes
(when-not test-utils/windows?
(is (= 'java.util.HashSet
(bb nil
'(do
(import
[java.nio.file Files LinkOption Path]
[java.nio.file.attribute PosixFileAttributes])
(-> (Files/readAttributes (Path/of "test-resources/posix-file-attributes.txt"
(into-array String []))
PosixFileAttributes
^"[Ljava.nio.file.LinkOption;"
(into-array LinkOption []))
.permissions
type)))))))
(deftest extended-attributes
(is (true?
(bb nil
'(do
(import
[java.nio.file Files LinkOption Path]
[java.nio.file.attribute UserDefinedFileAttributeView])
(instance? UserDefinedFileAttributeView
(Files/getFileAttributeView (Path/of "test-resources/extended-attributes.txt"
(into-array String []))
UserDefinedFileAttributeView
^"[Ljava.nio.file.LinkOption;"
(into-array LinkOption []))))))))
;; exercise a sampling of the superclass resolutions from the :public-class fn in
;; babashka.impl.classes/gen-class-map
(deftest public-class-resolutions
(testing "Charset"
(is (= "UTF-8" (bb nil "(.displayName (java.nio.charset.Charset/forName \"UTF-8\"))"))))
(testing "InputStream"
(is (zero? (bb nil "(with-open [is (java.io.InputStream/nullInputStream)]
(.available is))"))))
(testing "Throwable"
; compare output from ex-message to calling .getMessage
(let [return-throwable "(try (yaml/parse-string \"abc: def: ghi\") (catch Exception e e))"]
(is (= (bb nil (str "(ex-message " return-throwable ")"))
(bb nil (str "(.getMessage " return-throwable ")"))))))
(testing "jsoup Element"
(is (= "form" (bb nil "(.tagName (first (.getElementsByTag (org.jsoup.Jsoup/parseBodyFragment \"<form></form>\") \"form\")))")))))
(deftest cached-thread-pool
(is (= 3 (bb nil "(import '(java.util.concurrent Executors ExecutorService))
(let [fut (.submit ^ExecutorService (Executors/newCachedThreadPool) ^Callable (fn [] 3))]
(.get fut))")))
(is (nil? (bb nil "(import '(java.util.concurrent Executors ExecutorService))
(let [fut (.submit ^ExecutorService (Executors/newCachedThreadPool) ^Runnable (fn [] 3))]
(.get fut))"))))
(deftest break-iterator-test
(is (= 1 (bb nil "(ns dude
(:import [java.text BreakIterator]))
(defn count-characters
[^String text]
(let [it (BreakIterator/getCharacterInstance)]
(.setText it text)
(loop [count 0]
(if (= (.next it) BreakIterator/DONE)
count
(recur (inc count))))))
(prn
(count-characters \"🇨🇦\"))"))))

View file

@ -68,6 +68,10 @@
(is (= {:force? true :repl true} (parse-opts ["--force" "repl"])))
(is (= {:force? true :clojure true :command-line-args '("-M" "-r")}
(parse-opts ["--force" "clojure" "-M" "-r"])))
(is (= {:command-line-args '("asdf" "fdsa")}
(main/parse-opts ["--" "asdf" "fdsa"])))
(is (= {:repl true :command-line-args '("asdf" "fdsa")}
(main/parse-opts ["repl" "--" "asdf" "fdsa"])))
(testing "file opts parsing does not mess with :command-line-args"
(is (= {:prn true, :expressions ["(prn :foo)"]}
(-> (let [[_ opts] (main/parse-file-opt ["-e" "(prn :foo)"] {})]
@ -84,6 +88,18 @@
(is (not (main/satisfies-min-version? "300.0.0")))
(is (not (main/satisfies-min-version? "300.0.0-SNAPSHOT"))))
(deftest version-opt-test
(is (str/starts-with? (test-utils/bb nil "version")
"babashka v")))
(deftest help-opt-test
(is (every? #(str/includes? (test-utils/bb nil "help") %)
["Babashka v" "Help:"])))
(deftest describe-opt-test
(is (every? (partial contains? (bb nil "describe"))
[:babashka/version :feature/yaml :feature/logging])))
(deftest print-error-test
(is (thrown-with-msg? Exception #"java.lang.NullPointerException"
(bb nil "(subs nil 0 0)"))))
@ -476,7 +492,11 @@
(deftest command-line-args-test
(is (true? (bb nil "(nil? *command-line-args*)")))
(is (= ["1" "2" "3"] (bb nil "*command-line-args*" "1" "2" "3"))))
(is (= ["1" "2" "3"] (bb nil "*command-line-args*" "1" "2" "3")))
(is (str/includes? (test-utils/bb "*command-line-args*" "repl" "--" "1" "2" "3")
"(\"1\" \"2\" \"3\""))
(is (str/includes? (test-utils/bb "*command-line-args*" "--" "1" "2" "3")
"(\"1\" \"2\" \"3\"")))
(deftest constructors-test
(testing "the clojure.lang.Delay constructor works"

View file

@ -153,3 +153,10 @@
(force-gc)
@deleted?
")))
(deftest reify-dir-stream-filter
(is (true? (bb nil "
(defn get-dir-stream [^java.nio.file.Path dir-path glob-pattern]
(let [path (.toPath (java.io.File. dir-path))]
(java.nio.file.Files/newDirectoryStream path glob-pattern)))
(pos? (count (seq (get-dir-stream \".\" (reify java.nio.file.DirectoryStream$Filter (accept [_ path] (.isDirectory (.toFile path))))))))"))))