aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)Author
2022-08-25option.lisp: Update copyright yearbundle-lisp-dependenciesTeddy Wing
2022-08-25option.lisp: Define version string at compile timeTeddy Wing
Otherwise we get a runtime error when running the binary on a different machine than the one that built it: $ extreload -V error: Failed to find the WRITE-DATE of /private/tmp/extreload-20220825-3720-17mi6k3/extreload_0.0.2/bundle/local-projects/: No such file or directory
2022-08-25Update copyright dates after bundle changesTeddy Wing
2022-08-25extreload.asd: Turn off SSL in `websocket-driver-client`Teddy Wing
SSL is unnecessary for our purposes, and including it causes a runtime error when the path to `libcrypto.dylib` is different on the executing machine than it is on the build machine. This is the error I got when running `extreload` on an Apple Silicon machine with Homebrew, using a package bundled by an x86 machine with Homebrew: $ extreload debugger invoked on a SIMPLE-ERROR in thread #<THREAD "main thread" RUNNING {70024E0003}>: Error opening shared object "/usr/local/opt/openssl/lib/libcrypto.dylib": dlopen(/usr/local/opt/openssl/lib/libcrypto.dylib, 0x000A): tried: '/usr/local/opt/openssl/lib/libcrypto.dylib' (no such file). Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [CONTINUE ] Skip this shared object and continue. 1: [RETRY ] Retry loading this shared object. 2: [CHANGE-PATHNAME] Specify a different pathname to load the shared object from. 3: [ABORT ] Exit from the current thread. (SB-SYS:DLOPEN-OR-LOSE #S(SB-ALIEN::SHARED-OBJECT :PATHNAME #P"/usr/local/opt/openssl/lib/libcrypto.dylib" :NAMESTRING "/usr/local/opt/openssl/lib/libcrypto.dylib" :HANDLE NIL :DONT-SAVE NIL)) 0]
2022-08-25Makefile: Rewrite `pkg` target to include bundle and sourceTeddy Wing
Copy the `pkg` target from Wajir to make a tarball of the bundled dependencies in `bundle` and the Extreload source code. This tarball can then be distributed and the program can be built and installed from it using the Makefile. By distributing the source, an executable can be built for more architectures and systems.
2022-08-25Makefile: Add dependencies on `bundle` targetTeddy Wing
2022-08-25bundle.lisp: Remove `sysexits` from `local-dependencies` listTeddy Wing
Sysexits is now in Quicklisp so we don't need to load it here.
2022-08-23Makefile: Add an `install` targetTeddy Wing
Make it easy for package managers to build and install the program.
2022-08-23Makefile: Add self-contained bundle targetTeddy Wing
Add a target to create a self-contained bundle of the program that isn't dependent on Quicklisp. This code is based on what I did in Wajir.
2022-08-22Remove `lib/with-user-abort` submoduleTeddy Wing
With-user-abort is now in Quicklisp.
2022-08-22Remove `lib/sysexits` submoduleTeddy Wing
Sysexits is now in Quicklisp.
2021-03-03README: Add a note about pre-built binaries being availableTeddy Wing
2021-03-02Increase version v0.0.1 -> v0.0.2v0.0.2Teddy Wing
2021-03-02Update TODOTeddy Wing
2021-03-02main: Exit on Control-c interruptTeddy Wing
Use the `with-user-abort` library to catch an interrupt signal from `<C-c>` and exit immediately. Otherwise, the Lisp debugger is invoked, which is not the expected behaviour for a command line program. Tried putting the `user-abort` condition in the `handler-case` in `main`, but it didn't appear to be caught in my tests. Decided to catch it with `handler-case` immediately instead, confirming this works. Unfortunately, if `<C-c>` is received before entering `main` (by running the program and immediately pressing it), our handler won't get called, and instead the Lisp debugger will be invoked. Not sure how to deal with that, so I've decided not to bother.
2021-03-01Makefile: Add source dependencies to `extreload` buildTeddy Wing
2021-03-01Add 'with-user-abort' library dependencyTeddy Wing
For `<C-c>` handling.
2021-03-01Update TODOTeddy Wing
2021-02-27README: Add submodule documentationv0.0.1Teddy Wing
2021-02-27Add `wait-group` library dependencyTeddy Wing
2021-02-27Makefile: Add target to build a distributable packageTeddy Wing
2021-02-27Add READMETeddy Wing
2021-02-27Add license (GNU GPLv3+)Teddy Wing
2021-02-27Makefile: Remove `release` targetTeddy Wing
Not using ECL any more. Instead we're continuing to build with SBCL and enable binary compression.
2021-02-27Update TODOTeddy Wing
2021-02-27Add man pageTeddy Wing
2021-02-27Move everything from `l/` into the project rootTeddy Wing
This is the final project. Now that we got rid of the web extension and native host code, we can move the Lisp code to the root.
2021-02-27Move `l/lib/sysexits` to `lib/sysexits`Teddy Wing
2021-02-27Remove web extension and native messaging hostTeddy Wing
This code is superseded by the Common Lisp project that communicates via the DevTools Protocol. The `chrome.management` API's `setEnabled()` function just allowed me to turn extensions off and on. It didn't reload the extensions. The DevTools Protocol allows us to execute JavaScript in the context of an extension's background page. This allows us to run `chrome.runtime.reload()` in an extension's context, properly reloading the extension.
2021-02-27Update TODOTeddy Wing
2021-02-27main: Add documentationTeddy Wing
2021-02-27main: Remove unused globalsTeddy Wing
I used these for debugging, but they aren't relevant any more.
2021-02-27main: Move command line option definitions to `option.lisp`Teddy Wing
Makes more sense to group the option code together.
2021-02-27option: Add documentationTeddy Wing
2021-02-27macro: Add documentationTeddy Wing
2021-02-27ws-on-message: Move predicate checking tab reload exception to functionTeddy Wing
Give this check a name.
2021-02-27devtools-protocol: Add documentationTeddy Wing
2021-02-27call-id: Add documentationTeddy Wing
2021-02-27Update TODOTeddy Wing
2021-02-27Hide `websocket-send` debug output behind `--debug` flagTeddy Wing
Make the config containing command line options a global variable. This makes it easy to find out if the `--debug` flag is on in the `websocket-send` function. Not sure about the global variable, but seems fine for now.
2021-02-21make-config: Add function documentationTeddy Wing
2021-02-21When `chrome.tabs.reload()` errors, double decrement the wait groupTeddy Wing
We added an extra increment to the wait group in the `reload-tab` function because when the `chrome.tabs.reload()` message succeeds, we receive two response messages for a single one sent. When an error comes back from the message, however, only one message is received instead of two. We must thus decrement the wait group an extra time to account for the lack of a second response message. Here's what the message sequence looks like: #<WAIT-GROUP :counter 6> Sending: {"id":2,"sessionId":"C67B0BF214B28E1233277D01B897438E","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (id . 2) (result OBJ (result OBJ (type . object) (subtype . error) (className . TypeError) (description . TypeError: Cannot read property 'reload' of undefined at <anonymous>:1:13) (objectId . 1547982045888266898.197.11)) (exceptionDetails OBJ (exceptionId . 15) (text . Uncaught) (lineNumber . 0) (columnNumber . 12) (scriptId . 1569) (exception OBJ (type . object) (subtype . error) (className . TypeError) (description . TypeError: Cannot read property 'reload' of undefined at <anonymous>:1:13) (objectId . 1547982045888266898.197.12)))) (sessionId . C67B0BF214B28E1233277D01B897438E)) #<WAIT-GROUP :counter 7> Sending: {"id":2,"sessionId":"C67B0BF214B28E1233277D01B897438E","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (id . 2) (result OBJ (result OBJ (type . object) (subtype . error) (className . TypeError) (description . TypeError: Cannot read property 'reload' of undefined at <anonymous>:1:13) (objectId . 1547982045888266898.197.13)) (exceptionDetails OBJ (exceptionId . 16) (text . Uncaught) (lineNumber . 0) (columnNumber . 12) (scriptId . 1569) (exception OBJ (type . object) (subtype . error) (className . TypeError) (description . TypeError: Cannot read property 'reload' of undefined at <anonymous>:1:13) (objectId . 1547982045888266898.197.14)))) (sessionId . C67B0BF214B28E1233277D01B897438E)) #<WAIT-GROUP :counter 8> Sending: {"id":2,"sessionId":"C67B0BF214B28E1233277D01B897438E","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (id . 2) (result OBJ (result OBJ (type . undefined))) (sessionId . C67B0BF214B28E1233277D01B897438E)) #<WAIT-GROUP :counter 9>
2021-02-21Remove hard-coded call ID commentsTeddy Wing
We no longer have hard-coded call IDs, so these comments are outdated. The new call ID system seems to also contribute to keeping tab reloading working consistently, so I'm keeping it instead of going back to the hard-coded IDs.
2021-02-21reload-tab: Fix inconsistent tab reloadingTeddy Wing
Finally managed to figure out why tab reloading was inconsistent. With my added logs, I learned that _two_ responses come back from the `chrome.tabs.reload()` message we send instead of one. This means that the wait group gets decremented prematurely, and the program could exit before we've transmitted the message(s). To fix this, increment the wait group an extra time when sending the tab reload message to account for the second message response. Here are the logs: One tab reloaded, one not: #<WAIT-GROUP :counter 1> Sending: {"id":2,"method":"Target.attachToTarget","params":{"targetId":"E1DA65BA7761486BBA9B341E5403744F","flatten":true}} Sending: {"id":3,"method":"Target.attachToTarget","params":{"targetId":"84AFD21582910FC66AD0FB24E410BBC1","flatten":true}} Response: (OBJ (method . Target.attachedToTarget) (params OBJ (sessionId . C2BBFC26103DAB67ECC199C87CB38B86) (targetInfo OBJ (targetId . E1DA65BA7761486BBA9B341E5403744F) (type . background_page) (title . TITLE) (url . chrome-extension://EXTENSION_ID/_generated_background_page.html) (attached . T) (canAccessOpener) (browserContextId . 29837CF1E6AC13B4FDA7DD2883E6320E)) (waitingForDebugger))) #<WAIT-GROUP :counter 2> Sending: {"id":1,"sessionId":"C2BBFC26103DAB67ECC199C87CB38B86","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}} Response: (OBJ (id . 2) (result OBJ (sessionId . C2BBFC26103DAB67ECC199C87CB38B86))) #<WAIT-GROUP :counter 2> Sending: {"id":2,"sessionId":"C2BBFC26103DAB67ECC199C87CB38B86","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (method . Target.attachedToTarget) (params OBJ (sessionId . 9ED44EDF0DA25CE52F21AA90EBAEF7D7) (targetInfo OBJ (targetId . 84AFD21582910FC66AD0FB24E410BBC1) (type . background_page) (title . TITLE) (url . chrome-extension://EXTENSION_ID/_generated_background_page.html) (attached . T) (canAccessOpener) (browserContextId . E3DEC22E4F9847AAA674ACF4781D51A9)) (waitingForDebugger))) #<WAIT-GROUP :counter 2> Sending: {"id":3,"sessionId":"9ED44EDF0DA25CE52F21AA90EBAEF7D7","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}} Response: (OBJ (id . 3) (result OBJ (sessionId . 9ED44EDF0DA25CE52F21AA90EBAEF7D7))) #<WAIT-GROUP :counter 2> Sending: {"id":4,"sessionId":"9ED44EDF0DA25CE52F21AA90EBAEF7D7","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (id . 1) (result OBJ (result OBJ (type . undefined))) (sessionId . C2BBFC26103DAB67ECC199C87CB38B86)) #<WAIT-GROUP :counter 2> Response: (OBJ (id . 3) (result OBJ (result OBJ (type . undefined))) (sessionId . 9ED44EDF0DA25CE52F21AA90EBAEF7D7)) #<WAIT-GROUP :counter 1> Both tabs reloaded: #<WAIT-GROUP :counter 1> Sending: {"id":2,"method":"Target.attachToTarget","params":{"targetId":"84AFD21582910FC66AD0FB24E410BBC1","flatten":true}} Sending: {"id":3,"method":"Target.attachToTarget","params":{"targetId":"E1DA65BA7761486BBA9B341E5403744F","flatten":true}} Response: (OBJ (method . Target.attachedToTarget) (params OBJ (sessionId . A1BD02811FD42011A5325723F2D31819) (targetInfo OBJ (targetId . 84AFD21582910FC66AD0FB24E410BBC1) (type . background_page) (title . TITLE) (url . chrome-extension://EXTENSION_ID/_generated_background_page.html) (attached . T) (canAccessOpener) (browserContextId . E3DEC22E4F9847AAA674ACF4781D51A9)) (waitingForDebugger))) #<WAIT-GROUP :counter 2> Sending: {"id":1,"sessionId":"A1BD02811FD42011A5325723F2D31819","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}} Response: (OBJ (id . 2) (result OBJ (sessionId . A1BD02811FD42011A5325723F2D31819))) #<WAIT-GROUP :counter 2> Sending: {"id":2,"sessionId":"A1BD02811FD42011A5325723F2D31819","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (method . Target.attachedToTarget) (params OBJ (sessionId . 4DC48E49A8133A13BED664D9C466F892) (targetInfo OBJ (targetId . E1DA65BA7761486BBA9B341E5403744F) (type . background_page) (title . TITLE) (url . chrome-extension://EXTENSION_ID/_generated_background_page.html) (attached . T) (canAccessOpener) (browserContextId . 29837CF1E6AC13B4FDA7DD2883E6320E)) (waitingForDebugger))) #<WAIT-GROUP :counter 2> Sending: {"id":3,"sessionId":"4DC48E49A8133A13BED664D9C466F892","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}} Response: (OBJ (id . 3) (result OBJ (sessionId . 4DC48E49A8133A13BED664D9C466F892))) #<WAIT-GROUP :counter 2> Sending: {"id":4,"sessionId":"4DC48E49A8133A13BED664D9C466F892","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}} Response: (OBJ (id . 1) (result OBJ (result OBJ (type . undefined))) (sessionId . A1BD02811FD42011A5325723F2D31819)) #<WAIT-GROUP :counter 2> Response: (OBJ (id . 2) (result OBJ (result OBJ (type . undefined))) (sessionId . A1BD02811FD42011A5325723F2D31819)) #<WAIT-GROUP :counter 1> Response: (OBJ (id . 3) (result OBJ (result OBJ (type . undefined))) (sessionId . 4DC48E49A8133A13BED664D9C466F892)) #<WAIT-GROUP :counter 0> Response: (OBJ (id . 4) (result OBJ (result OBJ (type . undefined))) (sessionId . 4DC48E49A8133A13BED664D9C466F892)) #<WAIT-GROUP :counter -1>
2021-02-21websocket-send: Add debug output for WebSocket message sendTeddy Wing
Realised I'm only printing the received messages. It would help to see what messages we send and when too. Still having the inconsistent tab reload problem, so it looks like my 16c8122254725805be666cf065c590d54d66dfad change didn't fix it.
2021-02-21Add `--debug` option to print debug outputTeddy Wing
Let's keep a way to print WebSocket messages for debugging purposes in the release build rather than remove the messages completely. Since I've been struggling with the messages so much it seems like this could be a useful thing to have.
2021-02-21Update TODOTeddy Wing
2021-02-21main: Replace hard-coded call IDs with a new counterTeddy Wing
Looks like this was the answer to the problem of the active tab not reloading consistently. Previously, if I had two instances of an extension loaded in two separate Chrome profiles, the following could happen: 1. Neither profile's active tab reloaded 2. Only one profile's active tab reloaded 3. Both profiles' active tabs reloaded With this change, both profiles' active tabs reload correctly and consistently.
2021-02-21ws-on-message: Adjust debug messagesTeddy Wing
Move the response print calls to the top of the WebSocket message receiver to make debug output chronology easier to follow.
2021-02-14extreload.asd: Compress SBCL executableTeddy Wing
The default executable compiled by SBCL is huge. Copied code from: https://lispcookbook.github.io/cl-cookbook/scripting.html#building-a-smaller-binary-with-sbcls-core-compression to produce a smaller executable. Here's the size comparison: $ du -hs extreload* 11M extreload-ecl 58M extreload-sbcl 15M extreload-sbcl-compressed