diff --git a/cli/manifest/manifest.go b/cli/manifest/manifest.go index c740c21..81a7d14 100644 --- a/cli/manifest/manifest.go +++ b/cli/manifest/manifest.go @@ -16,15 +16,16 @@ const ManifestFileName string = "numerous.toml" var ManifestPath string = filepath.Join(".", ManifestFileName) type Manifest struct { - Name string `toml:"name" json:"name"` - Description string `toml:"description" json:"description"` - Library Library `toml:"library" json:"library"` - Python string `toml:"python" json:"python"` - AppFile string `toml:"app_file" json:"app_file"` - RequirementsFile string `toml:"requirements_file" json:"requirements_file"` - Port uint `toml:"port" json:"port"` - CoverImage string `toml:"cover_image" json:"cover_image"` - Exclude []string `toml:"exclude" json:"exclude"` + Name string `toml:"name" json:"name"` + Description string `toml:"description" json:"description"` + Library Library `toml:"library" json:"library"` + Python string `toml:"python" json:"python"` + AppFile string `toml:"app_file" json:"app_file"` + RequirementsFile string `toml:"requirements_file" json:"requirements_file"` + Port uint `toml:"port" json:"port"` + CoverImage string `toml:"cover_image" json:"cover_image"` + Exclude []string `toml:"exclude" json:"exclude"` + Deployment *Deployment `toml:"deploy,omitempty" json:"deploy,omitempty"` } type DeprecatedManifest struct { @@ -39,6 +40,11 @@ type DeprecatedManifest struct { Exclude []string `toml:"exclude" json:"exclude"` } +type Deployment struct { + OrganizationSlug string `toml:"organization" json:"organization"` + AppName string `toml:"name" json:"name"` +} + func LoadManifest(filePath string) (*Manifest, error) { var m Manifest diff --git a/cli/manifest/manifest_test.go b/cli/manifest/manifest_test.go index 6680d34..da10934 100644 --- a/cli/manifest/manifest_test.go +++ b/cli/manifest/manifest_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" ) -const manifestTOML string = `name = "Tool Name" +const streamlitTOML string = `name = "Tool Name" description = "A description" library = "streamlit" python = "3.11" @@ -19,7 +19,12 @@ requirements_file = "requirements.txt" port = 80 cover_image = "cover.png" exclude = ["*venv", "venv*"] + +[deploy] + organization = "organization-slug" + name = "app-name" ` +const streamlitJSON string = `{"name":"Tool Name","description":"A description","library":"streamlit","python":"3.11","app_file":"app.py","requirements_file":"requirements.txt","port":80,"cover_image":"cover.png","exclude":["*venv","venv*"],"deploy":{"organization":"organization-slug","name":"app-name"}}` const deprecatedTOML string = `name = "Tool Name" description = "A description" @@ -31,13 +36,6 @@ port = "80" cover_image = "cover.png" exclude = ["*venv", "venv*"] ` -const manifestJSON string = `{"name":"Tool Name","description":"A description","library":"streamlit","python":"3.11","app_file":"app.py","requirements_file":"requirements.txt","port":80,"cover_image":"cover.png","exclude":["*venv","venv*"]}` - -type encodeTOMLTestCase struct { - name string - manifest Manifest - expectedTOML string -} var streamlitManifest = Manifest{ Name: "Tool Name", @@ -49,74 +47,115 @@ var streamlitManifest = Manifest{ RequirementsFile: "requirements.txt", CoverImage: "cover.png", Exclude: []string{"*venv", "venv*"}, + Deployment: &Deployment{OrganizationSlug: "organization-slug", AppName: "app-name"}, } -var encodeTOMLTestCases = []encodeTOMLTestCase{ - { - name: "streamlit app", - manifest: streamlitManifest, - expectedTOML: manifestTOML, - }, +const noDeployJSON string = `{"name":"Tool Name","description":"A description","library":"streamlit","python":"3.11","app_file":"app.py","requirements_file":"requirements.txt","port":80,"cover_image":"cover.png","exclude":["*venv","venv*"]}` + +const noDeployTOML string = `name = "Tool Name" +description = "A description" +library = "streamlit" +python = "3.11" +app_file = "app.py" +requirements_file = "requirements.txt" +port = 80 +cover_image = "cover.png" +exclude = ["*venv", "venv*"] +` + +var noDeployManifest = Manifest{ + Name: "Tool Name", + Description: "A description", + Library: LibraryStreamlit, + Python: "3.11", + Port: 80, + AppFile: "app.py", + RequirementsFile: "requirements.txt", + CoverImage: "cover.png", + Exclude: []string{"*venv", "venv*"}, } func TestTOMLEncoding(t *testing.T) { - for _, testcase := range encodeTOMLTestCases { - t.Run(testcase.name, func(t *testing.T) { - actual, err := testcase.manifest.ToToml() + testCases := []struct { + name string + manifest Manifest + expectedTOML string + }{ + { + name: "streamlit app", + manifest: streamlitManifest, + expectedTOML: streamlitTOML, + }, + { + name: "without default deployment", + manifest: noDeployManifest, + expectedTOML: noDeployTOML, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual, err := tc.manifest.ToToml() require.NoError(t, err) - assert.Equal(t, testcase.expectedTOML, actual) + assert.Equal(t, tc.expectedTOML, actual) }) } } -type encodeJSONTestCase struct { - name string - manifest Manifest - expectedJSON string -} - -var encodeJSONTestCases = []encodeJSONTestCase{ - { - name: "streamlit app", - manifest: streamlitManifest, - expectedJSON: manifestJSON, - }, -} - func TestJSONEncoding(t *testing.T) { - for _, testcase := range encodeJSONTestCases { - t.Run(testcase.name, func(t *testing.T) { - actual, err := testcase.manifest.ToJSON() + testCases := []struct { + name string + manifest Manifest + expectedJSON string + }{ + { + name: "streamlit app", + manifest: streamlitManifest, + expectedJSON: streamlitJSON, + }, + { + name: "without default deployment", + manifest: noDeployManifest, + expectedJSON: noDeployJSON, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual, err := tc.manifest.ToJSON() require.NoError(t, err) - assert.Equal(t, testcase.expectedJSON, actual) + assert.Equal(t, tc.expectedJSON, actual) }) } } -type decodeTOMLTestCase struct { - name string - tomlContent string - expected Manifest -} - -var decodeTOMLTestCases = []decodeTOMLTestCase{ - { - name: "streamlit with deprecated string port", - tomlContent: deprecatedTOML, - expected: streamlitManifest, - }, - { - name: "streamlit", - tomlContent: manifestTOML, - expected: streamlitManifest, - }, -} - func TestManifestDecodeTOML(t *testing.T) { - for _, testcase := range decodeTOMLTestCases { - t.Run(testcase.name, func(t *testing.T) { + testCases := []struct { + name string + tomlContent string + expected Manifest + }{ + { + name: "streamlit with deprecated string port", + tomlContent: deprecatedTOML, + expected: noDeployManifest, + }, + { + name: "streamlit", + tomlContent: streamlitTOML, + expected: streamlitManifest, + }, + { + name: "without default deployment", + tomlContent: noDeployTOML, + expected: noDeployManifest, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { // Save Manifest - filePath := test.WriteTempFile(t, ManifestFileName, []byte(testcase.tomlContent)) + filePath := test.WriteTempFile(t, ManifestFileName, []byte(tc.tomlContent)) defer os.Remove(filePath) @@ -125,7 +164,7 @@ func TestManifestDecodeTOML(t *testing.T) { require.NoError(t, err) if assert.NotNil(t, actual) { - assert.Equal(t, testcase.expected, *actual) + assert.Equal(t, tc.expected, *actual) } }) } @@ -190,17 +229,17 @@ func TestManifestValidateApp(t *testing.T) { }, } - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - appfile := test.WriteTempFile(t, "appfile.py", []byte(testCase.appfileContent)) - l, err := GetLibraryByKey(testCase.library) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + appfile := test.WriteTempFile(t, "appfile.py", []byte(tc.appfileContent)) + l, err := GetLibraryByKey(tc.library) require.NoError(t, err) m := Manifest{Library: l, AppFile: appfile} validated, err := m.ValidateApp() assert.NoError(t, err) - assert.Equal(t, testCase.expected, validated) + assert.Equal(t, tc.expected, validated) }) } }