@@ -991,6 +991,82 @@ func TestResetStore(t *testing.T) {
991991 }
992992}
993993
994+ func TestMigrateTags (t * testing.T ) {
995+ tempDir := t .TempDir ()
996+
997+ storePath := filepath .Join (tempDir , "migrate-tags-store" )
998+ s , err := store .New (store.Options {
999+ RootPath : storePath ,
1000+ })
1001+ if err != nil {
1002+ t .Fatalf ("Failed to create store: %v" , err )
1003+ }
1004+
1005+ // Write a model with an hf.co tag (simulating pre-migration state)
1006+ mdl := newTestModel (t )
1007+ if err := s .Write (mdl , []string {"hf.co/testorg/testmodel:latest" }, nil ); err != nil {
1008+ t .Fatalf ("Write failed: %v" , err )
1009+ }
1010+
1011+ // Write another model with a non-HF tag (should be unaffected)
1012+ mdl2Content := []byte ("another model content" )
1013+ mdl2Path := filepath .Join (tempDir , "other-model.gguf" )
1014+ if err := os .WriteFile (mdl2Path , mdl2Content , 0644 ); err != nil {
1015+ t .Fatalf ("Failed to write model file: %v" , err )
1016+ }
1017+ mdl2 , err := gguf .NewModel (mdl2Path )
1018+ if err != nil {
1019+ t .Fatalf ("Failed to create model: %v" , err )
1020+ }
1021+ if err := s .Write (mdl2 , []string {"ai/some-model:latest" }, nil ); err != nil {
1022+ t .Fatalf ("Write failed: %v" , err )
1023+ }
1024+
1025+ // Run migration: hf.co/ -> huggingface.co/
1026+ migrated , err := s .MigrateTags (func (tag string ) string {
1027+ if rest , found := strings .CutPrefix (tag , "hf.co/" ); found {
1028+ return "huggingface.co/" + rest
1029+ }
1030+ return tag
1031+ })
1032+ if err != nil {
1033+ t .Fatalf ("MigrateTags failed: %v" , err )
1034+ }
1035+
1036+ if migrated != 1 {
1037+ t .Errorf ("Expected 1 migrated tag, got %d" , migrated )
1038+ }
1039+
1040+ // Verify the model can be found with the new tag
1041+ if _ , err := s .Read ("huggingface.co/testorg/testmodel:latest" ); err != nil {
1042+ t .Fatalf ("Failed to read model with migrated tag: %v" , err )
1043+ }
1044+
1045+ // Verify the old tag no longer works
1046+ if _ , err := s .Read ("hf.co/testorg/testmodel:latest" ); ! errors .Is (err , store .ErrModelNotFound ) {
1047+ t .Errorf ("Expected ErrModelNotFound for old tag, got: %v" , err )
1048+ }
1049+
1050+ // Verify the non-HF model is unaffected
1051+ if _ , err := s .Read ("ai/some-model:latest" ); err != nil {
1052+ t .Fatalf ("Non-HF model should be unaffected: %v" , err )
1053+ }
1054+
1055+ // Running migration again should be a no-op
1056+ migrated2 , err := s .MigrateTags (func (tag string ) string {
1057+ if rest , found := strings .CutPrefix (tag , "hf.co/" ); found {
1058+ return "huggingface.co/" + rest
1059+ }
1060+ return tag
1061+ })
1062+ if err != nil {
1063+ t .Fatalf ("Second MigrateTags failed: %v" , err )
1064+ }
1065+ if migrated2 != 0 {
1066+ t .Errorf ("Expected 0 migrated tags on second run, got %d" , migrated2 )
1067+ }
1068+ }
1069+
9941070func TestWriteLightweight (t * testing.T ) {
9951071 tempDir := t .TempDir ()
9961072
0 commit comments