Skip to content

Commit 405543f

Browse files
authored
feat: support package code to the artifact (#74)
Signed-off-by: chlins <[email protected]>
1 parent dd95023 commit 405543f

File tree

5 files changed

+129
-1
lines changed

5 files changed

+129
-1
lines changed

docs/getting-started.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ CONFIG generation_config.json
5454

5555
# Model weight, support glob path pattern.
5656
MODEL *.safetensors
57+
58+
# Specify code, support glob path pattern.
59+
CODE *.py
60+
5761
```
5862

5963
Then run the following command to build the model artifact:

pkg/backend/build.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ func (b *backend) getProcessors(modelfile modelfile.Modelfile) []processor.Proce
8888
processors = append(processors, processor.NewModelProcessor(b.store, modelspec.MediaTypeModelWeight, models))
8989
}
9090

91+
if codes := modelfile.GetCodes(); len(codes) > 0 {
92+
processors = append(processors, processor.NewCodeProcessor(b.store, modelspec.MediaTypeModelCode, codes))
93+
}
94+
9195
return processors
9296
}
9397

pkg/backend/build_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ func TestGetProcessors(t *testing.T) {
2828
modelfile := &modelfile.Modelfile{}
2929
modelfile.On("GetConfigs").Return([]string{"config1", "config2"})
3030
modelfile.On("GetModels").Return([]string{"model1", "model2"})
31+
modelfile.On("GetCodes").Return([]string{"1.py", "2.py"})
3132

3233
b := &backend{}
3334
processors := b.getProcessors(modelfile)
3435

35-
assert.Len(t, processors, 4)
36+
assert.Len(t, processors, 5)
3637
assert.Equal(t, "readme", processors[0].Name())
3738
assert.Equal(t, "license", processors[1].Name())
3839
assert.Equal(t, "model_config", processors[2].Name())
3940
assert.Equal(t, "model", processors[3].Name())
41+
assert.Equal(t, "code", processors[4].Name())
4042
}

pkg/backend/processor/code.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 The CNAI Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package processor
18+
19+
import (
20+
"context"
21+
22+
"github.com/CloudNativeAI/modctl/pkg/storage"
23+
24+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
25+
)
26+
27+
// NewCodeProcessor creates a new code processor.
28+
func NewCodeProcessor(store storage.Storage, mediaType string, patterns []string) Processor {
29+
return &codeProcessor{
30+
base: &base{
31+
store: store,
32+
mediaType: mediaType,
33+
patterns: patterns,
34+
},
35+
}
36+
}
37+
38+
// codeProcessor is the processor to process the code file.
39+
type codeProcessor struct {
40+
base *base
41+
}
42+
43+
func (p *codeProcessor) Name() string {
44+
return "code"
45+
}
46+
47+
func (p *codeProcessor) Process(ctx context.Context, workDir, repo string) ([]ocispec.Descriptor, error) {
48+
return p.base.Process(ctx, workDir, repo)
49+
}

pkg/backend/processor/code_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2025 The CNAI Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package processor
18+
19+
import (
20+
"context"
21+
"os"
22+
"path/filepath"
23+
"testing"
24+
25+
"github.com/CloudNativeAI/modctl/test/mocks/storage"
26+
modelspec "github.com/CloudNativeAI/model-spec/specs-go/v1"
27+
28+
"github.com/stretchr/testify/assert"
29+
"github.com/stretchr/testify/mock"
30+
"github.com/stretchr/testify/suite"
31+
)
32+
33+
type codeProcessorSuite struct {
34+
suite.Suite
35+
mockStore *storage.Storage
36+
processor Processor
37+
workDir string
38+
}
39+
40+
func (s *codeProcessorSuite) SetupTest() {
41+
s.mockStore = &storage.Storage{}
42+
s.processor = NewCodeProcessor(s.mockStore, modelspec.MediaTypeModelCode, []string{"*.py"})
43+
// generate test files for prorcess.
44+
s.workDir = s.Suite.T().TempDir()
45+
if err := os.WriteFile(filepath.Join(s.workDir, "test.py"), []byte(""), 0644); err != nil {
46+
s.Suite.T().Fatal(err)
47+
}
48+
}
49+
50+
func (s *codeProcessorSuite) TestName() {
51+
assert.Equal(s.Suite.T(), "code", s.processor.Name())
52+
}
53+
54+
func (s *codeProcessorSuite) TestProcess() {
55+
ctx := context.Background()
56+
repo := "test-repo"
57+
s.mockStore.On("PushBlob", ctx, repo, mock.Anything).Return("sha256:1234567890abcdef", int64(1024), nil)
58+
59+
desc, err := s.processor.Process(ctx, s.workDir, repo)
60+
assert.NoError(s.Suite.T(), err)
61+
assert.NotNil(s.Suite.T(), desc)
62+
assert.Equal(s.Suite.T(), "sha256:1234567890abcdef", desc[0].Digest.String())
63+
assert.Equal(s.Suite.T(), int64(1024), desc[0].Size)
64+
assert.Equal(s.Suite.T(), "test.py", desc[0].Annotations[modelspec.AnnotationFilepath])
65+
}
66+
67+
func TestCodeProcessorSuite(t *testing.T) {
68+
suite.Run(t, new(codeProcessorSuite))
69+
}

0 commit comments

Comments
 (0)