Like Docker, but for Squeak. You know, for kids.

Related tags

Miscellaneoussqueaker
Overview

Squeaker

Like Docker, but for Smalltalk images. You know, for kids.

It's a small program that helps in automated derivation of configured Smalltalk images from some fixed base image and a collection of Smalltalk commands. It's about 500 lines of Python, so far.

  • Squeakerfile.st is like Dockerfile, except it contains locations to fetch images from plus Smalltalk expressions to derive new images.

  • squeaker build is like docker build. It manages a cache (in $XDG_CACHE_HOME/squeaker, usually $HOME/.cache/squeaker on Unix) of downloaded artifacts, derived images, and the stages in each derivation.

  • squeaker run is like docker run. It starts a previously-downloaded or -derived image in a temporary directory. (Future: support persistent image instances, like docker does! Easy enough.)

  • squeaker gc is like docker system prune, roughly. It cleans out the Squeaker cache directory, treating tags as GC roots.

Installation

Install Python 3.x (I used 3.9 to build it), making sure python3 is on the PATH.

Make sure squeaker is on the PATH, too.

Usage

You can type "squeaker --help" and "squeaker subcommand --help" for terse usage information.

Downloading and customising images

The Squeakerfile.st specifying a build is written using !-delimited chunk format (see also here and below). A chunk starting with from: specifies either

  • A URL, if the argument to from: is a Smalltalk string literal, e.g.

    from: 'http://files.squeak.org/6.0alpha/Squeak6.0alpha-20582-64bit/Squeak6.0alpha-20582-64bit.zip'
    

    The URL must point to a ZIP file containing at least one *.image file and a matching *.changes file.

  • A tag, previously defined using squeaker build -t ..., if the argument to from is a quoted Smalltalk symbol literal, e.g.

    from: #'myimage'
    

Other chunks are snippets of Smalltalk to execute to configure the image, deriving another image. Chunks are applied in sequence. Squeaker caches intermediaries, like Docker does, to avoid repeated work.

Let's work with the following Squeakerfile.st:

from: 'http://files.squeak.org/6.0alpha/Squeak6.0alpha-20582-64bit/Squeak6.0alpha-20582-64bit.zip'!

World submorphs
    select: [:m |
        (m isKindOf: PreferenceWizardMorph) or:
            [m isSystemWindow and: [m label beginsWith: 'Welcome to Squeak']]]
    thenDo: [:m | m delete].
!

"Apply my preferences!!"
CommunityTheme createDark apply.
Model useColorfulWindows: true.
[Preferences setDemoFonts] valueSupplyingAnswer: true.
Cursor useBiggerCursors: true.
Preferences enable: #mouseOverForKeyboardFocus.
TextEditor autoEnclose: false.
Model windowActiveOnFirstClick: true.
!

MCMcmUpdater default doUpdate: false.
!

Metacello new configuration: 'FFI'; load.
Installer ss project: 'OSProcess'; install: 'OSProcess'.
!

Use squeaker build to build it. Here, I will tag the final image as myimage:

>asColorizedSmalltalk80Text (TextStyler is Undeclared) ========== Update completed: 20582 -> 20678 ========== INFO:root: execution: 22.103 seconds INFO:root: 57047392/57047392 (100%) archiving: squeak.image INFO:root: 20540949/20540949 (100%) archiving: squeak.changes INFO:root: archiving: 2.135 seconds INFO:root: 57047392/57047392 (100%) extracting: squeak.image INFO:root: 20540949/20540949 (100%) extracting: squeak.changes INFO:root: --- 9e4bcce29c3dba7dd48e INFO:root:Running: Metacello new configuration: 'FFI'; load. Installer ss project: 'OSProcess'; install: 'OSProcess'. ⋮ (output from Metacello and OSProcess installation elided) ⋮ loaded INFO:root: execution: 45.081 seconds INFO:root: 69034504/69034504 (100%) archiving: squeak.image INFO:root: 24673049/24673049 (100%) archiving: squeak.changes INFO:root: archiving: 2.535 seconds INFO:root:Tagging 4c8767963a0bc6ce727b as 'myimage' 4c8767963a0bc6ce727bbbdb787e7a51c36fe27fff53dfcd4e84a8f4ad13872c858e4351262ba00d8d649bf474e28e515816a0774a8a30fc4c88039985e6b4b6 $ ">
$ squeaker build -t myimage -f Squeakerfile.st .
INFO:root:Downloading http://files.squeak.org/6.0alpha/Squeak6.0alpha-20582-64bit/Squeak6.0alpha-20582-64bit.zip
INFO:root:  20519402/20519402 (100%) http://files.squeak.org/6.0alpha/Squeak6.0alpha-20582-64bit/Squeak6.0alpha-20582-64bit.zip
INFO:root:  51209408/51209408 (100%) extracting: Squeak6.0alpha-20582-64bit.image
INFO:root:  20374964/20374964 (100%) extracting: Squeak6.0alpha-20582-64bit.changes
INFO:root: --- 2d3e365261fa70f3ae6b
INFO:root:Running:
    World submorphs
    	select: [:m |
    		(m isKindOf: PreferenceWizardMorph) or:
    			[m isSystemWindow and: [m label beginsWith: 'Welcome to Squeak']]]
    	thenDo: [:m | m delete].
