diff --git a/CLAUDE.md b/CLAUDE.md index c4cf977..1b4fbc0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -36,7 +36,7 @@ Use [`docs/README.md`](docs/README.md) as the entrypoint for CC:Tweaked, CraftOS - `startup/servers.lua` creates the boot eventloop, runs autostart server files (which register handlers and return), then runs the shell and the eventloop in parallel via `parallel.waitForAny`. - Preserve `periphemu` guards used for CraftOS-PC emulation; see [`docs/craftos_pc_glossary.md`](docs/craftos_pc_glossary.md) for upstream emulator references. - TrapOS ships as packages, each described by `packages//ccpm.json` (`name`, `version`, `dependencies`, `files`, `autostart`); `packages/index.json` lists them. Source files stay in place — descriptors only reference them. To ship a new file, add it to the right package's `files` (and `autostart` if it is a server). `packages/trapos/ccpm.json` is the full OS meta-package. See [ADR-0010](docs/adrs/adr-0010-ccpm-package-manager.md). -- `install-ccpm.lua` is the one-time wget bootstrap. It installs only `trapos-core`/`ccpm`, seeds the default `guillaumearm/cc-libs` registry on `master` (or `next` with `--beta`), and tells users to run `ccpm update` then `ccpm install trapos`. +- `install-ccpm.lua` is the one-time wget bootstrap. It installs only `trapos-core`/`ccpm`, seeds the default `guillaumearm/cc-libs` registry as a `gitea` registry on `git.trapcloud.fr` tracking `master` (or `next` with `--beta`), and tells users to run `ccpm update` then `ccpm install trapos`. The legacy `github` registry type still resolves but is deprecated. - `ccpm` (in `trapos-core`) is the package manager: `apis/libccpm.lua` is the testable core (factory with injectable `http`/`stateDir`/`installRoot`), `programs/ccpm.lua` the CLI. State: `/trapos/ccpm.json` (registries), `/trapos/ccpm.lock.json` (installed packages), and `/trapos/ccpm.cache.json` (available packages from `ccpm update`). Never use the word "manifest" in ccpm — it is reserved for the OS manifest. - Add new servers to `startup/servers.lua` as needed. diff --git a/README.md b/README.md index 891d979..5e1bf1c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A small in-game operating system for ComputerCraft / CC:Tweaked, built around a Install `ccpm` first. This is the only step that needs `wget` with a URL: ``` -wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/master/install-ccpm.lua +wget run https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/master/install-ccpm.lua ``` Then sync the default registry (`guillaumearm/cc-libs`) and install TrapOS: @@ -23,7 +23,7 @@ Install individual packages instead if you want to cherry-pick: Install `ccpm` from the beta branch (one-time opt-in, asks for confirmation): ``` -wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/next/install-ccpm.lua --beta +wget run https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/next/install-ccpm.lua --beta ``` Once `ccpm` is installed from beta, the default registry tracks `next`; `ccpm update` and `ccpm upgrade` keep using that branch. @@ -56,7 +56,7 @@ ccpm install ccpm reinstall ccpm uninstall ccpm update ccpm upgrade ccpm ls ccpm available [term] ccpm search [term] ccpm info -ccpm registry ls ccpm registry add [--branch ] [--type github|http] +ccpm registry ls ccpm registry add [--branch ] [--type gitea|github|http] ccpm registry rm ``` diff --git a/apis/libccpm.lua b/apis/libccpm.lua index 314a1af..06fc05e 100644 --- a/apis/libccpm.lua +++ b/apis/libccpm.lua @@ -85,7 +85,7 @@ local function createCcpm(opts) end local registry = { name = name, - type = registryOpts.type or 'github', + type = registryOpts.type or 'gitea', branch = registryOpts.branch or 'master', }; cfg.registries[#cfg.registries + 1] = registry; @@ -176,6 +176,9 @@ local function createCcpm(opts) if registry.type == 'github' then local branch = registry.branch or 'master'; return 'https://raw.githubusercontent.com/' .. registry.name .. '/' .. branch .. '/'; + elseif registry.type == 'gitea' then + local branch = registry.branch or 'master'; + return 'https://git.trapcloud.fr/' .. registry.name .. '/raw/branch/' .. branch .. '/'; end local base = registry.name; if base:sub(-1) ~= '/' then base = base .. '/'; end diff --git a/docs/adrs/adr-0010-ccpm-package-manager.md b/docs/adrs/adr-0010-ccpm-package-manager.md index 840d39a..e1b64a8 100644 --- a/docs/adrs/adr-0010-ccpm-package-manager.md +++ b/docs/adrs/adr-0010-ccpm-package-manager.md @@ -53,7 +53,9 @@ To avoid colliding with the OS `manifest.json`, ccpm never uses the word "manife Local state lives under `/trapos`: - `ccpm.json` — ordered registry list `{ registries = { { name, type, branch } } }`. - `type` is `github` (resolves to `raw.githubusercontent.com///`) or + `type` is `gitea` (resolves to `git.trapcloud.fr//raw/branch//`, the + default seeded by the bootstrap), `github` (resolves to + `raw.githubusercontent.com///`, deprecated but still supported), or `http`/`https` (the `name` is a base URL). - `ccpm.lock.json` — installed packages `{ packages = { = { version, registry, files, dependencies, autostart } } }`, used by `ls`, `uninstall`, and `reinstall`. diff --git a/docs/ingame-trapos-ai-mcp-guide.md b/docs/ingame-trapos-ai-mcp-guide.md index 5378a28..2e20403 100644 --- a/docs/ingame-trapos-ai-mcp-guide.md +++ b/docs/ingame-trapos-ai-mcp-guide.md @@ -7,7 +7,7 @@ Follow this order while playing. On the ComputerCraft computer: ```sh -wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/next/install-ccpm.lua --beta +wget run https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/next/install-ccpm.lua --beta ccpm update ccpm install trapos ``` diff --git a/docs/opencode_server_guide.md b/docs/opencode_server_guide.md index a15dd41..71b2f08 100644 --- a/docs/opencode_server_guide.md +++ b/docs/opencode_server_guide.md @@ -17,7 +17,7 @@ CC Computer On a fresh CC computer (beta branch): ``` -wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/next/install-ccpm.lua --beta +wget run https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/next/install-ccpm.lua --beta ccpm update ccpm install trapos ``` diff --git a/install-ccpm.lua b/install-ccpm.lua index 8580bc4..820ec50 100644 --- a/install-ccpm.lua +++ b/install-ccpm.lua @@ -1,6 +1,6 @@ -local _VERSION = '5.0.1'; +local _VERSION = '5.1.0'; -local REPO_BASE = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/'; +local REPO_BASE = 'https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/'; local LOCAL_STATE_DIR = '/trapos'; local LOCAL_MANIFEST_PATH = '/trapos/manifest.json'; local LOCAL_CONFIG_PATH = '/trapos/ccpm.json'; @@ -113,13 +113,13 @@ local function seedCcpmConfig(branch) local found = false; for _, r in ipairs(cfg.registries) do if r.name == DEFAULT_REGISTRY_NAME then - r.type = 'github'; + r.type = 'gitea'; r.branch = branch; found = true; end end if not found then - table.insert(cfg.registries, 1, { name = DEFAULT_REGISTRY_NAME, type = 'github', branch = branch }); + table.insert(cfg.registries, 1, { name = DEFAULT_REGISTRY_NAME, type = 'gitea', branch = branch }); end writeJsonFile(LOCAL_CONFIG_PATH, cfg); end diff --git a/packages/index.json b/packages/index.json index 500c906..e132486 100644 --- a/packages/index.json +++ b/packages/index.json @@ -1,6 +1,6 @@ { "packages": { - "trapos-core": "0.4.0", + "trapos-core": "0.5.0", "trapos-test": "0.2.1", "trapos-boot": "0.3.2", "trapos-net": "0.3.0", diff --git a/packages/trapos-core/ccpm.json b/packages/trapos-core/ccpm.json index 4c812a3..ace6815 100644 --- a/packages/trapos-core/ccpm.json +++ b/packages/trapos-core/ccpm.json @@ -1,6 +1,6 @@ { "name": "trapos-core", - "version": "0.4.0", + "version": "0.5.0", "description": "TrapOS base: package manager, event loop, upgrade and event tools", "dependencies": [], "files": [ diff --git a/programs/ccpm.lua b/programs/ccpm.lua index 2861f35..70086f7 100644 --- a/programs/ccpm.lua +++ b/programs/ccpm.lua @@ -17,7 +17,7 @@ local function printUsage() print('\t\tccpm search [term]'); print('\t\tccpm info '); print('\t\tccpm registry ls'); - print('\t\tccpm registry add [--branch ] [--type github|http]'); + print('\t\tccpm registry add [--branch ] [--type github|gitea|http]'); print('\t\tccpm registry rm '); print('\t\tccpm version'); print('\t\tccpm help'); @@ -180,6 +180,8 @@ if command == 'registry' then for _, r in ipairs(registries) do if r.type == 'github' then print(r.name .. ' (github:' .. tostring(r.branch or 'master') .. ')'); + elseif r.type == 'gitea' then + print(r.name .. ' (gitea:' .. tostring(r.branch or 'master') .. ')'); else print(r.name .. ' (' .. tostring(r.type or 'http') .. ')'); end diff --git a/tests/ccpm.lua b/tests/ccpm.lua index 79373a2..9eca6b9 100644 --- a/tests/ccpm.lua +++ b/tests/ccpm.lua @@ -33,6 +33,10 @@ local function ghBase(name, branch) return 'https://raw.githubusercontent.com/' .. name .. '/' .. branch .. '/'; end +local function giteaBase(name, branch) + return 'https://git.trapcloud.fr/' .. name .. '/raw/branch/' .. branch .. '/'; +end + testlib.test('registryBaseUrl resolves a github branch', function() local ccpm = createCcpm({ stateDir = freshDirs() }); testlib.assertEquals( @@ -41,6 +45,18 @@ testlib.test('registryBaseUrl resolves a github branch', function() ); end); +testlib.test('registryBaseUrl resolves a gitea branch', function() + local ccpm = createCcpm({ stateDir = freshDirs() }); + testlib.assertEquals( + ccpm.registryBaseUrl({ name = 'guillaumearm/cc-libs', type = 'gitea', branch = 'next' }), + 'https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/next/' + ); + testlib.assertEquals( + ccpm.descriptorUrl({ name = 'guillaumearm/cc-libs', type = 'gitea', branch = 'next' }, 'trapos-net'), + 'https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/next/packages/trapos-net/ccpm.json' + ); +end); + testlib.test('registry urls resolve an http base', function() local ccpm = createCcpm({ stateDir = freshDirs() }); testlib.assertEquals( @@ -128,6 +144,32 @@ testlib.test('install downloads files and records the lock', function() testlib.assertEquals(lock.packages['trapos-net'].registry, 'me/repo'); end); +testlib.test('install downloads files from a gitea registry', function() + local base = giteaBase('guillaumearm/cc-libs', 'next'); + local routes = { + [base .. 'packages/trapos-core/ccpm.json'] = textutils.serializeJSON({ name = 'trapos-core', version = '1', dependencies = {}, files = { 'apis/eventloop.lua' } }), + [base .. 'packages/trapos-net/ccpm.json'] = textutils.serializeJSON({ name = 'trapos-net', version = '1', dependencies = { 'trapos-core' }, files = { 'apis/net.lua' } }), + [base .. 'apis/eventloop.lua'] = 'eventloop-body', + [base .. 'apis/net.lua'] = 'net-body', + }; + local sd, root = freshDirs(); + local ccpm = createCcpm({ stateDir = sd, installRoot = root, http = fakeHttp(routes) }); + ccpm.writeConfig({ registries = { { name = 'guillaumearm/cc-libs', type = 'gitea', branch = 'next' } } }); + + local ok = ccpm.install('trapos-net', {}); + testlib.assertTrue(ok); + testlib.assertTrue(fs.exists(root .. '/apis/net.lua')); + testlib.assertTrue(fs.exists(root .. '/apis/eventloop.lua')); + + local f = fs.open(root .. '/apis/net.lua', 'r'); + local body = f.readAll(); + f.close(); + testlib.assertEquals(body, 'net-body'); + + local lock = ccpm.readLock(); + testlib.assertEquals(lock.packages['trapos-net'].registry, 'guillaumearm/cc-libs'); +end); + testlib.test('installing trapos writes aggregated os state', function() local base = ghBase('me/repo', 'master'); local routes = { @@ -171,6 +213,30 @@ testlib.test('registry add and remove round-trip', function() testlib.assertTrue(not rmOk); end); +testlib.test('addRegistry defaults to a gitea registry', function() + local ccpm = createCcpm({ stateDir = freshDirs() }); + ccpm.writeConfig({ registries = {} }); + + local ok, registry = ccpm.addRegistry('foo/bar', {}); + testlib.assertTrue(ok); + testlib.assertEquals(registry.type, 'gitea'); + testlib.assertEquals(registry.branch, 'master'); + + local regs = ccpm.listRegistries(); + testlib.assertEquals(regs[1].type, 'gitea'); + -- The default registry must not silently fall back to github. + testlib.assertTrue(regs[1].type ~= 'github'); + testlib.assertEquals( + ccpm.registryBaseUrl(regs[1]), + 'https://git.trapcloud.fr/foo/bar/raw/branch/master/' + ); + + -- An explicit type is still honored (github stays supported but opt-in). + testlib.assertTrue(ccpm.addRegistry('legacy/repo', { type = 'github' })); + local legacy = ccpm.listRegistries()[2]; + testlib.assertEquals(legacy.type, 'github'); +end); + testlib.test('compareVersions treats padded zeros as equal', function() -- compareVersions is internal; probe via available() status local ccpm = createCcpm({ stateDir = freshDirs() }); diff --git a/tests/install-ccpm.lua b/tests/install-ccpm.lua index de985e4..67bbb5c 100644 --- a/tests/install-ccpm.lua +++ b/tests/install-ccpm.lua @@ -56,7 +56,7 @@ testlib.test('fresh beta bootstrap leaves ccpm runnable without trapos-boot', fu fs.delete(root); fs.makeDir(root); - local base = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/next/'; + local base = 'https://git.trapcloud.fr/guillaumearm/cc-libs/raw/branch/next/'; local routes = { [base .. 'manifest.json'] = textutils.serializeJSON({ name = 'TrapOS', version = 'test' }), [base .. 'packages/trapos-core/ccpm.json'] = textutils.serializeJSON({ @@ -115,6 +115,7 @@ testlib.test('fresh beta bootstrap leaves ccpm runnable without trapos-boot', fu local config = textutils.unserializeJSON(f.readAll()); f.close(); testlib.assertEquals(config.registries[1].branch, 'next'); + testlib.assertEquals(config.registries[1].type, 'gitea'); end); testlib.run();