Skip to content

Commit 8e373d2

Browse files
committed
Merge branch 'feat/dockver-compose-converter' into chore/all-my-stuffs
# Conflicts: # package.json # pnpm-lock.yaml # src/tools/index.ts
2 parents dd49e2f + 93d3ab6 commit 8e373d2

File tree

6 files changed

+179
-1
lines changed

6 files changed

+179
-1
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
"country-code-lookup": "^0.1.0",
127127
"crc": "^4.3.2",
128128
"countries-and-timezones": "^3.6.0",
129+
"composeverter": "^1.6.2",
129130
"country-code-lookup": "^0.1.0",
130131
"cron-parser": "^4.9.0",
131132
"cron-validator": "^1.3.1",

pnpm-lock.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
declare module 'composeverter' {
2+
interface Configuration {
3+
expandVolumes?: boolean;
4+
expandPorts?: boolean;
5+
indent?: number;
6+
}
7+
interface DockerComposeValidatioError {
8+
line?: number;
9+
message: string;
10+
helpLink?: string;
11+
}
12+
export function validateDockerComposeToCommonSpec(content: string): DockerComposeValidatioError[];
13+
export function migrateFromV2xToV3x(content: string, configuration?: Configuration = null): string;
14+
export function migrateFromV3xToV2x(content: string, configuration?: Configuration = null): string;
15+
export function migrateFromV1ToV2x(content: string, configuration?: Configuration = null): string;
16+
export function migrateToCommonSpec(content: string, configuration?: Configuration = null): string;
17+
export function migrateFromV2xToV3x(content: string, configuration?: Configuration = null): string;
18+
export function getDockerComposeSchemaWithoutFormats(): object;
19+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<script setup lang="ts">
2+
import Composeverter from 'composeverter';
3+
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
4+
import { textToBase64 } from '@/utils/base64';
5+
import TextareaCopyable from '@/components/TextareaCopyable.vue';
6+
7+
const dockerCompose = ref(
8+
`nginx:
9+
ports:
10+
- '80:80'
11+
volumes:
12+
- '/var/run/docker.sock:/tmp/docker.sock:ro'
13+
image: nginx`,
14+
);
15+
const indentSize = useStorage('docker-compose-converter:indent-size', 4);
16+
17+
const expandVolumes = ref(
18+
false,
19+
);
20+
const expandPorts = ref(
21+
false,
22+
);
23+
const conversion = useStorage('docker-compose-converter:conversion', 'latest');
24+
const conversionOptions = [
25+
{ value: 'v1ToV2x', label: 'V1 to V2 2.x' },
26+
{ value: 'v1ToV3x', label: 'V1 to V2 3.x' },
27+
{ value: 'v2xToV3x', label: 'V2 - 2.x to 3.x' },
28+
{ value: 'v3xToV2x', label: 'V2 - 3.x to 2.x' },
29+
{ value: 'latest', label: 'To CommonSpec' },
30+
];
31+
32+
const conversionResult = computed(() => {
33+
try {
34+
let convertedDockerCompose = '';
35+
const config = {
36+
expandPorts: expandPorts.value,
37+
expandVolumes: expandVolumes.value,
38+
indent: indentSize.value,
39+
};
40+
switch (conversion.value) {
41+
case 'latest':
42+
convertedDockerCompose = Composeverter.migrateToCommonSpec(dockerCompose.value, config);
43+
break;
44+
case 'v1ToV2x':
45+
convertedDockerCompose = Composeverter.migrateFromV1ToV2x(dockerCompose.value, config);
46+
break;
47+
case 'v1ToV3x':
48+
convertedDockerCompose = Composeverter.migrateFromV2xToV3x(Composeverter.migrateFromV1ToV2x(dockerCompose.value), config);
49+
break;
50+
case 'v2xToV3x':
51+
convertedDockerCompose = Composeverter.migrateFromV2xToV3x(dockerCompose.value, config);
52+
break;
53+
case 'v3xToV2x':
54+
convertedDockerCompose = Composeverter.migrateFromV3xToV2x(dockerCompose.value, config);
55+
break;
56+
57+
default:
58+
throw new Error(`Unknown conversion '${conversion}'`);
59+
}
60+
return { yaml: convertedDockerCompose, errors: [] };
61+
}
62+
catch (e: any) {
63+
return { yaml: '#see error messages', errors: e.toString().split('\n') };
64+
}
65+
});
66+
67+
const convertedDockerCompose = computed(() => conversionResult.value.yaml);
68+
const errors = computed(() => conversionResult.value.errors);
69+
70+
const convertedDockerComposeBase64 = computed(() => `data:application/yaml;base64,${textToBase64(convertedDockerCompose.value)}`);
71+
const { download } = useDownloadFileFromBase64({ source: convertedDockerComposeBase64, filename: 'docker-compose.yml' });
72+
73+
const MONACO_EDITOR_OPTIONS = {
74+
automaticLayout: true,
75+
formatOnType: true,
76+
formatOnPaste: true,
77+
};
78+
</script>
79+
80+
<template>
81+
<div>
82+
<c-label label="Paste your existing Docker Compose:">
83+
<div relative w-full>
84+
<c-monaco-editor
85+
v-model:value="dockerCompose"
86+
theme="vs-dark"
87+
language="yaml"
88+
height="200px"
89+
:options="MONACO_EDITOR_OPTIONS"
90+
/>
91+
</div>
92+
</c-label>
93+
94+
<div v-if="errors.length > 0">
95+
<n-alert title="The following errors occured" type="error" mt-5>
96+
<ul>
97+
<li v-for="(message, index) of errors" :key="index">
98+
{{ message }}
99+
</li>
100+
</ul>
101+
</n-alert>
102+
</div>
103+
104+
<n-divider />
105+
106+
<n-grid cols="4" x-gap="12" w-full>
107+
<n-gi span="2">
108+
<c-select
109+
v-model:value="conversion"
110+
label-position="top"
111+
label="Docker Compose conversion:"
112+
:options="conversionOptions"
113+
placeholder="Select Docker Compose conversion"
114+
/>
115+
</n-gi>
116+
<n-gi span="2">
117+
<n-form-item label="Indent size:" label-placement="top" label-width="100" :show-feedback="false">
118+
<n-input-number v-model:value="indentSize" min="0" max="10" w-100px />
119+
</n-form-item>
120+
</n-gi>
121+
</n-grid>
122+
123+
<n-divider />
124+
125+
<div class="mb-6 flex flex-row items-center gap-2">
126+
<n-checkbox v-model:checked="expandPorts">
127+
Expand Ports
128+
</n-checkbox>
129+
<n-checkbox v-model:checked="expandVolumes">
130+
Expand Volumes
131+
</n-checkbox>
132+
</div>
133+
134+
<n-divider />
135+
136+
<TextareaCopyable :value="convertedDockerCompose" language="yaml" />
137+
138+
<div mt-5 flex justify-center>
139+
<c-button :disabled="dockerCompose === ''" secondary @click="download">
140+
Download converted docker-compose.yml
141+
</c-button>
142+
</div>
143+
</div>
144+
</template>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { BrandDocker } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'Docker Compose Format Converter',
6+
path: '/docker-compose-converter',
7+
description: 'Convert Docker Compose file between V1, 2.x, 3.x or CommonSpec and may expand ports/volumes syntaxes',
8+
keywords: ['docker', 'compose', 'converter'],
9+
component: () => import('./docker-compose-converter.vue'),
10+
icon: BrandDocker,
11+
createdAt: new Date('2024-01-04'),
12+
});

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ import { tool as pdfEncrypt } from './pdf-encrypt';
190190
import { tool as pdfLinearize } from './pdf-linearize';
191191
import { tool as manyUnitsConverter } from './many-units-converter';
192192
import { tool as powerConverter } from './power-converter';
193+
import { tool as dockerComposeConverter } from './docker-compose-converter';
193194
import { tool as yamlViewer } from './yaml-viewer';
194195
import { tool as barcodeReader } from './barcode-reader';
195196
import { tool as barcodeGenerator } from './barcode-generator';
@@ -349,6 +350,7 @@ export const toolsByCategory: ToolCategory[] = [
349350
dockerComposeToKubernetesConverter,
350351
dockerRunToKubernetesConverter,
351352
dockerComposeValidator,
353+
dockerComposeConverter,
352354
xmlFormatter,
353355
xsltTester,
354356
yamlViewer,

0 commit comments

Comments
 (0)