Skip to content

Commit 7039888

Browse files
committed
feat: add umask computation
Fix CorentinTh#719
1 parent 3d63fde commit 7039888

File tree

4 files changed

+139
-3
lines changed

4 files changed

+139
-3
lines changed

src/tools/chmod-calculator/chmod-calculator.service.test.ts

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it } from 'vitest';
2-
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation } from './chmod-calculator.service';
2+
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service';
33

44
describe('chmod-calculator', () => {
55
describe('computeChmodOctalRepresentation', () => {
@@ -454,4 +454,106 @@ describe('chmod-calculator', () => {
454454
});
455455
});
456456
});
457+
458+
describe('computeUmaskRepresentation', () => {
459+
it('get the umask from permissions', () => {
460+
expect(
461+
computeUmaskRepresentation({
462+
permissions: {
463+
owner: { read: true, write: true, execute: true },
464+
group: { read: true, write: true, execute: true },
465+
public: { read: true, write: true, execute: true },
466+
flags: { setuid: false, setgid: false, stickybit: false },
467+
},
468+
}),
469+
).to.deep.eq({
470+
octal: '000',
471+
symbolic: 'umask u=rwx,g=rwx,o=rwx',
472+
});
473+
474+
expect(
475+
computeUmaskRepresentation({
476+
permissions: {
477+
owner: { read: false, write: false, execute: false },
478+
group: { read: false, write: false, execute: false },
479+
public: { read: false, write: false, execute: false },
480+
flags: { setuid: false, setgid: false, stickybit: false },
481+
},
482+
}),
483+
).to.deep.eq({
484+
octal: '777',
485+
symbolic: 'umask u=,g=,o=',
486+
});
487+
488+
expect(
489+
computeUmaskRepresentation({
490+
permissions: {
491+
owner: { read: false, write: true, execute: false },
492+
group: { read: false, write: true, execute: true },
493+
public: { read: true, write: false, execute: true },
494+
flags: { setuid: false, setgid: false, stickybit: false },
495+
},
496+
}),
497+
).to.deep.eq({
498+
octal: '542',
499+
symbolic: 'umask u=w,g=wx,o=rx',
500+
});
501+
502+
expect(
503+
computeUmaskRepresentation({
504+
permissions: {
505+
owner: { read: true, write: false, execute: false },
506+
group: { read: false, write: true, execute: false },
507+
public: { read: false, write: false, execute: true },
508+
flags: { setuid: false, setgid: false, stickybit: false },
509+
},
510+
}),
511+
).to.deep.eq({
512+
octal: '356',
513+
symbolic: 'umask u=r,g=w,o=x',
514+
});
515+
516+
expect(
517+
computeUmaskRepresentation({
518+
permissions: {
519+
owner: { read: false, write: false, execute: true },
520+
group: { read: false, write: true, execute: false },
521+
public: { read: true, write: false, execute: false },
522+
flags: { setuid: false, setgid: false, stickybit: false },
523+
},
524+
}),
525+
).to.deep.eq({
526+
octal: '653',
527+
symbolic: 'umask u=x,g=w,o=r',
528+
});
529+
530+
expect(
531+
computeUmaskRepresentation({
532+
permissions: {
533+
owner: { read: false, write: true, execute: false },
534+
group: { read: false, write: true, execute: false },
535+
public: { read: false, write: true, execute: false },
536+
flags: { setuid: false, setgid: false, stickybit: false },
537+
},
538+
}),
539+
).to.deep.eq({
540+
octal: '555',
541+
symbolic: 'umask u=w,g=w,o=w',
542+
});
543+
544+
expect(
545+
computeUmaskRepresentation({
546+
permissions: {
547+
owner: { read: false, write: false, execute: true },
548+
group: { read: false, write: true, execute: false },
549+
public: { read: true, write: false, execute: false },
550+
flags: { setuid: true, setgid: true, stickybit: true },
551+
},
552+
}),
553+
).to.deep.eq({
554+
octal: '653',
555+
symbolic: 'umask u=x,g=w,o=r',
556+
});
557+
});
558+
});
457559
});

src/tools/chmod-calculator/chmod-calculator.service.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from 'lodash';
22
import type { GroupPermissions, Permissions, SpecialPermissions } from './chmod-calculator.types';
33

4-
export { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation };
4+
export { computeUmaskRepresentation, computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation };
55

66
function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string {
77
const permissionValue = { read: 4, write: 2, execute: 1 };
@@ -86,3 +86,30 @@ function computePermissionsFromChmodSymbolicRepresentation(symbolicPermissions:
8686

8787
return computePermissionsFromChmodOctalRepresentation(octalString);
8888
}
89+
90+
function computeUmaskRepresentation({ permissions }: { permissions: Permissions }): {
91+
octal: string
92+
symbolic: string
93+
} {
94+
const permissionValue = { read: 'r', write: 'w', execute: 'x' };
95+
const getGroupPermissionValue = (permission: GroupPermissions) =>
96+
_.reduce(permission, (acc, isPermSet, key) => acc + ((isPermSet ? _.get(permissionValue, key, '') : '')), '');
97+
98+
const symbolic = `umask u=${getGroupPermissionValue(permissions.owner)},g=${getGroupPermissionValue(permissions.group)},o=${getGroupPermissionValue(permissions.public)}`;
99+
const octal = (0o777 - Number.parseInt(
100+
computeChmodOctalRepresentation({
101+
permissions:
102+
{
103+
owner: permissions.owner,
104+
group: permissions.group,
105+
public: permissions.public,
106+
flags: { setuid: false, setgid: false, stickybit: false },
107+
},
108+
}), 8))
109+
.toString(8)
110+
.padStart(3, '0');
111+
112+
return {
113+
symbolic, octal,
114+
};
115+
}

src/tools/chmod-calculator/chmod-calculator.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { useThemeVars } from 'naive-ui';
33
44
import InputCopyable from '../../components/InputCopyable.vue';
5-
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation } from './chmod-calculator.service';
5+
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service';
66
77
import type { Group, Scope } from './chmod-calculator.types';
88
import { useValidation } from '@/composable/validation';
@@ -81,6 +81,7 @@ watch(
8181
8282
const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value }));
8383
const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions: permissions.value }));
84+
const umask = computed(() => computeUmaskRepresentation({ permissions: permissions.value }));
8485
</script>
8586

8687
<template>
@@ -155,6 +156,11 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions
155156
</div>
156157

157158
<InputCopyable :value="`chmod ${octal} path`" readonly />
159+
160+
<c-card title="Umask">
161+
<InputCopyable :value="umask.octal" readonly />
162+
<InputCopyable :value="umask.symbolic" readonly />
163+
</c-card>
158164
</div>
159165
</template>
160166

src/tools/chmod-calculator/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const tool = defineTool({
1616
'recursive',
1717
'generator',
1818
'octal',
19+
'umask',
1920
],
2021
component: () => import('./chmod-calculator.vue'),
2122
icon: FileInvoice,

0 commit comments

Comments
 (0)