feat(new tool): Docker Compose to Docker Run

#634 #546
This commit is contained in:
sharevb 2024-01-21 22:52:28 +01:00 committed by ShareVB
parent 22e836bb3d
commit a4f0522ad2
8 changed files with 201 additions and 37 deletions

1
components.d.ts vendored
View File

@ -69,6 +69,7 @@ declare module '@vue/runtime-core' {
DemoWrapper: typeof import('./src/ui/demo/demo-wrapper.vue')['default']
DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default']
DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default']
DockerComposeToDockerRunConverter: typeof import('./src/tools/docker-compose-to-docker-run-converter/docker-compose-to-docker-run-converter.vue')['default']
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']

View File

@ -56,6 +56,7 @@
"cronstrue": "^2.26.0",
"crypto-js": "^4.1.1",
"date-fns": "^2.29.3",
"decomposerize": "^1.2.4",
"dompurify": "^3.0.6",
"emojilib": "^3.0.10",
"figue": "^1.2.0",

View File

@ -50,9 +50,9 @@ dependencies:
colord:
specifier: ^2.9.3
version: 2.9.3
composerize:
specifier: ^1.6.6
version: 1.6.6
composerize-ts:
specifier: ^0.6.2
version: 0.6.2
country-code-lookup:
specifier: ^0.1.0
version: 0.1.0
@ -68,6 +68,9 @@ dependencies:
date-fns:
specifier: ^2.29.3
version: 2.29.3
decomposerize:
specifier: ^1.2.4
version: 1.2.4
dompurify:
specifier: ^3.0.6
version: 3.0.6
@ -4164,7 +4167,6 @@ packages:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
sprintf-js: 1.0.3
dev: true
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@ -4297,7 +4299,6 @@ packages:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
dev: true
/brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
@ -4587,6 +4588,11 @@ packages:
delayed-stream: 1.0.0
dev: true
/commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
engines: {node: '>=14'}
dev: false
/commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
@ -4604,16 +4610,16 @@ packages:
resolution: {integrity: sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==}
dev: false
/composerize@1.6.6:
resolution: {integrity: sha512-ZvnntVZvz4VzMSmxDc/BF+l5ra7pMAUDxDrljTosVCKhIFKR3mBVVKRJrne3Dx9xIDyvVwA1pRhmrAq+JGJX4g==}
/composerize-ts@0.6.2:
resolution: {integrity: sha512-8tw5p/FBxg77ubjVftaXA+pknWbkUgbZ4rbZZs2yFUsj2yvO38IvtfpGLfaJ9mGFj324lFEr/OU9xULrKSF9Ag==}
hasBin: true
dependencies:
composeverter: 1.6.2
core-js: 2.6.12
deepmerge: 2.2.1
invariant: 2.2.4
yaml: 1.10.2
yargs-parser: 13.1.2
commander: 10.0.1
deepmerge-ts: 5.1.0
flex-js: 1.0.5
ip-cidr: 3.1.0
set-value: 4.1.0
yamljs: 0.3.0
dev: false
/composeverter@1.6.2:
@ -4627,7 +4633,6 @@ packages:
/concat-map@0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
dev: true
/config-chain@1.1.13:
resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
@ -4856,6 +4861,15 @@ packages:
/decimal.js@10.4.3:
resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
/decomposerize@1.2.4:
resolution: {integrity: sha512-ON5UBObjuK313+/ftm+k/DDRgTjHJ+4SA4zEDXE6BpXB26FXWKmAj2k8NhzEvaLI9E3Cdvaw2KKV0vJh3hAgHw==}
hasBin: true
dependencies:
composeverter: 1.6.2
core-js: 2.6.12
yaml: 1.10.2
dev: false
/deep-eql@4.1.3:
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
engines: {node: '>=6'}
@ -4867,6 +4881,11 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
/deepmerge-ts@5.1.0:
resolution: {integrity: sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==}
engines: {node: '>=16.0.0'}
dev: false
/deepmerge@2.2.1:
resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==}
engines: {node: '>=0.10.0'}
@ -5715,6 +5734,10 @@ packages:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
/flex-js@1.0.5:
resolution: {integrity: sha512-Z5uoLzOGtTB/nzaTVVBbwmxOHBzHovAGJHLXE1TUKsQuN1RRWMOWeA08J9RRKtAl9TH9tkaH6fpjA4sLf0DzQw==}
dev: false
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
dependencies:
@ -5781,7 +5804,6 @@ packages:
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
/fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
@ -5893,7 +5915,6 @@ packages:
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
/glob@8.1.0:
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
@ -6212,11 +6233,9 @@ packages:
dependencies:
once: 1.4.0
wrappy: 1.0.2
dev: true
/inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true
/ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
@ -6231,10 +6250,20 @@ packages:
side-channel: 1.0.4
dev: true
/invariant@2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
/ip-address@7.1.0:
resolution: {integrity: sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ==}
engines: {node: '>= 10'}
dependencies:
loose-envify: 1.4.0
jsbn: 1.1.0
sprintf-js: 1.1.2
dev: false
/ip-cidr@3.1.0:
resolution: {integrity: sha512-HUCn4snshEX1P8cja/IyU3qk8FVDW8T5zZcegDFbu4w7NojmAhk5NcOgj3M8+0fmumo1afJTPDtJlzsxLdOjtg==}
engines: {node: '>=10.0.0'}
dependencies:
ip-address: 7.1.0
jsbn: 1.1.0
dev: false
/is-alphabetical@1.0.4:
@ -6404,6 +6433,11 @@ packages:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
dev: true
/is-primitive@3.0.1:
resolution: {integrity: sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==}
engines: {node: '>=0.10.0'}
dev: false
/is-regex@1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
@ -6551,6 +6585,10 @@ packages:
argparse: 2.0.1
dev: true
/jsbn@1.1.0:
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
dev: false
/jsdom@22.0.0:
resolution: {integrity: sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw==}
engines: {node: '>=16'}
@ -6763,13 +6801,6 @@ packages:
is-unicode-supported: 0.1.0
dev: true
/loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
dependencies:
js-tokens: 4.0.0
dev: false
/loupe@2.3.6:
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
dependencies:
@ -6966,7 +6997,6 @@ packages:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
dependencies:
brace-expansion: 1.1.11
dev: true
/minimatch@5.1.6:
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
@ -7213,7 +7243,6 @@ packages:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: true
/onetime@5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
@ -7401,7 +7430,6 @@ packages:
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: true
/path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
@ -8119,6 +8147,14 @@ packages:
has-property-descriptors: 1.0.1
dev: true
/set-value@4.1.0:
resolution: {integrity: sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==}
engines: {node: '>=11.0'}
dependencies:
is-plain-object: 2.0.4
is-primitive: 3.0.1
dev: false
/shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@ -8239,7 +8275,10 @@ packages:
/sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
dev: true
/sprintf-js@1.1.2:
resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==}
dev: false
/sql-formatter@13.0.0:
resolution: {integrity: sha512-V21cVvge4rhn9Fa7K/fTKcmPM+x1yee6Vhq8ZwgaWh3VPBqApgsaoFB5kLAhiqRo5AmSaRyLU7LIdgnNwH01/w==}
@ -9595,7 +9634,6 @@ packages:
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true
/ws@8.13.0:
resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}
@ -9663,11 +9701,12 @@ packages:
resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==}
engines: {node: '>= 14'}
/yargs-parser@13.1.2:
resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==}
/yamljs@0.3.0:
resolution: {integrity: sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==}
hasBin: true
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
argparse: 1.0.10
glob: 7.2.3
dev: false
/yargs-parser@18.1.3:

