Add initial Linux support #150

Key features of Linux support:
- It supports python 3 scripts execution.
- It supports Flatpak and Snap installation for software
  clean-up/configurations.
- Extensive documentation.
This commit is contained in:
undergroundwires
2023-07-30 22:54:24 +02:00
parent e8199932b4
commit c404dfebe2
19 changed files with 3847 additions and 36 deletions

View File

@@ -4,6 +4,7 @@ import { IProjectInformation } from '@/domain/IProjectInformation';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import WindowsData from '@/application/collections/windows.yaml';
import MacOsData from '@/application/collections/macos.yaml';
import LinuxData from '@/application/collections/linux.yaml';
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
import { Application } from '@/domain/Application';
import { parseCategoryCollection } from './CategoryCollectionParser';
@@ -28,7 +29,7 @@ const CategoryCollectionParser: CategoryCollectionParserType = (file, info) => {
};
const PreParsedCollections: readonly CollectionData [] = [
WindowsData, MacOsData,
WindowsData, MacOsData, LinuxData,
];
function validateCollectionsData(collections: readonly CollectionData[]) {

View File

@@ -3,5 +3,5 @@ import { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/I
export class ShellScriptSyntax implements ILanguageSyntax {
public readonly commentDelimiters = ['#'];
public readonly commonCodeParts = ['(', ')', 'else', 'fi'];
public readonly commonCodeParts = ['(', ')', 'else', 'fi', 'done'];
}

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,8 @@ export class CodeRunner {
function getExecuteCommand(scriptPath: string, environment: Environment): string {
switch (environment.os) {
case OperatingSystem.Linux:
return `x-terminal-emulator -e '${scriptPath}'`;
case OperatingSystem.macOS:
return `open -a Terminal.app ${scriptPath}`;
// Another option with graphical sudo would be

View File

@@ -0,0 +1,93 @@
import { OperatingSystem } from '@/domain/OperatingSystem';
import { InstructionsBuilder } from './InstructionsBuilder';
export class LinuxInstructionsBuilder extends InstructionsBuilder {
constructor() {
super(OperatingSystem.Linux);
super
.withStep(() => ({
action: {
instruction: 'Download the file.',
details: 'You should have already been prompted to save the script file.'
+ '<br/>If this was not the case or you did not save the script when prompted,'
+ '<br/>please try to download your script file again.',
},
}))
.withStep(() => ({
action: {
instruction: 'Open terminal.',
details:
'Opening terminal changes based on the distro you run.'
+ '<br/>You may search for "Terminal" in your application launcher to find it.'
+ '<br/>'
+ '<br/>Alternatively use terminal shortcut for your distro if it has one by default:'
+ '<ul>'
+ '<li><code>Ctrl-Alt-T</code>: Ubuntu, CentOS, Linux Mint, Elementary OS, ubermix, Kali…</li>'
+ '<li><code>Super-T</code>: Pop!_OS…</li>'
+ '<li><code>Alt-T</code>: Parrot OS…</li>'
+ '<li><code>Ctrl-Alt-Insert</code>: Bodhi Linux…</li>'
+ '</ul>'
+ '<br/>'
,
},
}))
.withStep(() => ({
action: {
instruction: 'Navigate to the folder where you downloaded the file e.g.:',
},
code: {
instruction: 'cd ~/Downloads',
details: 'Press on <code>enter/return</code> key after running the command.'
+ '<br/>If the file is not downloaded on Downloads folder,'
+ '<br/>change <code>Downloads</code> to path where the file is downloaded.'
+ '<br/>'
+ '<br/>This command means:'
+ '<ul>'
+ '<li><code>cd</code> will change the current folder.</li>'
+ '<li><code>~</code> is the user home directory.</li>'
+ '</ul>',
},
}))
.withStep((data) => ({
action: {
instruction: 'Give the file execute permissions:',
},
code: {
instruction: `chmod +x ${data.fileName}`,
details: 'Press on <code>enter/return</code> key after running the command.<br/>'
+ 'It will make the file executable. <br/>'
+ 'If you use desktop environment you can alternatively (instead of running the command):'
+ '<ol>'
+ '<li>Locate the file using your file manager.</li>'
+ '<li>Right click on the file, select "Properties".</li>'
+ '<li>Go to "Permissions" and check "Allow executing file as program".</li>'
+ '</ol>'
+ '<br/>These GUI steps and name of options may change depending on your file manager.'
,
},
}))
.withStep((data) => ({
action: {
instruction: 'Execute the file:',
},
code: {
instruction: `./${data.fileName}`,
details:
'If you have desktop environment, instead of running this command you can alternatively:'
+ '<ol>'
+ '<li>Locate the file using your file manager.</li>'
+ '<li>Right click on the file, select "Run as program".</li>'
+ '</ol>'
,
},
}))
.withStep(() => ({
action: {
instruction: 'If asked, enter your administrator password.',
details: 'As you type, your password will be hidden but the keys are still registered, so keep typing.'
+ '<br/>Press on <code>enter/return</code> key after typing your password.'
+ '<br/>Administrator privileges are required to configure OS.',
},
}));
}
}

View File

@@ -2,9 +2,11 @@ import { OperatingSystem } from '@/domain/OperatingSystem';
import { InstructionsBuilder } from './Data/InstructionsBuilder';
import { MacOsInstructionsBuilder } from './Data/MacOsInstructionsBuilder';
import { IInstructionListData } from './InstructionListData';
import { LinuxInstructionsBuilder } from './Data/LinuxInstructionsBuilder';
const builders = new Map<OperatingSystem, InstructionsBuilder>([
[OperatingSystem.macOS, new MacOsInstructionsBuilder()],
[OperatingSystem.Linux, new LinuxInstructionsBuilder()],
]);
export function hasInstructions(os: OperatingSystem) {

View File

@@ -50,6 +50,7 @@ function renderOsName(os: OperatingSystem): string {
switch (os) {
case OperatingSystem.Windows: return 'Windows';
case OperatingSystem.macOS: return 'macOS';
case OperatingSystem.Linux: return 'Linux (preview)';
default: throw new RangeError(`Cannot render os name: ${OperatingSystem[os]}`);
}
}

View File

@@ -24,7 +24,7 @@ function beatifyAutoLinks(content: string): string {
if (!content) {
return content;
}
return content.replaceAll(/(?<!\]\(|\[\d+\]:\s+|https?\S+)((?:https?):\/\/[^\s\])]*)(?:[\])](?!\()|$|\s)/gm, (_$, urlMatch) => {
return content.replaceAll(/(?<!\]\(|\[\d+\]:\s+|https?\S+|`)((?:https?):\/\/[^\s\])]*)(?:[\])](?!\()|$|\s)/gm, (_$, urlMatch) => {
return toReadableLink(urlMatch);
});
}

View File

@@ -56,7 +56,7 @@ function hasDesktopVersion(os: OperatingSystem): boolean {
function getOperatingSystemName(os: OperatingSystem): string {
switch (os) {
case OperatingSystem.Linux:
return 'Linux';
return 'Linux (preview)';
case OperatingSystem.macOS:
return 'macOS';
case OperatingSystem.Windows:

View File

@@ -1,7 +1,7 @@
<template>
<div id="container">
<h1 class="child title" >{{ title }}</h1>
<h2 class="child subtitle">Enforce privacy &amp; security on Windows and macOS</h2>
<h2 class="child subtitle">Enforce privacy &amp; security on Windows, macOS and Linux</h2>
</div>
</template>