feat(tool enhancement): Docker Run to Docker Compose
- Ability to paste more than one docker run command - Ability to choose Docker Compose version - Ability to merge an existing Docker Compose - Ability to set indent size #775 - Fix #814, #838
This commit is contained in:
		
							parent
							
								
									22e836bb3d
								
							
						
					
					
						commit
						39bc40172f
					
				| @ -50,7 +50,7 @@ | ||||
|     "bcryptjs": "^2.4.3", | ||||
|     "change-case": "^4.1.2", | ||||
|     "colord": "^2.9.3", | ||||
|     "composerize-ts": "^0.6.2", | ||||
|     "composerize": "^1.6.6", | ||||
|     "country-code-lookup": "^0.1.0", | ||||
|     "cron-validator": "^1.3.1", | ||||
|     "cronstrue": "^2.26.0", | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| declare module 'composerize' { | ||||
|   const composerize: (arg: string) => string; | ||||
|   const composerize: (commands: string, existingDockerComposeFile?: string, conversion?: string, indent?: number) => string; | ||||
|   export default composerize; | ||||
| } | ||||
|  | ||||
| @ -1,48 +1,94 @@ | ||||
| <script setup lang="ts"> | ||||
| import { MessageType, composerize } from 'composerize-ts'; | ||||
| import { withDefaultOnError } from '@/utils/defaults'; | ||||
| import composerize from 'composerize'; | ||||
| import { useDownloadFileFromBase64 } from '@/composable/downloadBase64'; | ||||
| import { textToBase64 } from '@/utils/base64'; | ||||
| import TextareaCopyable from '@/components/TextareaCopyable.vue'; | ||||
| 
 | ||||
