@@ -21,6 +21,7 @@ class ProcessFirstSection(str, enum.Enum):
2121 what = "what"
2222 mapping = "mapping"
2323 tips = "tips"
24+ best_practices = "best_practices"
2425 all = "all"
2526
2627
@@ -32,40 +33,126 @@ def init(
3233):
3334 """Interactive project initializer."""
3435 typer .echo ("Welcome to DevOps-OS Init Wizard!" )
36+ typer .echo ("Tools are grouped by Process-First DevOps principles (Systems Thinking).\n " )
37+
38+ # ── Canonical tool lists ──────────────────────────────────────────────
39+ ALL_LANGUAGES = ["python" , "java" , "node" , "ruby" , "csharp" , "php" , "rust" ,
40+ "typescript" , "kotlin" , "c" , "cpp" , "javascript" , "go" ]
41+ ALL_CICD = ["docker" , "podman" , "terraform" , "kubectl" , "helm" , "github_actions" , "jenkins" ]
42+ ALL_KUBERNETES = ["k9s" , "kustomize" , "argocd_cli" , "lens" , "kubeseal" ,
43+ "flux" , "kind" , "minikube" , "openshift_cli" ]
44+ ALL_BUILD_TOOLS = ["gradle" , "maven" , "ant" , "make" , "cmake" ]
45+ ALL_CODE_ANALYSIS = ["sonarqube" , "checkstyle" , "pmd" , "eslint" , "pylint" ]
46+ ALL_DEVOPS_TOOLS = ["nexus" , "prometheus" , "grafana" , "elk" , "jenkins" ]
3547
36- categories = {
37- "languages" : ["python" , "java" , "node" , "ruby" , "csharp" , "php" , "rust" , "typescript" , "kotlin" , "c" , "cpp" , "javascript" , "go" ],
38- "cicd" : ["docker" , "terraform" , "kubectl" , "helm" , "github_actions" , "jenkins" ],
39- "kubernetes" : ["k9s" , "kustomize" , "argocd_cli" , "lens" , "kubeseal" , "flux" , "kind" , "minikube" , "openshift_cli" ],
40- "build_tools" : ["gradle" , "maven" , "ant" , "make" , "cmake" ],
41- "code_analysis" : ["sonarqube" , "checkstyle" , "pmd" , "eslint" , "pylint" ],
42- "devops_tools" : ["nexus" , "prometheus" , "grafana" , "elk" , "jenkins" ]
43- }
4448 versions_defaults = {
4549 "python" : "3.11" , "java" : "17" , "node" : "20" , "go" : "1.21" , "nexus" : "3.50.0" ,
4650 "prometheus" : "2.45.0" , "grafana" : "10.0.0" , "k9s" : "0.29.1" , "argocd" : "2.8.4" ,
4751 "flux" : "2.1.2" , "kustomize" : "5.2.1" , "jenkins" : "2.440.1"
4852 }
49- config = {}
50- selected_versions = {}
51- selected_options = {}
52- for cat , opts in categories .items ():
53- selected = inquirer .checkbox (message = f"Select { cat .replace ('_' , ' ' ).title ()} :" , choices = opts ).execute ()
54- selected_options [cat ] = selected
55- # Now build config with True/False for each option
56- for cat , opts in categories .items ():
57- config [cat ] = {opt : (opt in selected_options [cat ]) for opt in opts }
58- # Prompt for version only for selected
59- if cat == "languages" or cat == "devops_tools" :
60- for opt in selected_options [cat ]:
61- if opt in versions_defaults :
62- selected_versions [opt ] = inquirer .text (message = f"{ opt .title ()} version:" , default = versions_defaults [opt ]).execute ()
63- if cat == "kubernetes" :
64- for opt in selected_options [cat ]:
65- if opt in ["k9s" , "argocd_cli" , "flux" , "kustomize" ]:
66- vkey = opt if opt != "argocd_cli" else "argocd"
67- selected_versions [vkey ] = inquirer .text (message = f"{ opt .title ()} version:" , default = versions_defaults .get (vkey , "" )).execute ()
68- config ["versions" ] = selected_versions
53+
54+ # ── Wizard groups aligned with Process-First DevOps principles ────────
55+ # Each group maps to a DevOps stage in the Systems Thinking value stream.
56+ wizard_groups = {
57+ "Languages" : {
58+ "choices" : ALL_LANGUAGES ,
59+ "description" : "Programming languages for your project" ,
60+ },
61+ "Containerization [CONTAINER stage]" : {
62+ "choices" : ["docker" , "podman" ],
63+ "description" : "Container runtimes to build, ship, and run application images" ,
64+ },
65+ "Build Tools [BUILD stage]" : {
66+ "choices" : ["gradle" , "maven" , "ant" , "make" , "cmake" , "nexus" ],
67+ "description" : "Tools to compile, package, and store build artifacts" ,
68+ },
69+ "Test & Quality [TEST stage]" : {
70+ "choices" : ["sonarqube" , "checkstyle" , "pmd" , "eslint" , "pylint" ],
71+ "description" : "Static analysis and quality gates to enforce standards early" ,
72+ },
73+ "Kubernetes [KUBERNETES stage]" : {
74+ "choices" : ["kubectl" , "helm" , "kustomize" , "k9s" , "argocd_cli" ,
75+ "flux" , "kind" , "minikube" , "lens" , "kubeseal" , "openshift_cli" ],
76+ "description" : "Kubernetes CLI tools, GitOps engines, and local cluster runtimes" ,
77+ },
78+ "CI/CD & Deploy [DEPLOY stage]" : {
79+ "choices" : ["github_actions" , "jenkins" , "terraform" ],
80+ "description" : "CI/CD pipelines, IaC provisioning, and deployment automation" ,
81+ },
82+ "SRE & Monitoring [SRE/MONITORING stage]" : {
83+ "choices" : ["prometheus" , "grafana" , "elk" ],
84+ "description" : "Observability stack: metrics, dashboards, and centralised logs" ,
85+ },
86+ }
87+
88+ selected_by_group : dict = {}
89+ selected_versions : dict = {}
90+
91+ for group_label , group_info in wizard_groups .items ():
92+ typer .echo (f"\n 📌 { group_info ['description' ]} " )
93+ selected = inquirer .checkbox (
94+ message = f"Select { group_label } :" ,
95+ choices = group_info ["choices" ],
96+ instruction = "(Space to select, ↑↓ to navigate, Enter to confirm)" ,
97+ ).execute ()
98+ selected_by_group [group_label ] = selected
99+
100+ # ── Version prompts ───────────────────────────────────────────────────
101+ all_selected = {tool for tools in selected_by_group .values () for tool in tools }
102+ for tool in all_selected :
103+ vkey = "argocd" if tool == "argocd_cli" else tool
104+ if vkey in versions_defaults :
105+ selected_versions [vkey ] = inquirer .text (
106+ message = f"{ tool .title ()} version:" ,
107+ default = versions_defaults [vkey ],
108+ ).execute ()
109+
110+ # ── Map wizard selections back to legacy JSON structure ───────────────
111+ # Keep the devcontainer.env.json keys identical to scaffold_devcontainer
112+ # output for backward compatibility.
113+ def _sel (group ): return selected_by_group .get (group , [])
114+
115+ container_sel = _sel ("Containerization [CONTAINER stage]" )
116+ build_sel = _sel ("Build Tools [BUILD stage]" )
117+ test_sel = _sel ("Test & Quality [TEST stage]" )
118+ k8s_sel = _sel ("Kubernetes [KUBERNETES stage]" )
119+ deploy_sel = _sel ("CI/CD & Deploy [DEPLOY stage]" )
120+ sre_sel = _sel ("SRE & Monitoring [SRE/MONITORING stage]" )
121+ lang_sel = _sel ("Languages" )
122+
123+ config = {
124+ "languages" : {opt : opt in lang_sel for opt in ALL_LANGUAGES },
125+ "cicd" : {
126+ "docker" : "docker" in container_sel ,
127+ "podman" : "podman" in container_sel ,
128+ "terraform" : "terraform" in deploy_sel ,
129+ "kubectl" : "kubectl" in k8s_sel ,
130+ "helm" : "helm" in k8s_sel ,
131+ "github_actions" : "github_actions" in deploy_sel ,
132+ "jenkins" : "jenkins" in deploy_sel ,
133+ },
134+ "kubernetes" : {
135+ "k9s" : "k9s" in k8s_sel ,
136+ "kustomize" : "kustomize" in k8s_sel ,
137+ "argocd_cli" : "argocd_cli" in k8s_sel ,
138+ "lens" : "lens" in k8s_sel ,
139+ "kubeseal" : "kubeseal" in k8s_sel ,
140+ "flux" : "flux" in k8s_sel ,
141+ "kind" : "kind" in k8s_sel ,
142+ "minikube" : "minikube" in k8s_sel ,
143+ "openshift_cli" : "openshift_cli" in k8s_sel ,
144+ },
145+ "build_tools" : {opt : opt in build_sel for opt in ALL_BUILD_TOOLS },
146+ "code_analysis" : {opt : opt in test_sel for opt in ALL_CODE_ANALYSIS },
147+ "devops_tools" : {
148+ "nexus" : "nexus" in build_sel ,
149+ "prometheus" : "prometheus" in sre_sel ,
150+ "grafana" : "grafana" in sre_sel ,
151+ "elk" : "elk" in sre_sel ,
152+ "jenkins" : "jenkins" in deploy_sel ,
153+ },
154+ "versions" : selected_versions ,
155+ }
69156
70157 # Review step: show config and confirm
71158 typer .echo ("\n Review your configuration:" )
@@ -88,39 +175,52 @@ def init(
88175 build_args = {}
89176 # Languages
90177 lang_map = {
91- "python" : "INSTALL_PYTHON" , "java" : "INSTALL_JAVA" , "node" : "INSTALL_JS" , "ruby" : "INSTALL_RUBY" ,
92- "csharp" : "INSTALL_CSHARP" , "php" : "INSTALL_PHP" , "rust" : "INSTALL_RUST" , "typescript" : "INSTALL_TYPESCRIPT" ,
93- "kotlin" : "INSTALL_KOTLIN" , "c" : "INSTALL_C" , "cpp" : "INSTALL_CPP" , "javascript" : "INSTALL_JAVASCRIPT" , "go" : "INSTALL_GO"
178+ "python" : "INSTALL_PYTHON" , "java" : "INSTALL_JAVA" , "node" : "INSTALL_JS" ,
179+ "ruby" : "INSTALL_RUBY" , "csharp" : "INSTALL_CSHARP" , "php" : "INSTALL_PHP" ,
180+ "rust" : "INSTALL_RUST" , "typescript" : "INSTALL_TYPESCRIPT" ,
181+ "kotlin" : "INSTALL_KOTLIN" , "c" : "INSTALL_C" , "cpp" : "INSTALL_CPP" ,
182+ "javascript" : "INSTALL_JAVASCRIPT" , "go" : "INSTALL_GO"
94183 }
95184 for lang , arg in lang_map .items ():
96185 build_args [arg ] = str (config ["languages" ].get (lang , False )).lower ()
97- # CICD
186+ # CICD (includes container runtimes docker/podman)
98187 cicd_map = {
99- "docker" : "INSTALL_DOCKER" , "terraform" : "INSTALL_TERRAFORM" , "kubectl" : "INSTALL_KUBECTL" , "helm" : "INSTALL_HELM" , "github_actions" : "INSTALL_GITHUB_ACTIONS" , "jenkins" : "INSTALL_JENKINS"
188+ "docker" : "INSTALL_DOCKER" , "podman" : "INSTALL_PODMAN" ,
189+ "terraform" : "INSTALL_TERRAFORM" ,
190+ "kubectl" : "INSTALL_KUBECTL" , "helm" : "INSTALL_HELM" ,
191+ "github_actions" : "INSTALL_GITHUB_ACTIONS" , "jenkins" : "INSTALL_JENKINS"
100192 }
101193 for tool , arg in cicd_map .items ():
102194 build_args [arg ] = str (config ["cicd" ].get (tool , False )).lower ()
103195 # Kubernetes
104196 k8s_map = {
105- "k9s" : "INSTALL_K9S" , "kustomize" : "INSTALL_KUSTOMIZE" , "argocd_cli" : "INSTALL_ARGOCD_CLI" , "lens" : "INSTALL_LENS" , "kubeseal" : "INSTALL_KUBESEAL" , "flux" : "INSTALL_FLUX" , "kind" : "INSTALL_KIND" , "minikube" : "INSTALL_MINIKUBE" , "openshift_cli" : "INSTALL_OPENSHIFT_CLI"
197+ "k9s" : "INSTALL_K9S" , "kustomize" : "INSTALL_KUSTOMIZE" ,
198+ "argocd_cli" : "INSTALL_ARGOCD_CLI" , "lens" : "INSTALL_LENS" ,
199+ "kubeseal" : "INSTALL_KUBESEAL" , "flux" : "INSTALL_FLUX" ,
200+ "kind" : "INSTALL_KIND" , "minikube" : "INSTALL_MINIKUBE" ,
201+ "openshift_cli" : "INSTALL_OPENSHIFT_CLI"
106202 }
107203 for tool , arg in k8s_map .items ():
108204 build_args [arg ] = str (config ["kubernetes" ].get (tool , False )).lower ()
109205 # Build tools
110206 build_map = {
111- "gradle" : "INSTALL_GRADLE" , "maven" : "INSTALL_MAVEN" , "ant" : "INSTALL_ANT" , "make" : "INSTALL_MAKE" , "cmake" : "INSTALL_CMAKE"
207+ "gradle" : "INSTALL_GRADLE" , "maven" : "INSTALL_MAVEN" , "ant" : "INSTALL_ANT" ,
208+ "make" : "INSTALL_MAKE" , "cmake" : "INSTALL_CMAKE"
112209 }
113210 for tool , arg in build_map .items ():
114211 build_args [arg ] = str (config ["build_tools" ].get (tool , False )).lower ()
115212 # Code analysis
116213 analysis_map = {
117- "sonarqube" : "INSTALL_SONARQUBE" , "checkstyle" : "INSTALL_CHECKSTYLE" , "pmd" : "INSTALL_PMD" , "eslint" : "INSTALL_ESLINT" , "pylint" : "INSTALL_PYLINT"
214+ "sonarqube" : "INSTALL_SONARQUBE" , "checkstyle" : "INSTALL_CHECKSTYLE" ,
215+ "pmd" : "INSTALL_PMD" , "eslint" : "INSTALL_ESLINT" , "pylint" : "INSTALL_PYLINT"
118216 }
119217 for tool , arg in analysis_map .items ():
120218 build_args [arg ] = str (config ["code_analysis" ].get (tool , False )).lower ()
121219 # DevOps tools
122220 devops_map = {
123- "nexus" : "INSTALL_NEXUS" , "prometheus" : "INSTALL_PROMETHEUS" , "grafana" : "INSTALL_GRAFANA" , "elk" : "INSTALL_ELK" , "jenkins" : "INSTALL_JENKINS"
221+ "nexus" : "INSTALL_NEXUS" , "prometheus" : "INSTALL_PROMETHEUS" ,
222+ "grafana" : "INSTALL_GRAFANA" , "elk" : "INSTALL_ELK" ,
223+ "jenkins" : "INSTALL_JENKINS"
124224 }
125225 for tool , arg in devops_map .items ():
126226 build_args [arg ] = str (config ["devops_tools" ].get (tool , False )).lower ()
@@ -181,10 +281,11 @@ def process_first_cmd(
181281 ProcessFirstSection .all ,
182282 help = (
183283 "Section to display:\n \n "
184- " 'what' — What Process-First is and its 5 core principles\n \n "
185- " 'mapping' — How each principle maps to a devopsos scaffold command\n \n "
186- " 'tips' — AI prompts and book recommendations for DevOps beginners\n \n "
187- " 'all' — All sections combined (default)"
284+ " 'what' — What Process-First is, 5 core principles + thought leaders\n \n "
285+ " 'mapping' — How each principle maps to a devopsos scaffold command\n \n "
286+ " 'tips' — AI prompts and book recommendations for DevOps beginners\n \n "
287+ " 'best_practices' — Best practices by stage (build/test/iac/deploy/sre/monitoring/security)\n \n "
288+ " 'all' — All sections combined (default)"
188289 ),
189290 show_choices = True ,
190291 ),
@@ -194,15 +295,16 @@ def process_first_cmd(
194295 \b
195296 Quick invocation guide:
196297
197- python -m cli.devopsos process-first # full overview
198- python -m cli.devopsos process-first --section what # core principles
199- python -m cli.devopsos process-first --section mapping # tool mapping table
200- python -m cli.devopsos process-first --section tips # AI prompts for beginners
298+ python -m cli.devopsos process-first # full overview
299+ python -m cli.devopsos process-first --section what # core principles + thought leaders
300+ python -m cli.devopsos process-first --section mapping # tool mapping table
301+ python -m cli.devopsos process-first --section tips # AI prompts for beginners
302+ python -m cli.devopsos process-first --section best_practices # best practices by stage
201303
202304 You can also run the module directly:
203305
204306 python -m cli.process_first
205- python -m cli.process_first --section mapping
307+ python -m cli.process_first --section best_practices
206308 """
207309 process_first .display (section .value )
208310
0 commit comments