View File

@ -7,6 +7,7 @@ import sqlHljs from 'highlight.js/lib/languages/sql';
import xmlHljs from 'highlight.js/lib/languages/xml';
import yamlHljs from 'highlight.js/lib/languages/yaml';
import iniHljs from 'highlight.js/lib/languages/ini';
import bashHljs from 'highlight.js/lib/languages/bash';
import { useCopy } from '@/composable/copy';
const props = withDefaults(
@ -30,6 +31,7 @@ hljs.registerLanguage('html', xmlHljs);
hljs.registerLanguage('xml', xmlHljs);
hljs.registerLanguage('yaml', yamlHljs);
hljs.registerLanguage('toml', iniHljs);
hljs.registerLanguage('bash', bashHljs);
const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props);
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };

View File

@ -0,0 +1,12 @@
declare module 'decomposerize' {
type Configuration = {
command?: string,
rm?: boolean,
detach?: boolean,
multiline?: boolean,
'long-args'?: boolean,
'arg-value-separator'?: ArgValueSeparator,
};
const decomposerize: (dockerComposeContent: string, configuration?: Configuration) => string;
export default decomposerize;
}

View File

@ -0,0 +1,95 @@
<script setup lang="ts">
import decomposerize from 'decomposerize';
import TextareaCopyable from '@/components/TextareaCopyable.vue';
const detachOption = ref<boolean>(false);
const removeOption = ref<boolean>(false);
const longArgsOption = ref<boolean>(false);
const equalAsSepOption = ref<boolean>(false);
const dockerCompose = ref(
`version: '3.3'
services:
nginx:
ports:
- '80:80'
volumes:
- '/var/run/docker.sock:/tmp/docker.sock:ro'
restart: always
logging:
options:
max-size: 1g
image: nginx`,
);
const conversionResult = computed(() => {
try {
const config = {
'detach': detachOption.value,
'rm': removeOption.value,
'long-args': longArgsOption.value,
'arg-value-separator': equalAsSepOption.value ? '=' : ' ',
};
return { commands: decomposerize(dockerCompose.value.trim(), config), errors: [] };
}
catch (e: any) {
return { commands: '#see error messages', errors: e.toString().split('\n') };
}
});
const errors = computed(() => conversionResult.value.errors);
const dockerRunCommands = computed(() => conversionResult.value.commands);
const MONACO_EDITOR_OPTIONS = {
automaticLayout: true,
formatOnType: true,
formatOnPaste: true,
};
</script>
<template>
<div>
<c-label label="Paste your Docker Compose file content:">
<div relative w-full>
<c-monaco-editor
v-model:value="dockerCompose"
theme="vs-dark"
language="yaml"
height="250px"
:options="MONACO_EDITOR_OPTIONS"
/>
</div>
</c-label>
<div v-if="errors.length > 0">
<n-alert title="The following errors occured" type="error" mt-5>
<ul>
<li v-for="(message, index) of errors" :key="index">
{{ message }}
</li>
</ul>
</n-alert>
</div>
<n-divider />
<div class="mb-6 flex flex-row items-center gap-2">
<n-checkbox v-model:checked="detachOption">
Detach (-d)
</n-checkbox>
<n-checkbox v-model:checked="removeOption">
Remove (--rm)
</n-checkbox>
<n-checkbox v-model:checked="longArgsOption">
Long Arguments
</n-checkbox>
<n-checkbox v-model:checked="equalAsSepOption">
--<i>arg</i>=<i>value</i> ?
</n-checkbox>
</div>
<n-divider />
<TextareaCopyable :value="dockerRunCommands" language="bash" copy-placement="outside" />
</div>
</template>

View File

@ -0,0 +1,12 @@
import { BrandDocker } from '@vicons/tabler';
import { defineTool } from '../tool';
export const tool = defineTool({
name: 'Docker Compose to Docker run converter',
path: '/docker-compose-to-docker-run-converter',
description: 'Turns Docker Compose filt to docker run command(s)!',
keywords: ['docker', 'run', 'compose', 'yaml', 'yml', 'convert', 'deamon'],
component: () => import('./docker-compose-to-docker-run-converter.vue'),
icon: BrandDocker,
createdAt: new Date('2024-01-03'),
});

View File

@ -75,6 +75,7 @@ import { tool as urlParser } from './url-parser';
import { tool as uuidGenerator } from './uuid-generator';
import { tool as macAddressLookup } from './mac-address-lookup';
import { tool as xmlFormatter } from './xml-formatter';
import { tool as dockerComposeToDockerRunConverter } from './docker-compose-to-docker-run-converter';
export const toolsByCategory: ToolCategory[] = [
{
@ -138,6 +139,7 @@ export const toolsByCategory: ToolCategory[] = [
sqlPrettify,
chmodCalculator,
dockerRunToDockerComposeConverter,
dockerComposeToDockerRunConverter,
xmlFormatter,
],
},