Repository: pyscript/pyscript-cli

Issue:
CLI config file and Default project config file names
Naming is hard but necessary! 

We need a place to PyScript CLI global configurations (that I'm referring to as CLI config file) and PyScript apps now have [a JSON/[TOML]](https://github.com/pyscript/pyscript/pull/754) format for Apps configuration. So we need to choose a default name for that file when the CLI creates a new project (referring to as project config).

My proposal here is that:

1. we use TOML for the CLI config file format
2. we name it `pyscript.config.toml` or `.pyscriptconfig` 
3. we name the default project config file to `pyscript.json`

/cc @ntoll @mattkram 

Discussion:

Patch:
diff --git a/src/pyscript/__init__.py b/src/pyscript/__init__.py
index 471235c..dd9dfc1 100644
--- a/src/pyscript/__init__.py
+++ b/src/pyscript/__init__.py
@@ -7,13 +7,13 @@ from rich.console import Console
 
 APPNAME = "pyscript"
 APPAUTHOR = "python"
-DEFAULT_CONFIG_FILENAME = "pyscript.json"
+DEFAULT_CONFIG_FILENAME = ".pyscriptconfig"
 
 
 # Default initial data for the command line.
 DEFAULT_CONFIG = {
     # Name of config file for PyScript projects.
-    "project_config_filename": "manifest.json",
+    "project_config_filename": "pyscript.toml",
 }
 
 
diff --git a/src/pyscript/_generator.py b/src/pyscript/_generator.py
index 1a949ba..86b8e4e 100644
--- a/src/pyscript/_generator.py
+++ b/src/pyscript/_generator.py
@@ -4,6 +4,7 @@ from pathlib import Path
 from typing import Optional
 
 import jinja2
+import toml
 
 from pyscript import config
 
@@ -50,6 +51,10 @@ def create_project(
     app_dir.mkdir()
     manifest_file = app_dir / config["project_config_filename"]
     with manifest_file.open("w", encoding="utf-8") as fp:
-        json.dump(context, fp)
+        if str(manifest_file).endswith(".json"):
+            json.dump(context, fp)
+        else:
+            toml.dump(context, fp)
+
     index_file = app_dir / "index.html"
     string_to_html('print("Hello, world!")', app_name, index_file)


Test patch:
diff --git a/tests/test_generator.py b/tests/test_generator.py
index 1664ce7..da8c9ef 100644
--- a/tests/test_generator.py
+++ b/tests/test_generator.py
@@ -8,41 +8,126 @@ from pathlib import Path
 from typing import Any
 
 import pytest
+import toml
 
 from pyscript import _generator as gen
 from pyscript import config
 
+TESTS_AUTHOR_NAME = "A.Coder"
+TESTS_AUTHOR_EMAIL = "acoder@domain.com"
+
 
 def test_create_project(tmp_cwd: Path, is_not_none: Any) -> None:
     app_name = "app_name"
     app_description = "A longer, human friendly, app description."
-    author_name = "A.Coder"
-    author_email = "acoder@domain.com"
-    gen.create_project(app_name, app_description, author_name, author_email)
 
-    manifest_path = tmp_cwd / app_name / config["project_config_filename"]
-    assert manifest_path.exists()
+    # GIVEN a a new project
+    gen.create_project(app_name, app_description, TESTS_AUTHOR_NAME, TESTS_AUTHOR_EMAIL)
 
-    with manifest_path.open() as fp:
-        contents = json.load(fp)
+    # with a default config path
+    manifest_path = tmp_cwd / app_name / config["project_config_filename"]
 
-    assert contents == {
-        "name": "app_name",
-        "description": "A longer, human friendly, app description.",
-        "type": "app",
-        "author_name": "A.Coder",
-        "author_email": "acoder@domain.com",
-        "version": is_not_none,
-    }
+    check_project_manifest(manifest_path, toml, app_name, is_not_none)
 
 
 def test_create_project_twice_raises_error(tmp_cwd: Path) -> None:
     """We get a FileExistsError when we try to create an existing project."""
     app_name = "app_name"
     app_description = "A longer, human friendly, app description."
-    author_name = "A.Coder"
-    author_email = "acoder@domain.com"
-    gen.create_project(app_name, app_description, author_name, author_email)
+    gen.create_project(app_name, app_description, TESTS_AUTHOR_NAME, TESTS_AUTHOR_EMAIL)
 
     with pytest.raises(FileExistsError):
-        gen.create_project(app_name, app_description, author_name, author_email)
+        gen.create_project(
+            app_name, app_description, TESTS_AUTHOR_NAME, TESTS_AUTHOR_EMAIL
+        )
+
+
+def test_create_project_explicit_json(
+    tmp_cwd: Path, is_not_none: Any, monkeypatch
+) -> None:
+    app_name = "JSON_app_name"
+    app_description = "A longer, human friendly, app description."
+
+    # Let's patch the config so that the project config file is a JSON file
+    config_file_name = "pyscript.json"
+    monkeypatch.setitem(gen.config, "project_config_filename", config_file_name)
+
+    # GIVEN a new project
+    gen.create_project(app_name, app_description, TESTS_AUTHOR_NAME, TESTS_AUTHOR_EMAIL)
+
+    # get the path where the config file is being created
+    manifest_path = tmp_cwd / app_name / config["project_config_filename"]
+
+    check_project_manifest(manifest_path, json, app_name, is_not_none)
+
+
+def test_create_project_explicit_toml(
+    tmp_cwd: Path, is_not_none: Any, monkeypatch
+) -> None:
+    app_name = "TOML_app_name"
+    app_description = "A longer, human friendly, app description."
+
+    # Let's patch the config so that the project config file is a JSON file
+    config_file_name = "mypyscript.toml"
+    monkeypatch.setitem(gen.config, "project_config_filename", config_file_name)
+
+    # GIVEN a new project
+    gen.create_project(app_name, app_description, TESTS_AUTHOR_NAME, TESTS_AUTHOR_EMAIL)
+
+    # get the path where the config file is being created
+    manifest_path = tmp_cwd / app_name / config["project_config_filename"]
+
+    check_project_manifest(manifest_path, toml, app_name, is_not_none)
+
+
+def check_project_manifest(
+    config_path: Path,
+    serializer: Any,
+    app_name: str,
+    is_not_none: Any,
+    app_description: str = "A longer, human friendly, app description.",
+    author_name: str = TESTS_AUTHOR_NAME,
+    author_email: str = TESTS_AUTHOR_EMAIL,
+    project_type: str = "app",
+):
+    """
+    Perform the following:
+
+        * checks that `config_path` exists
+        * loads the contents of `config_path` using `serializer.load`
+        * check that the contents match with the values provided in input. Specifically:
+            * "name" == app_name
+            * "description" == app_description
+            * "type" == app_type
+            * "author_name" == author_name
+            * "author_email" == author_email
+            * "version" == is_not_none
+
+    Params:
+        * config_path(Path): path to the app config file
+        * serializer(json|toml): serializer to be used to load contents of `config_path`.
+                                 Supported values are either modules `json` or `toml`
+        * app_name(str): name of application
+        * is_not_none(any): pytest fixture
+        * app_description(str): application description
+        * author_name(str): application author name
+        * author_email(str): application author email
+        * project_type(str): project type
+
+    """
+    # assert that the new project config file exists
+    assert config_path.exists()
+
+    # assert that we can load it as a TOML file (TOML is the default config format)
+    # and that the contents of the config are as we expect
+    with config_path.open() as fp:
+        contents = serializer.load(fp)
+
+    assert contents == {
+        "name": app_name,
+        "description": app_description,
+        "type": project_type,
+        "author_name": author_name,
+        "author_email": author_email,
+        "version": is_not_none,
+    }