@@ -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,123 @@ 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" , "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+ "Build Tools [BUILD stage]" : {
62+ "choices" : ["docker" , "gradle" , "maven" , "ant" , "make" , "cmake" , "nexus" ],
63+ "description" : "Tools to compile, package, and store build artifacts" ,
64+ },
65+ "Test & Quality [TEST stage]" : {
66+ "choices" : ["sonarqube" , "checkstyle" , "pmd" , "eslint" , "pylint" ],
67+ "description" : "Static analysis and quality gates to enforce standards early" ,
68+ },
69+ "IaC & Infrastructure [IaC stage]" : {
70+ "choices" : ["terraform" , "kubectl" , "helm" , "kustomize" ],
71+ "description" : "Infrastructure as Code tools for reproducible environments" ,
72+ },
73+ "Deploy & GitOps [DEPLOY stage]" : {
74+ "choices" : ["github_actions" , "jenkins" , "argocd_cli" , "flux" ],
75+ "description" : "CI/CD pipelines and GitOps delivery tools" ,
76+ },
77+ "SRE & Monitoring [SRE/MONITORING stage]" : {
78+ "choices" : ["prometheus" , "grafana" , "elk" , "k9s" ],
79+ "description" : "Observability stack: metrics, dashboards, and logs" ,
80+ },
81+ "Security & Kubernetes Dev [SECURITY stage]" : {
82+ "choices" : ["kubeseal" , "lens" , "kind" , "minikube" , "openshift_cli" ],
83+ "description" : "Secret management, security scanning, and local K8s dev tools" ,
84+ },
85+ }
86+
87+ selected_by_group : dict = {}
88+ selected_versions : dict = {}
89+
90+ for group_label , group_info in wizard_groups .items ():
91+ typer .echo (f"\n 📌 { group_info ['description' ]} " )
92+ selected = inquirer .checkbox (
93+ message = f"Select { group_label } :" ,
94+ choices = group_info ["choices" ],
95+ ).execute ()
96+ selected_by_group [group_label ] = selected
97+
98+ # ── Version prompts ───────────────────────────────────────────────────
99+ all_selected = {tool for tools in selected_by_group .values () for tool in tools }
100+ for tool in all_selected :
101+ vkey = "argocd" if tool == "argocd_cli" else tool
102+ if vkey in versions_defaults :
103+ selected_versions [vkey ] = inquirer .text (
104+ message = f"{ tool .title ()} version:" ,
105+ default = versions_defaults [vkey ],
106+ ).execute ()
107+
108+ # ── Map wizard selections back to legacy JSON structure ───────────────
109+ # Keep the devcontainer.env.json keys identical to scaffold_devcontainer
110+ # output for backward compatibility.
111+ def _sel (group ): return selected_by_group .get (group , [])
112+
113+ build_sel = _sel ("Build Tools [BUILD stage]" )
114+ test_sel = _sel ("Test & Quality [TEST stage]" )
115+ iac_sel = _sel ("IaC & Infrastructure [IaC stage]" )
116+ deploy_sel = _sel ("Deploy & GitOps [DEPLOY stage]" )
117+ sre_sel = _sel ("SRE & Monitoring [SRE/MONITORING stage]" )
118+ security_sel = _sel ("Security & Kubernetes Dev [SECURITY stage]" )
119+ lang_sel = _sel ("Languages" )
120+
121+ config = {
122+ "languages" : {opt : opt in lang_sel for opt in ALL_LANGUAGES },
123+ "cicd" : {
124+ "docker" : "docker" in build_sel ,
125+ "terraform" : "terraform" in iac_sel ,
126+ "kubectl" : "kubectl" in iac_sel ,
127+ "helm" : "helm" in iac_sel ,
128+ "github_actions" : "github_actions" in deploy_sel ,
129+ "jenkins" : "jenkins" in deploy_sel ,
130+ },
131+ "kubernetes" : {
132+ "k9s" : "k9s" in sre_sel ,
133+ "kustomize" : "kustomize" in iac_sel ,
134+ "argocd_cli" : "argocd_cli" in deploy_sel ,
135+ "lens" : "lens" in security_sel ,
136+ "kubeseal" : "kubeseal" in security_sel ,
137+ "flux" : "flux" in deploy_sel ,
138+ "kind" : "kind" in security_sel ,
139+ "minikube" : "minikube" in security_sel ,
140+ "openshift_cli" : "openshift_cli" in security_sel ,
141+ },
142+ "build_tools" : {opt : opt in build_sel for opt in ALL_BUILD_TOOLS },
143+ "code_analysis" : {opt : opt in test_sel for opt in ALL_CODE_ANALYSIS },
144+ "devops_tools" : {
145+ "nexus" : "nexus" in build_sel ,
146+ "prometheus" : "prometheus" in sre_sel ,
147+ "grafana" : "grafana" in sre_sel ,
148+ "elk" : "elk" in sre_sel ,
149+ "jenkins" : "jenkins" in deploy_sel ,
150+ },
151+ "versions" : selected_versions ,
152+ }
69153
70154 # Review step: show config and confirm
71155 typer .echo ("\n Review your configuration:" )
@@ -88,39 +172,51 @@ def init(
88172 build_args = {}
89173 # Languages
90174 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"
175+ "python" : "INSTALL_PYTHON" , "java" : "INSTALL_JAVA" , "node" : "INSTALL_JS" ,
176+ "ruby" : "INSTALL_RUBY" , "csharp" : "INSTALL_CSHARP" , "php" : "INSTALL_PHP" ,
177+ "rust" : "INSTALL_RUST" , "typescript" : "INSTALL_TYPESCRIPT" ,
178+ "kotlin" : "INSTALL_KOTLIN" , "c" : "INSTALL_C" , "cpp" : "INSTALL_CPP" ,
179+ "javascript" : "INSTALL_JAVASCRIPT" , "go" : "INSTALL_GO"
94180 }
95181 for lang , arg in lang_map .items ():
96182 build_args [arg ] = str (config ["languages" ].get (lang , False )).lower ()
97183 # CICD
98184 cicd_map = {
99- "docker" : "INSTALL_DOCKER" , "terraform" : "INSTALL_TERRAFORM" , "kubectl" : "INSTALL_KUBECTL" , "helm" : "INSTALL_HELM" , "github_actions" : "INSTALL_GITHUB_ACTIONS" , "jenkins" : "INSTALL_JENKINS"
185+ "docker" : "INSTALL_DOCKER" , "terraform" : "INSTALL_TERRAFORM" ,
186+ "kubectl" : "INSTALL_KUBECTL" , "helm" : "INSTALL_HELM" ,
187+ "github_actions" : "INSTALL_GITHUB_ACTIONS" , "jenkins" : "INSTALL_JENKINS"
100188 }
101189 for tool , arg in cicd_map .items ():
102190 build_args [arg ] = str (config ["cicd" ].get (tool , False )).lower ()
103191 # Kubernetes
104192 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"
193+ "k9s" : "INSTALL_K9S" , "kustomize" : "INSTALL_KUSTOMIZE" ,
194+ "argocd_cli" : "INSTALL_ARGOCD_CLI" , "lens" : "INSTALL_LENS" ,
195+ "kubeseal" : "INSTALL_KUBESEAL" , "flux" : "INSTALL_FLUX" ,
196+ "kind" : "INSTALL_KIND" , "minikube" : "INSTALL_MINIKUBE" ,
197+ "openshift_cli" : "INSTALL_OPENSHIFT_CLI"
106198 }
107199 for tool , arg in k8s_map .items ():
108200 build_args [arg ] = str (config ["kubernetes" ].get (tool , False )).lower ()
109201 # Build tools
110202 build_map = {
111- "gradle" : "INSTALL_GRADLE" , "maven" : "INSTALL_MAVEN" , "ant" : "INSTALL_ANT" , "make" : "INSTALL_MAKE" , "cmake" : "INSTALL_CMAKE"
203+ "gradle" : "INSTALL_GRADLE" , "maven" : "INSTALL_MAVEN" , "ant" : "INSTALL_ANT" ,
204+ "make" : "INSTALL_MAKE" , "cmake" : "INSTALL_CMAKE"
112205 }
113206 for tool , arg in build_map .items ():
114207 build_args [arg ] = str (config ["build_tools" ].get (tool , False )).lower ()
115208 # Code analysis
116209 analysis_map = {
117- "sonarqube" : "INSTALL_SONARQUBE" , "checkstyle" : "INSTALL_CHECKSTYLE" , "pmd" : "INSTALL_PMD" , "eslint" : "INSTALL_ESLINT" , "pylint" : "INSTALL_PYLINT"
210+ "sonarqube" : "INSTALL_SONARQUBE" , "checkstyle" : "INSTALL_CHECKSTYLE" ,
211+ "pmd" : "INSTALL_PMD" , "eslint" : "INSTALL_ESLINT" , "pylint" : "INSTALL_PYLINT"
118212 }
119213 for tool , arg in analysis_map .items ():
120214 build_args [arg ] = str (config ["code_analysis" ].get (tool , False )).lower ()
121215 # DevOps tools
122216 devops_map = {
123- "nexus" : "INSTALL_NEXUS" , "prometheus" : "INSTALL_PROMETHEUS" , "grafana" : "INSTALL_GRAFANA" , "elk" : "INSTALL_ELK" , "jenkins" : "INSTALL_JENKINS"
217+ "nexus" : "INSTALL_NEXUS" , "prometheus" : "INSTALL_PROMETHEUS" ,
218+ "grafana" : "INSTALL_GRAFANA" , "elk" : "INSTALL_ELK" ,
219+ "jenkins" : "INSTALL_JENKINS"
124220 }
125221 for tool , arg in devops_map .items ():
126222 build_args [arg ] = str (config ["devops_tools" ].get (tool , False )).lower ()
@@ -181,10 +277,11 @@ def process_first_cmd(
181277 ProcessFirstSection .all ,
182278 help = (
183279 "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)"
280+ " 'what' — What Process-First is, 5 core principles + thought leaders\n \n "
281+ " 'mapping' — How each principle maps to a devopsos scaffold command\n \n "
282+ " 'tips' — AI prompts and book recommendations for DevOps beginners\n \n "
283+ " 'best_practices' — Best practices by stage (build/test/iac/deploy/sre/monitoring/security)\n \n "
284+ " 'all' — All sections combined (default)"
188285 ),
189286 show_choices = True ,
190287 ),
@@ -194,15 +291,16 @@ def process_first_cmd(
194291 \b
195292 Quick invocation guide:
196293
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
294+ python -m cli.devopsos process-first # full overview
295+ python -m cli.devopsos process-first --section what # core principles + thought leaders
296+ python -m cli.devopsos process-first --section mapping # tool mapping table
297+ python -m cli.devopsos process-first --section tips # AI prompts for beginners
298+ python -m cli.devopsos process-first --section best_practices # best practices by stage
201299
202300 You can also run the module directly:
203301
204302 python -m cli.process_first
205- python -m cli.process_first --section mapping
303+ python -m cli.process_first --section best_practices
206304 """
207305 process_first .display (section .value )
208306
0 commit comments