mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-01 14:27:00 +00:00
v3.2: vendor-bundle re-mint under the product-triple rule
Every remaining legacy filament_id outside the BBL/QD_* islands re-derives from its product triple (filament_vendor / filament_type / family name), completing the content-addressed id model of filament_id_plan_v3.md: - Relocation pre-step: 14 fdm_filament_* template forks (Cubicon x3, Prusa x6, RH3D x6 minus the pc fork already re-homed) stop declaring ids; the 16 presets that rode Prusa's forks now declare the id they already resolved (verified zero effective-id drift over all 5892 instantiated presets). - --drop-redundant-ids: 6 Custom/MyToolChanger generics drop copied GF ids and ride their OFL families. - --remint over all 62 non-island vendors: 2647 declarations re-derived; identical products converge cross-bundle (showcase: PolyLite PLA is now OF5CgdDq in OrcaFilamentLibrary, Qidi, OrcaArena and Snapmaker). - Prusament @XL completions surfaced by the relocation: filament_vendor ["Prusa Polymers"] on the 8 @XL declarers; Prusament PA-CF typed PA11-CF (the product is Prusament PA11CF) and PC-CF typed PC-CF (-CF family typed as base polymer); each family converges on one id. - Succession: 331 ids retired with mode-rule successors, 355 never-shipped v1 mints forgotten with chain splicing, 151 GF-shaped ids released to the island space with hints, 27 curated BBL-generic -> OFL-generic hints (GFL99 -> OFDSrzZ8 class). New --retire "OLD=NEW" maintenance mode records lineage for OGFC99/OGFG99/OGFN99 (the shipped ids of OFL's Generic PC/PETG/PA in released versions, whose claims migrated in v3.1 while Cubicon's inert fork declarations kept them alive). - Retiring the P-hex system ids removes the last system ids from check_ams_filament_valid's destructive P-gate. - AMS-ambiguity fixes surfaced by convergence (validator -f): 4 presets riding another family's id through inherits now declare their true family id (Elegoo Generic ASA-CF/PETG-CF, Snapmaker PolyLite Dual PLA / PolyLite J1 PLA); 9 Cubicon @base presets and Dremel Generic PLA, which duplicate their per-printer variants on the same printers, split onto the salt-1 iteration of their triple (sanctioned by the mint-conformance check; --remint now leaves salt-conformant declarations alone). Gates: assign_filament_ids --check 0; orca_extra_profile_check 0; 116 python unit tests; config-equivalence over all 5892 instantiated presets (byte-identical configs except the 14 sanctioned Prusament vendor/type corrections; setting_id and compatible_printers unchanged; per-family convergence and ledger conservation verified); profile validator base/-f/-r(BBL)/-r(Qidi) all green; libslic3r_tests 48610 assertions; Moonraker OFL generic map check; custom-preset fixture archives v1.9.0-v2.4.1.
This commit is contained in:
@@ -153,6 +153,12 @@ class SyntheticTree:
|
||||
rc = afi.add_hints(pairs, self.profiles, self.retired)
|
||||
return rc, buf.getvalue()
|
||||
|
||||
def retire(self, pairs):
|
||||
buf = io.StringIO()
|
||||
with contextlib.redirect_stdout(buf):
|
||||
rc = afi.retire_ids(pairs, self.profiles, self.retired)
|
||||
return rc, buf.getvalue()
|
||||
|
||||
|
||||
def make_clean_tree():
|
||||
"""Baseline tree: OFL base+generic, a vendor family, a clean tuned generic."""
|
||||
@@ -1049,6 +1055,65 @@ class TestAddHint(SyntheticTreeCase):
|
||||
self.assertIn('expects "OLD=NEW"', out)
|
||||
|
||||
|
||||
class TestRetire(SyntheticTreeCase):
|
||||
def test_retires_vanished_id_with_successor(self):
|
||||
rc, out = self.t.retire(["OFOLD001=AX01"])
|
||||
self.assertEqual(rc, 0, out)
|
||||
self.assertEqual(load_json_file(self.t.retired)["retired"]["OFOLD001"],
|
||||
{"claims": [], "successor": "AX01"})
|
||||
errors, out = self.t.check()
|
||||
self.assertEqual(errors, 0, out)
|
||||
|
||||
def test_rejects_live_old(self):
|
||||
rc, out = self.t.retire(["AX01=OGFL99"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("still lives in the tree", out)
|
||||
self.assertEqual(afi.load_ledger(self.t.retired)["retired"], {})
|
||||
|
||||
def test_rejects_declaration_only_old(self):
|
||||
# The inert-fork case: an id declared by a claim-less root still lives
|
||||
# in the tree; the declaration must be deleted before --retire.
|
||||
self.t.write_preset("VendorA", preset("ZOLD @base", filament_id="ZDECL01",
|
||||
instantiation=False,
|
||||
filament_vendor="ZV",
|
||||
filament_type="PLA"))
|
||||
rc, out = self.t.retire(["ZDECL01=AX01"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("still lives in the tree", out)
|
||||
|
||||
def test_rejects_island_space_old(self):
|
||||
rc, out = self.t.retire(["GFXX99=AX01"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("reserved id space", out)
|
||||
|
||||
def test_rejects_user_space_old(self):
|
||||
rc, out = self.t.retire(["P1234ABC=AX01"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("reserved id space", out)
|
||||
|
||||
def test_rejects_already_retired_old(self):
|
||||
self.t.write_ledger(retired={"ROLD": {"claims": [], "successor": None}})
|
||||
rc, out = self.t.retire(["ROLD=AX01"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("already retired", out)
|
||||
|
||||
def test_rejects_hinted_old(self):
|
||||
self.t.write_ledger(hints={"HOLD": "AX01"})
|
||||
rc, out = self.t.retire(["HOLD=AX01"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("hint key", out)
|
||||
|
||||
def test_rejects_dead_successor(self):
|
||||
rc, out = self.t.retire(["OFOLD001=OFnope99"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn("not a live tree id", out)
|
||||
|
||||
def test_rejects_malformed_pair(self):
|
||||
rc, out = self.t.retire(["OFOLD001"])
|
||||
self.assertEqual(rc, 1)
|
||||
self.assertIn('expects "OLD=NEW"', out)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# default run: mint + insert
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -1261,6 +1326,21 @@ class TestRemint(SyntheticTreeCase):
|
||||
changed, errors, _out = self.t.remint(["VendorA"])
|
||||
self.assertEqual((changed, errors), (0, 0))
|
||||
|
||||
def test_salted_declaration_survives_remint(self):
|
||||
# A deliberate salt split (a second preset of one product kept on its
|
||||
# own id for per-printer AMS disambiguation) is mint-conformant and
|
||||
# must not be converged back onto salt 0.
|
||||
salt1 = afi.generate_filament_id(*self.TRIPLE, salt=1)
|
||||
self.t.write_preset("VendorA", preset("APLA @legacy",
|
||||
filament_id=salt1,
|
||||
inherits="APLA @base",
|
||||
compatible_printers=["P2 0.4 nozzle"]))
|
||||
changed, errors, out = self.t.remint(["VendorA"])
|
||||
self.assertEqual(errors, 0, out)
|
||||
self.assertEqual(changed, 1) # only the non-conformant AX01 root
|
||||
legacy = load_json_file(self.t.preset_path("VendorA", "APLA @legacy"))
|
||||
self.assertEqual(legacy["filament_id"], salt1)
|
||||
|
||||
def test_same_triple_converges_within_run(self):
|
||||
self.t.add_vendor("VendorB", [
|
||||
preset("APLA @Bbase", filament_id="BX01", instantiation=False,
|
||||
|
||||
Reference in New Issue
Block a user