| const dockerRun = ref( | ||||
| const dockerRuns = ref( | ||||
|   'docker run -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro --restart always --log-opt max-size=1g nginx', | ||||
| ); | ||||
| const indentSize = useStorage('docker-run-to-compose:indent-size', 4); | ||||
| 
 | ||||
| const conversionResult = computed(() => | ||||
|   withDefaultOnError(() => composerize(dockerRun.value.trim()), { yaml: '', messages: [] }), | ||||
| const existingDockerComposeFile = ref( | ||||
|   '', | ||||
| ); | ||||
| const format = useStorage('docker-run-to-compose:format', 'latest'); | ||||
| const formatOptions = [ | ||||
|   { value: 'v2x', label: 'V2 - 2.x' }, | ||||
|   { value: 'v3x', label: 'V2 - 3.x' }, | ||||
|   { value: 'latest', label: 'CommonSpec' }, | ||||
| ]; | ||||
| 
 | ||||
| const conversionResult = computed(() => { | ||||
|   try { | ||||
|     return { yaml: composerize(dockerRuns.value.trim(), existingDockerComposeFile.value, format.value, indentSize.value), errors: [] }; | ||||
|   } | ||||
|   catch (e: any) { | ||||
|     return { yaml: '#see error messages', errors: e.toString().split('\n') }; | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| const dockerCompose = computed(() => conversionResult.value.yaml); | ||||
| const notImplemented = computed(() => | ||||
|   conversionResult.value.messages.filter(msg => msg.type === MessageType.notImplemented).map(msg => msg.value), | ||||
| ); | ||||
| const notComposable = computed(() => | ||||
|   conversionResult.value.messages.filter(msg => msg.type === MessageType.notTranslatable).map(msg => msg.value), | ||||
| ); | ||||
| const errors = computed(() => | ||||
|   conversionResult.value.messages | ||||
|     .filter(msg => msg.type === MessageType.errorDuringConversion) | ||||
|     .map(msg => msg.value), | ||||
| ); | ||||
| const errors = computed(() => conversionResult.value.errors); | ||||
| 
 | ||||
| const dockerComposeBase64 = computed(() => `data:application/yaml;base64,${textToBase64(dockerCompose.value)}`); | ||||
| const { download } = useDownloadFileFromBase64({ source: dockerComposeBase64, filename: 'docker-compose.yml' }); | ||||
| 
 | ||||
| const MONACO_EDITOR_OPTIONS = { | ||||
|   automaticLayout: true, | ||||
|   formatOnType: true, | ||||
|   formatOnPaste: true, | ||||
| }; | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div> | ||||
|     <c-input-text | ||||
|       v-model:value="dockerRun" | ||||
|       label="Your docker run command:" | ||||
|       v-model:value="dockerRuns" | ||||
|       label="Your docker run command(s):" | ||||
|       style="font-family: monospace" | ||||
|       multiline | ||||
|       raw-text | ||||
|       monospace | ||||
|       placeholder="Your docker run command to convert..." | ||||
|       rows="3" | ||||
|       placeholder="Your docker run command(s) to convert..." | ||||
|       rows="4" | ||||
|     /> | ||||
| 
 | ||||
|     <n-divider /> | ||||
| 
 | ||||
|     <c-label label="Eventually, paste your existing Docker Compose:"> | ||||
|       <div relative w-full> | ||||
|         <c-monaco-editor | ||||
|           v-model:value="existingDockerComposeFile" | ||||
|           theme="vs-dark" | ||||
|           language="yaml" | ||||
|           height="100px" | ||||
|           :options="MONACO_EDITOR_OPTIONS" | ||||
|         /> | ||||
|       </div> | ||||
|     </c-label> | ||||
| 
 | ||||
|     <n-divider /> | ||||
| 
 | ||||
|     <n-grid cols="4" x-gap="12" w-full> | ||||
|       <n-gi span="2"> | ||||
|         <c-select | ||||
|           v-model:value="format" | ||||
|           label-position="top" | ||||
|           label="Docker Compose format:" | ||||
|           :options="formatOptions" | ||||
|           placeholder="Select Docker Compose format" | ||||
|         /> | ||||
|       </n-gi> | ||||
|       <n-gi span="2"> | ||||
|         <n-form-item label="Indent size:" label-placement="top" label-width="100" :show-feedback="false"> | ||||
|           <n-input-number v-model:value="indentSize" min="0" max="10" w-100px /> | ||||
|         </n-form-item> | ||||
|       </n-gi> | ||||
|     </n-grid> | ||||
| 
 | ||||
|     <n-divider /> | ||||
| 
 | ||||
|     <TextareaCopyable :value="dockerCompose" language="yaml" /> | ||||
| 
 | ||||
|     <div mt-5 flex justify-center> | ||||
| @ -51,30 +97,6 @@ const { download } = useDownloadFileFromBase64({ source: dockerComposeBase64, fi | ||||
|       </c-button> | ||||
|     </div> | ||||
| 
 | ||||
|     <div v-if="notComposable.length > 0"> | ||||
|       <n-alert title="This options are not translatable to docker-compose" type="info" mt-5> | ||||
|         <ul> | ||||
|           <li v-for="(message, index) of notComposable" :key="index"> | ||||
|             {{ message }} | ||||
|           </li> | ||||
|         </ul> | ||||
|       </n-alert> | ||||
|     </div> | ||||
| 
 | ||||
|     <div v-if="notImplemented.length > 0"> | ||||
|       <n-alert | ||||
|         title="This options are not yet implemented and therefore haven't been translated to docker-compose" | ||||
|         type="warning" | ||||
|         mt-5 | ||||
|       > | ||||
|         <ul> | ||||
|           <li v-for="(message, index) of notImplemented" :key="index"> | ||||
|             {{ message }} | ||||
|           </li> | ||||
|         </ul> | ||||
|       </n-alert> | ||||
|     </div> | ||||
| 
 | ||||
|     <div v-if="errors.length > 0"> | ||||
|       <n-alert title="The following errors occured" type="error" mt-5> | ||||
|         <ul> | ||||
|  | ||||
| @ -4,7 +4,7 @@ import { defineTool } from '../tool'; | ||||
| export const tool = defineTool({ | ||||
|   name: 'Docker run to Docker compose converter', | ||||
|   path: '/docker-run-to-docker-compose-converter', | ||||
|   description: 'Turns docker run commands into docker-compose files!', | ||||
|   description: 'Turns docker run command(s) into docker-compose files!', | ||||
|   keywords: ['docker', 'run', 'compose', 'yaml', 'yml', 'convert', 'deamon'], | ||||
|   component: () => import('./docker-run-to-docker-compose-converter.vue'), | ||||
|   icon: BrandDocker, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user