diff --git a/test.sh b/test.sh index 61cd7f5..3db27d7 100755 --- a/test.sh +++ b/test.sh @@ -838,6 +838,58 @@ else ((PASSED++)) fi +# Test: mk template python +cd "$TEST_DIR" +u7 mk template python myapp >/dev/null 2>&1 +if [[ -f "myapp/src/main.py" && -f "myapp/README.md" && -f "myapp/src/__init__.py" && -f "myapp/tests/__init__.py" ]]; then + echo -e "${GREEN}✓${NC} mk template python works" + ((PASSED++)) +else + echo -e "${RED}✗${NC} mk template python failed" + ((FAILED++)) +fi + +# Test: mk template node +u7 mk template node mynode >/dev/null 2>&1 +if [[ -f "mynode/package.json" && -f "mynode/src/index.js" ]]; then + assert_contains "mk template node package.json has name" "mynode" "$(cat mynode/package.json)" +else + echo -e "${RED}✗${NC} mk template node failed" + ((FAILED++)) +fi + +# Test: mk template bash +u7 mk template bash mybash >/dev/null 2>&1 +if [[ -f "mybash/main.sh" && -x "mybash/main.sh" ]]; then + echo -e "${GREEN}✓${NC} mk template bash works" + ((PASSED++)) +else + echo -e "${RED}✗${NC} mk template bash failed" + ((FAILED++)) +fi + +# Test: mk template web +u7 mk template web myweb >/dev/null 2>&1 +if [[ -f "myweb/index.html" && -d "myweb/css" && -d "myweb/js" ]]; then + echo -e "${GREEN}✓${NC} mk template web works" + ((PASSED++)) +else + echo -e "${RED}✗${NC} mk template web failed" + ((FAILED++)) +fi + +# Test: mk template requires args +result=$(u7 mk template 2>&1) +assert_contains "mk template requires args" "Usage:" "$result" + +# Test: mk template rejects existing directory +mkdir -p existingdir +result=$(u7 mk template python existingdir 2>&1) +assert_contains "mk template rejects existing dir" "already exists" "$result" + +# Test: mk template rejects special characters in name +result=$(u7 mk template python "my project" 2>&1) +assert_contains "mk template rejects special chars" "alphanumerics" "$result" # Test 92: sh system result=$(u7 sh system 2>&1) assert_contains "sh system shows hostname" "Hostname:" "$result" diff --git a/utility.sh b/utility.sh index f9ba355..1fd9676 100644 --- a/utility.sh +++ b/utility.sh @@ -544,6 +544,60 @@ _u7_make() { fi ;; + template) + local tmpl="$1" + local name="$2" + if [[ -z "$tmpl" || -z "$name" ]]; then + echo "Usage: u7 mk template " + return 1 + fi + if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then + echo "Error: project name must contain only alphanumerics, hyphens, and underscores" + return 1 + fi + if [[ -d "$name" ]]; then + echo "Error: directory '$name' already exists" + return 1 + fi + if [[ "$_U7_DRY_RUN" == "1" ]]; then + echo "[dry-run] Create $tmpl project: $name" + return 0 + fi + case "$tmpl" in + python) + mkdir -p "$name/src" "$name/tests" + echo "# $name" > "$name/README.md" + echo "#!/usr/bin/env python3" > "$name/src/main.py" + touch "$name/src/__init__.py" "$name/tests/__init__.py" + echo "Created Python project: $name" + ;; + node) + _u7_require jq || return 1 + mkdir -p "$name/src" "$name/test" + echo "# $name" > "$name/README.md" + jq -n --arg name "$name" '{"name": $name, "version": "0.1.0", "main": "src/index.js"}' > "$name/package.json" + echo "// $name" > "$name/src/index.js" + echo "Created Node project: $name" + ;; + bash) + mkdir -p "$name" + echo "# $name" > "$name/README.md" + printf '#!/usr/bin/env bash\nset -euo pipefail\n\necho '\''Hello from %s'\''\n' "$name" > "$name/main.sh" + chmod +x "$name/main.sh" + echo "Created Bash project: $name" + ;; + web) + mkdir -p "$name/css" "$name/js" + local escaped_name="${name///>}" + echo "$escaped_name

$escaped_name

" > "$name/index.html" + touch "$name/css/style.css" "$name/js/main.js" + echo "Created Web project: $name" + ;; + *) echo "Unknown template: $tmpl. Available: python, node, bash, web" ; return 1 ;; + esac + ;; + sequence) if [[ "$1" != "with" || "$2" != "prefix" ]]; then echo "Usage: u7 mk sequence with prefix limit " @@ -575,6 +629,7 @@ Entities: link to Create symbolic link archive from Create archive from to clone [to ] Git clone a repository + template Scaffold a project structure sequence with prefix limit Generate numbered sequence with prefix and limit Examples: