From: stephan Date: Tue, 29 Aug 2023 15:39:57 +0000 (+0000) Subject: Get the JS SQLTester command handlers in place sans those which have to run SQL. X-Git-Tag: version-3.44.0~239^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=69a55ca17dc711a9b75eb738ab32336936d69fd7;p=thirdparty%2Fsqlite.git Get the JS SQLTester command handlers in place sans those which have to run SQL. FossilOrigin-Name: d21b1217964a53f33b7ba3958b34aa8560dff8ede33e66f54aa0afbab7099ec3 --- diff --git a/ext/jni/src/org/sqlite/jni/tester/SQLTester.java b/ext/jni/src/org/sqlite/jni/tester/SQLTester.java index e355fe7603..f7550c8e46 100644 --- a/ext/jni/src/org/sqlite/jni/tester/SQLTester.java +++ b/ext/jni/src/org/sqlite/jni/tester/SQLTester.java @@ -336,7 +336,9 @@ public class SQLTester { } sqlite3 setCurrentDb(int n) throws Exception{ - return affirmDbId(n).aDb[n]; + affirmDbId(n); + iCurrentDb = n; + return this.aDb[n]; } sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; } @@ -399,7 +401,7 @@ public class SQLTester { nullView = "nil"; emitColNames = false; iCurrentDb = 0; - dbInitSql.append("SELECT 1;"); + //dbInitSql.append("SELECT 1;"); } void setNullValue(String v){nullView = v;} diff --git a/ext/wasm/SQLTester/SQLTester.mjs b/ext/wasm/SQLTester/SQLTester.mjs index 3af83e9e71..0461beb86f 100644 --- a/ext/wasm/SQLTester/SQLTester.mjs +++ b/ext/wasm/SQLTester/SQLTester.mjs @@ -64,11 +64,9 @@ SQLTesterException.toss = (...args)=>{ } class DbException extends SQLTesterException { - constructor(...args){ - super(...args); - //TODO... - //const db = args[0]; - //if( db instanceof sqlite3.oo1.DB ) + constructor(pDb, rc, closeDb){ + super("DB error #"+rc+": "+sqlite3.capi.sqlite3_errmsg(pDb)); + if( closeDb ) sqlite3.capi.sqlite3_close_v2(pDb); } isFatal() { return true; } } @@ -150,9 +148,14 @@ class Outer { return this; } - setOutputPrefix( func ){ - this.getOutputPrefix = func; - return this; + outputPrefix(){ + if( 0==arguments.length ){ + return (this.getOutputPrefix + ? (this.getOutputPrefix() ?? '') : ''); + }else{ + this.getOutputPrefix = arguments[0]; + return this; + } } verboseN(lvl, argv){ @@ -179,7 +182,7 @@ class Outer { class SQLTester { - #outer = new Outer().setOutputPrefix( ()=>'SQLTester: ' ); + #outer = new Outer().outputPrefix( ()=>'SQLTester: ' ); #aFiles = []; #inputBuffer = []; #resultBuffer = []; @@ -189,16 +192,34 @@ class SQLTester { }); #emitColNames = false; #keepGoing = false; - #aDb = []; #db = newObj({ - list: [], - iCurrent: 0, + list: new Array(7), + iCurrentDb: 0, initialDbName: "test.db", + initSql: ['select 1;'], + currentDb: function(){ + return this.list[this.iCurrentDb]; + } }); constructor(){ } + outln(...args){ return this.#outer.outln(...args); } + out(...args){ return this.#outer.out(...args); } + + reset(){ + this.clearInputBuffer(); + this.clearResultBuffer(); + this.#clearBuffer(this.#db.initSql); + this.closeAllDbs(); + this.nTest = 0; + this.nullView = "nil"; + this.emitColNames = false; + this.#db.iCurrentDb = 0; + this.#db.initSql.push("SELECT 1;"); + } + appendInput(line, addNL){ this.#inputBuffer.push(line); if( addNL ) this.#inputBuffer.push('\n'); @@ -208,20 +229,195 @@ class SQLTester { if( addNL ) this.#resultBuffer.push('\n'); } - clearInputBuffer(){ - this.#inputBuffer.length = 0; - return this.#inputBuffer; - } - clearResultBuffer(){ - this.#resultBuffer.length = 0; - return this.#resultBuffer; + #clearBuffer(buffer){ + buffer.length = 0; + return buffer; } + clearInputBuffer(){ return this.#clearBuffer(this.#inputBuffer); } + clearResultBuffer(){return this.#clearBuffer(this.#resultBuffer); } + getInputText(){ return this.#inputBuffer.join(''); } getResultText(){ return this.#resultBuffer.join(''); } + #takeBuffer(buffer){ + const s = buffer.join(''); + buffer.length = 0; + return s; + } + + takeInputBuffer(){ + return this.#takeBuffer(this.#inputBuffer); + } + takeResultBuffer(){ + return this.#takeBuffer(this.#resultBuffer); + } + verbosity(...args){ return this.#outer.verbosity(...args); } + nullValue(){ + if( 0==arguments.length ){ + return this.#nullView; + }else{ + this.#nullView = ''+arguments[0]; + } + } + + outputColumnNames(){ + if( 0==arguments.length ){ + return this.#emitColNames; + }else{ + this.#emitColNames = !!arguments[0]; + } + } + + currentDbId(){ + if( 0==arguments.length ){ + return this.#db.iCurrentDb; + }else{ + this.#affirmDbId(arguments[0]).#db.iCurrentDb = arguments[0]; + } + } + + #affirmDbId(id){ + if(id<0 || id>=this.#db.list.length){ + toss(SQLTesterException, "Database index ",id," is out of range."); + } + return this; + } + + currentDb(...args){ + if( 0!=args.length ){ + this.#affirmDbId(id).#db.iCurrentDb = id; + } + return this.#db.currentDb(); + } + + getDbById(id){ + return this.#affirmDbId(id).#db.list[id]; + } + + getCurrentDb(){ return this.#db.list[this.#db.iCurrentDb]; } + + + closeDb(id) { + if( 0==arguments.length ){ + id = this.#db.iCurrentDb; + } + const db = this.#affirmDbId(id).#db.list[id]; + if( db ){ + sqlite3.capi.sqlite3_close_v2(db); + this.#db.list[id] = null; + } + } + + closeAllDbs(){ + for(let i = 0; i 0){ + //this.#outer.verbose2("RUNNING DB INIT CODE: ",this.#db.initSql.toString()); + rc = this.execSql(pDb, false, ResultBufferMode.NONE, + null, this.#db.initSql.join('')); + } + if( 0!=rc ){ + sqlite3.SQLite3Error.toss( + rc, + "sqlite3 result code",rc+":", + (pDb ? sqlite3.capi.sqlite3_errmsg(pDb) + : sqlite3.capi.sqlite3_errstr(rc)) + ); + } + return this.#db.list[this.#db.iCurrentDb] = pDb; + }catch(e){ + sqlite3.capi.sqlite3_close_v2(pDb); + throw e; + } + } + + #setupInitialDb(){ + if( !this.#db.list[0] ){ + Util.unlink(this.#db.initialDbName); + this.openDb(0, this.#db.initialDbName, true); + }else{ + this.#outer.outln("WARNING: setupInitialDb() unexpectedly ", + "triggered while it is opened."); + } + } + + /** + Returns v or some escaped form of v, as defined in the tester's + spec doc. + */ + #escapeSqlValue(v){ + if( !v ) return "{}"; + if( !Rx.special.test(v) ){ + return v /* no escaping needed */; + } + if( !Rx.squiggly.test(v) ){ + return "{"+v+"}"; + } + const sb = ["\""]; + const n = v.length; + for(let i = 0; i < n; ++i){ + const ch = v.charAt(i); + switch(ch){ + case '\\': sb.push("\\\\"); break; + case '"': sb.push("\\\""); break; + default:{ + //verbose("CHAR ",(int)ch," ",ch," octal=",String.format("\\%03o", (int)ch)); + const ccode = ch.charCodeAt(i); + if( ccode < 32 ) sb.push('\\',ccode.toString(8),'o'); + else sb.push(ch); + break; + } + } + } + sb.append("\""); + return sb.join(''); + } + + #appendDbErr(pDb, sb, rc){ + sb.push(sqlite3.capi.sqlite3_js_rc_str(rc), ' '); + const msg = this.#escapeSqlValue(sqlite3.capi.sqlite3_errmsg(pDb)); + if( '{' == msg.charAt(0) ){ + sb.push(msg); + }else{ + sb.push('{', msg, '}'); + } + } + + execSql(pDb, throwOnError, appendMode, lineMode, sql){ + sql = sqlite3.capi.sqlite3_js_sql_to_string(sql); + this.#outer.outln("execSql() is TODO. ",sql); + return 0; + } + }/*SQLTester*/ class Command { @@ -246,16 +442,6 @@ class Command { } } -class TestCase extends Command { - - process(tester, script, argv){ - this.argcCheck(script, argv,1); - script.testCaseName(argv[1]); - tester.clearResultBuffer(); - tester.clearInputBuffer(); - } -} - class Cursor { src; sb = []; @@ -287,7 +473,11 @@ const Rx = newObj({ requiredProperties: / REQUIRED_PROPERTIES:[ \t]*(\S.*)\s*$/, scriptModuleName: / SCRIPT_MODULE_NAME:[ \t]*(\S+)\s*$/, mixedModuleName: / ((MIXED_)?MODULE_NAME):[ \t]*(\S+)\s*$/, - command: /^--(([a-z-]+)( .*)?)$/ + command: /^--(([a-z-]+)( .*)?)$/, + //! "Special" characters - we have to escape output if it contains any. + special: /[\x00-\x20\x22\x5c\x7b\x7d]/, + //! Either of '{' or '}'. + squiggly: /[{}]/ }); class TestScript { @@ -295,7 +485,7 @@ class TestScript { #moduleName = null; #filename = null; #testCaseName = null; - #outer = new Outer().setOutputPrefix( ()=>this.getOutputPrefix() ); + #outer = new Outer().outputPrefix( ()=>this.getOutputPrefix()+': ' ); constructor(...args){ let content, filename; @@ -307,7 +497,6 @@ class TestScript { } this.#filename = filename; this.#cursor.src = content; - this.#outer.outputPrefix = ()=>this.getOutputPrefix(); } testCaseName(){ @@ -318,7 +507,7 @@ class TestScript { getOutputPrefix() { let rc = "["+(this.#moduleName || this.#filename)+"]"; if( this.#testCaseName ) rc += "["+this.#testCaseName+"]"; - return rc + " line "+ this.#cursor.lineNo +" "; + return rc + " line "+ this.#cursor.lineNo; } reset(){ @@ -471,6 +660,106 @@ class TestScript { }/*TestScript*/; +//! --close command +class CloseDbCommand extends Command { + process(t, ts, argv){ + this.argcCheck(ts,argv,0,1); + let id; + if(argv.length>1){ + const arg = argv[1]; + if("all".equals(arg)){ + t.closeAllDbs(); + return; + } + else{ + id = parseInt(arg); + } + }else{ + id = t.currentDbId(); + } + t.closeDb(id); + } +} + +//! --column-names command +class ColumnNamesCommand extends Command { + process( st, ts, argv ){ + this.argcCheck(ts,argv,1); + st.outputColumnNames( !!parseInt(argv[1]) ); + } +} + +//! --db command +class DbCommand extends Command { + process(t, ts, argv){ + this.argcCheck(ts,argv,1); + t.currentDbId( parseInt(argv[1]) ); + } +} + +//! --open command +class OpenDbCommand extends Command { + #createIfNeeded = false; + constructor(createIfNeeded=false){ + super(); + this.#createIfNeeded = createIfNeeded; + } + process(t, ts, argv){ + this.argcCheck(ts,argv,1); + t.openDb(argv[1], this.#createIfNeeded); + } +} + +//! --new command +class NewDbCommand extends OpenDbCommand { + constructor(){ super(true); } +} + +//! Placeholder dummy/no-op commands +class NoopCommand extends Command { + process(t, ts, argv){} +} + +//! --null command +class NullCommand extends Command { + process(st, ts, argv){ + this.argcCheck(ts,argv,1); + st.nullValue( argv[1] ); + } +} + +//! --print command +class PrintCommand extends Command { + process(st, ts, argv){ + st.out(ts.getOutputPrefix(),': '); + if( 1==argv.length ){ + st.out( st.getInputText() ); + }else{ + st.outln( Util.argvToString(argv) ); + } + } +} + + +//! --testcase command +class TestCaseCommand extends Command { + process(tester, script, argv){ + this.argcCheck(script, argv,1); + script.testCaseName(argv[1]); + tester.clearResultBuffer(); + tester.clearInputBuffer(); + } +} + + +//! --verbosity command +class VerbosityCommand extends Command { + process(t, ts, argv){ + t.argcCheck(ts,argv,1); + ts.verbosity( parseInt(argv[1]) ); + } +} + class CommandDispatcher { static map = newObj(); @@ -478,8 +767,23 @@ class CommandDispatcher { let rv = CommandDispatcher.map[name]; if( rv ) return rv; switch(name){ - //todo: map name to Command instance - case "testcase": rv = new TestCase(); break; + case "close": rv = new CloseDbCommand(); break; + case "column-names": rv = new ColumnNamesCommand(); break; + case "db": rv = new DbCommand(); break; + //case "glob": rv = new GlobCommand(); break; + //case "json": rv = new JsonCommand(); break; + //case "json-block": rv = new JsonBlockCommand(); break; + case "new": rv = new NewDbCommand(); break; + //case "notglob": rv = new NotGlobCommand(); break; + case "null": rv = new NullCommand(); break; + case "oom": rv = new NoopCommand(); break; + case "open": rv = new OpenDbCommand(); break; + case "print": rv = new PrintCommand(); break; + //case "result": rv = new ResultCommand(); break; + //case "run": rv = new RunCommand(); break; + //case "tableresult": rv = new TableResultCommand(); break; + case "testcase": rv = new TestCaseCommand(); break; + case "verbosity": rv = new VerbosityCommand(); break; } if( rv ){ CommandDispatcher.map[name] = rv; @@ -506,7 +810,8 @@ const namespace = newObj({ TestScript, TestScriptFailed, UnknownCommand, - Util + Util, + sqlite3 }); export {namespace as default}; diff --git a/ext/wasm/SQLTester/SQLTester.run.mjs b/ext/wasm/SQLTester/SQLTester.run.mjs index 4efd068e30..dc8eaa0c17 100644 --- a/ext/wasm/SQLTester/SQLTester.run.mjs +++ b/ext/wasm/SQLTester/SQLTester.run.mjs @@ -1,26 +1,51 @@ import {default as ns} from './SQLTester.mjs'; +globalThis.sqlite3 = ns.sqlite3; const log = function f(...args){ console.log('SQLTester.run:',...args); return f; }; -console.log("Loaded",ns); const out = function f(...args){ return f.outer.out(...args) }; out.outer = new ns.Outer(); out.outer.getOutputPrefix = ()=>'SQLTester.run: '; const outln = (...args)=>{ return out.outer.outln(...args) }; +const affirm = function(expr, msg){ + if( !expr ){ + throw new Error(arguments[1] + ? ("Assertion failed: "+arguments[1]) + : "Assertion failed"); + } +} + +console.log("Loaded",ns); + log("ns =",ns); out("Hi there. ").outln("SQLTester is ostensibly ready."); -let ts = new ns.TestScript('/foo.test', ns.Util.utf8Encode(` -# comment line -select 1; ---testcase 0.0 -#--result 1 +let ts = new ns.TestScript('/foo.test', ns.Util.utf8Encode( +`# comment line +--print Starting up... +--null NIL +--new :memory: +--testcase 0.0.1 +select '0.0.1'; +#--result 0.0.1 +--print done `)); const sqt = new ns.SQLTester(); -sqt.verbosity(3); -ts.run(sqt); +try{ + log( 'sqt.getCurrentDb()', sqt.getCurrentDb() ); + sqt.openDb('/foo.db', true); + log( 'sqt.getCurrentDb()', sqt.getCurrentDb() ); + sqt.verbosity(0); + affirm( 'NIL' !== sqt.nullValue() ); + ts.run(sqt); + affirm( 'NIL' === sqt.nullValue() ); +}finally{ + sqt.reset(); +} +log( 'sqt.getCurrentDb()', sqt.getCurrentDb() ); + diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 5abb13b990..35c856269d 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1135,7 +1135,23 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( return 1===n ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof) : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof); + }, + + /** + Records the current pstack position, calls the given function, + and restores the pstack regardless of whether the function + throws. Returns the result of the call or propagates an + exception on error. + + Added in 3.44. + */ + call: function(f){ + const stackPos = wasm.pstack.pointer; + try{ return f() }finally{ + wasm.pstack.restore(stackPos); + } } + })/*wasm.pstack*/; Object.defineProperties(wasm.pstack, { /** @@ -1543,6 +1559,26 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( } }; + /** + If v is a string, it is returned as-is. If it is-a Array, its + join("") result is returned. If is is a Uint8Array, Int8Array, + or ArrayBuffer, it is assumed to hold UTF-8-encoded text and is + decoded to a string. If it looks like a WASM pointer, + wasm.cstrToJs(sql) is returned. Else undefined is returned. + + The intent of this function is to convert SQL input text from a + variety of common forms to plain strings. + + Added in 3.44 + */ + capi.sqlite3_js_sql_to_string = (sql)=>{ + if('string' === typeof sql){ + return sql; + } + const x = flexibleString(v); + return x===v ? undefined : x; + } + if( util.isUIThread() ){ /* Features specific to the main window thread... */ diff --git a/manifest b/manifest index 8e208a8ae1..94540f2c28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\sbasic\sparsing\spieces\sand\scommand\sdispatching\sin\splace\sin\sthe\sJS\sSQLTester. -D 2023-08-29T13:28:36.476 +C Get\sthe\sJS\sSQLTester\scommand\shandlers\sin\splace\ssans\sthose\swhich\shave\sto\srun\sSQL. +D 2023-08-29T15:39:57.155 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -283,7 +283,7 @@ F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c38 F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a -F ext/jni/src/org/sqlite/jni/tester/SQLTester.java bf350903abe04a9bed2d8a2a71692ed4291dbb4eece2d3329ed91d15b0321e6d +F ext/jni/src/org/sqlite/jni/tester/SQLTester.java c8a9f20694e66f4d7ed677cd6d1f0d829f802c347a1f413ac2446c62e4cba23d F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e F ext/jni/src/tests/000-000-sanity.test cfe6dc1b950751d6096e3f5695becaadcdaa048bfe9567209d6eb676e693366d F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70 @@ -548,8 +548,8 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile 0e362f3fc04eab6628cbe4f1e35f4ab4a200881f6b5f753b27fb45eabeddd9d2 F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193 -F ext/wasm/SQLTester/SQLTester.mjs 2ea7d09f0c33e509aa3c4ca974be5705f59ddcd2173d4ff2721d7448c65be8bd -F ext/wasm/SQLTester/SQLTester.run.mjs 478f4d90951591decaa7e1e3fa1729f6ed0043ae4cb48b0a92056b9707d44185 +F ext/wasm/SQLTester/SQLTester.mjs 90fc3d2eb831afed237c18b78c22b8871d8f855a742715ebee571a60b9fcd98e +F ext/wasm/SQLTester/SQLTester.run.mjs 30a459ec400495cc52f1d693703f1629e141947a19eaf868a8e4c1fd3ef2a114 F ext/wasm/SQLTester/index.html 88d87e3ccbc33e7ab3773a8e48c1172e876951c4be31d1307c3700671262cddf F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b @@ -563,7 +563,7 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e F ext/wasm/api/sqlite3-api-glue.js b65e546568f1dfb35205b9792feb5146a6323d71b55cda58e2ed30def6dd52f3 F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 -F ext/wasm/api/sqlite3-api-prologue.js ef6f67c5ea718490806e5e17d2644b8b2f6e6ba5284d23dc1fbfd14d401c1ab5 +F ext/wasm/api/sqlite3-api-prologue.js 7fe51f06cd855634cb3765f830393f544fb532ead1cf95b5de3dd0befc81b92d F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 @@ -2111,8 +2111,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 60eec5ceda80c64870713df8e9aeabeef933c007f2010792225a07d5ef36baef -R 0bdc268c3b78f235b9f50e80fcfe1a69 +P 8fcc2a553c1e26734902bbdee0c38183ee22b7b5c75f07405529bb79db34145a +R 8ed29d2cdb1f79e88ba5ccad29a3151d U stephan -Z 00dd200744de92467554b7f23df0cf79 +Z 988ed72426998a455381761a89d498de # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 212a3786b4..60048b2641 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8fcc2a553c1e26734902bbdee0c38183ee22b7b5c75f07405529bb79db34145a \ No newline at end of file +d21b1217964a53f33b7ba3958b34aa8560dff8ede33e66f54aa0afbab7099ec3 \ No newline at end of file