INFO:root:    execution: 0.249 seconds
INFO:root:  58630352/58630352 (100%) archiving: squeak.image
INFO:root:  20376501/20376501 (100%) archiving: squeak.changes
INFO:root:    archiving: 2.182 seconds
INFO:root:  58630352/58630352 (100%) extracting: squeak.image
INFO:root:  20376501/20376501 (100%) extracting: squeak.changes
INFO:root: --- a65c4397156194b571d7
INFO:root:Running:
    "Tony's preferences!"
    CommunityTheme createDark apply.
    Model useColorfulWindows: true.
    [Preferences setDemoFonts] valueSupplyingAnswer: true.
    Cursor useBiggerCursors: true.
    Preferences enable: #mouseOverForKeyboardFocus.
    TextEditor autoEnclose: false.
    Model windowActiveOnFirstClick: true.
INFO:root:    execution: 0.619 seconds
INFO:root:  62905552/62905552 (100%) archiving: squeak.image
INFO:root:  20378159/20378159 (100%) archiving: squeak.changes
INFO:root:    archiving: 2.289 seconds
INFO:root:  62905552/62905552 (100%) extracting: squeak.image
INFO:root:  20378159/20378159 (100%) extracting: squeak.changes
INFO:root: --- e80909c4f1f2f14324b2
INFO:root:Running:
    MCMcmUpdater default doUpdate: false.

MethodNode>>asColorizedSmalltalk80Text (TextStyler is Undeclared) 
==========  Update completed:  20582 -> 20678 ==========
INFO:root:    execution: 22.103 seconds
INFO:root:  57047392/57047392 (100%) archiving: squeak.image
INFO:root:  20540949/20540949 (100%) archiving: squeak.changes
INFO:root:    archiving: 2.135 seconds
INFO:root:  57047392/57047392 (100%) extracting: squeak.image
INFO:root:  20540949/20540949 (100%) extracting: squeak.changes
INFO:root: --- 9e4bcce29c3dba7dd48e
INFO:root:Running:
    Metacello new configuration: 'FFI'; load.
    Installer ss project: 'OSProcess'; install: 'OSProcess'.
 ⋮
 (output from Metacello and OSProcess installation elided)
 ⋮
loaded
INFO:root:    execution: 45.081 seconds
INFO:root:  69034504/69034504 (100%) archiving: squeak.image
INFO:root:  24673049/24673049 (100%) archiving: squeak.changes
INFO:root:    archiving: 2.535 seconds
INFO:root:Tagging 4c8767963a0bc6ce727b as 'myimage'
4c8767963a0bc6ce727bbbdb787e7a51c36fe27fff53dfcd4e84a8f4ad13872c858e4351262ba00d8d649bf474e28e515816a0774a8a30fc4c88039985e6b4b6

$

Running images

Now I can get a transient, disposable image in a temporary directory which will be deleted when the VM process terminates, by running

$ squeaker run myimage
INFO:root:Image: 4c8767963a0bc6ce727bbbdb787e7a51c36fe27fff53dfcd4e84a8f4ad13872c858e4351262ba00d8d649bf474e28e515816a0774a8a30fc4c88039985e6b4b6
INFO:root:  69034504/69034504 (100%) extracting: squeak.image
INFO:root:  24673049/24673049 (100%) extracting: squeak.changes

Screenshot of the running myimage

If I want to keep this image, I have to take care to Save as... to some other directory!

Garbage collection

During development, and after a bit of normal usage, you'll find you have a lot of unwanted intermediary images saved in the cache. You can discard those not reachable from some tag using squeaker gc.

Use squeaker gc --dry-run to get a description of what will be deleted, without deleting anything.

You can also get a picture of the (live) contents of your cache by running the Graphviz dot tool over the output of the squeaker dot command.

Here's the kind of thing it looks like:

Example graph drawn by Graphviz dot

Chunk format

"Chunk" format (1, 2) is an old, old Smalltalkism. It's a binary file, using byte 0x21 (!) as delimiter. Exclamation points are doubled to escape them: so the chunk containing the text Hello! How are you? is written

Hello!! How are you?!

The final ! terminates the chunk; the embedded !! decodes to a single !.

License and Copyright

(MIT.)

