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:
sharevb 2024-01-21 23:11:30 +01:00 committed by ShareVB
parent 22e836bb3d
commit 39bc40172f
4 changed files with 69 additions and 47 deletions

View file

@ -50,7 +50,7 @@
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"change-case": "^4.1.2", "change-case": "^4.1.2",
"colord": "^2.9.3", "colord": "^2.9.3",
"composerize-ts": "^0.6.2", "composerize": "^1.6.6",
"country-code-lookup": "^0.1.0", "country-code-lookup": "^0.1.0",
"cron-validator": "^1.3.1", "cron-validator": "^1.3.1",
"cronstrue": "^2.26.0", "cronstrue": "^2.26.0",

View file

@ -1,4 +1,4 @@
declare module 'composerize' { declare module 'composerize' {
const composerize: (arg: string) => string; const composerize: (commands: string, existingDockerComposeFile?: string, conversion?: string, indent?: number) => string;
export default composerize; export default composerize;
} }

View file

@ -1,48 +1,94 @@
<script setup lang="ts"> <script setup lang="ts">
import { MessageType, composerize } from 'composerize-ts'; import composerize from 'composerize';
import { withDefaultOnError } from '@/utils/defaults';
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64'; import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
import { textToBase64 } from '@/utils/base64'; import { textToBase64 } from '@/utils/base64';
import TextareaCopyable from '@/components/TextareaCopyable.vue'; 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', '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(() => const existingDockerComposeFile = ref(
withDefaultOnError(() => composerize(dockerRun.value.trim()), { yaml: '', messages: [] }), '',
); );
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 dockerCompose = computed(() => conversionResult.value.yaml);
const notImplemented = computed(() => const errors = computed(() => conversionResult.value.errors);
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 dockerComposeBase64 = computed(() => `data:application/yaml;base64,${textToBase64(dockerCompose.value)}`); const dockerComposeBase64 = computed(() => `data:application/yaml;base64,${textToBase64(dockerCompose.value)}`);
const { download } = useDownloadFileFromBase64({ source: dockerComposeBase64, filename: 'docker-compose.yml' }); const { download } = useDownloadFileFromBase64({ source: dockerComposeBase64, filename: 'docker-compose.yml' });
const MONACO_EDITOR_OPTIONS = {
automaticLayout: true,
formatOnType: true,
formatOnPaste: true,
};
</script> </script>
<template> <template>
<div> <div>
<c-input-text <c-input-text
v-model:value="dockerRun" v-model:value="dockerRuns"
label="Your docker run command:" label="Your docker run command(s):"
style="font-family: monospace" style="font-family: monospace"
multiline multiline
raw-text raw-text
monospace monospace
placeholder="Your docker run command to convert..." placeholder="Your docker run command(s) to convert..."
rows="3" rows="4"
/> />
<n-divider /> <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" /> <TextareaCopyable :value="dockerCompose" language="yaml" />
<div mt-5 flex justify-center> <div mt-5 flex justify-center>
@ -51,30 +97,6 @@ const { download } = useDownloadFileFromBase64({ source: dockerComposeBase64, fi
</c-button> </c-button>
</div> </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"> <div v-if="errors.length > 0">
<n-alert title="The following errors occured" type="error" mt-5> <n-alert title="The following errors occured" type="error" mt-5>
<ul> <ul>

View file

@ -4,7 +4,7 @@ import { defineTool } from '../tool';
export const tool = defineTool({ export const tool = defineTool({
name: 'Docker run to Docker compose converter', name: 'Docker run to Docker compose converter',
path: '/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'], keywords: ['docker', 'run', 'compose', 'yaml', 'yml', 'convert', 'deamon'],
component: () => import('./docker-run-to-docker-compose-converter.vue'), component: () => import('./docker-run-to-docker-compose-converter.vue'),
icon: BrandDocker, icon: BrandDocker,