Copyright 2021 Tony Garnock-Jones [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Owner
Tony Garnock-Jones
Tony Garnock-Jones
适用于HoshinoBot下的雀魂插件。可进行近期对局查询、查询个人数据等功能,更多功能正在扩展

Majsoul_bot This is a Majsoul plugin for HoshinoBot 这是一个HoshinoBot的雀魂相关插件 本项目目前正在扩展,后续会扩展更多功能,敬请期待 前言 项目地址:https://github.com/DaiShengSheng/Majsoul_bo

黛笙笙 33 Dec 14, 2022
Ramadhan countdown - Simple daily reminder about upcoming Ramadhan

Ramadhan Countdown Bot Simple bot for displaying daily reminder about Islamic pr

Abdurrahman Shofy Adianto 1 Feb 06, 2022
pspsps(1) is a compyuter software to call an online catgirl to the Linux terminyal.

pspsps(1): call a catgirl from the Internyet to the Linux terminyal show processes: ps show catgirls: pspsps —@ Melissa Boiko 32 Dec 19, 2022

The semi-complete teardown of Cosmo's Cosmic Adventure.

The semi-complete teardown of Cosmo's Cosmic Adventure.

Scott Smitelli 10 Dec 02, 2022
A tool to quickly create codeforces contest directories with templates.

Codeforces Template Tool I created this tool to help me quickly set up codeforces contests/singular problems with templates. Tested for windows, shoul

1 Jun 02, 2022
Automatically re-open threads when they get archived, no matter your boost level!

ThreadPersist Automatically re-open threads when they get archived, no matter your boost level! Installation You will need to install poetry to run th

7 Sep 18, 2022
A Regex based linter tool that works for any language and works exclusively with custom linting rules.

renag Documentation Available Here Short for Regex (re) Nag (like "one who complains"). Now also PEGs (Parsing Expression Grammars) compatible with py

Ryan Peach 12 Oct 20, 2022
AIST++ API This repo contains starter code for using the AIST++ dataset.

Explainability for Vision Transformers (in PyTorch) This repository implements methods for explainability in Vision Transformers

Google 260 Dec 30, 2022
Given tool find related trending keywords of input keyword

blog_generator Given tool find related trending keywords of input keyword (blog_related_to_keyword). Then cretes a mini blog. Currently its customised

Shivanshu Srivastava 2 Nov 30, 2021
This repository contains the exercices for the robotics class at Supaero, 2022.

Supaero robotics, 2022 This repository contains the exercices for the robotics class at Supaero, 2022. The exercices are organized by notebook. Each n

Gepetto team, LAAS-CNRS 5 Aug 01, 2022
XHacks 2021 Startup Track Winner: Be Heard. Educate, Enact, Empower. No voice left behind. (backend)

Be Heard: X Hacks 2021 Submission Educate, Enact, Empower. No voice left behind. Inspiration To say 2020 was an eventful year would be an understateme

3 Jul 14, 2022
Simple dependency injection framework for Python

A simple, strictly typed dependency injection library.

BentoML 14 Jun 29, 2022
Block when attacker want to bypass the limit of request

Block when attacker want to bypass the limit of request

iFanpS 1 Dec 01, 2021
A very terrible python-based programming language that uses folders instead of text files

PYFolders by Lewis L. Foster PYFolders is a very terrible python-based programming language that uses folders instead of regular text files. In this r

Lewis L. Foster 5 Jan 08, 2022
An execution framework for systematic strategies

WAGMI is an execution framework for systematic strategies. It is very much a work in progress, please don't expect it to work! Architecture The Django

Rich Atkinson 10 Mar 28, 2022
Python wrapper around Apple App Store Api

App Store Connect Api This is a Python wrapper around the Apple App Store Api : https://developer.apple.com/documentation/appstoreconnectapi So far, i

123 Jan 06, 2023
Easily Generate Revolut Business Cards

RevBusinessCardGen Easily Generate Revolut Business Cards Prerequisites Before you begin, ensure you have met the following requirements: You have ins

Younes™ 35 Dec 14, 2022
School helper, helps you at your pyllabus's.

pyllabus, helps you at your syllabus's... WARNING: It won't run without config.py! You should add config.py yourself, it will include your APIKEY. e.g

Ahmet Efe AKYAZI 6 Aug 07, 2022
The only purpose of a byte-sized application is to help you create .desktop entry files for downloaded applications.

Turtle 🐢 The only purpose of a byte-sized application is to help you create .desktop entry files for downloaded applications. As of usual with elemen

TenderOwl 14 Dec 29, 2022
Age of Empires II recorded game parsing and summarization in Python 3.

mgz Age of Empires II recorded game parsing and summarization in Python 3. Supported Versions Age of Kings (.mgl) The Conquerors (.mgx) Userpatch 1.4

148 Dec 11, 2022