Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve core functionality (Logging, Config comparison, Code Quality) #2464

Merged
merged 15 commits into from
Jul 24, 2024
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,25 @@ This icon extension consists not only of icons but also brings some code. This i
6. Run tests with `bun test`

You will find more information about the official extension API in the [extension guides of VS Code](https://code.visualstudio.com/api/extension-guides/file-icon-theme).

### Enable logging

Logging can be enabled with the following settings:

```json
{
"material-icon-theme.enableLogging": true,
"material-icon-theme.logLevel": "debug",
}
```

The available log levels are:

- `error`: Only errors are logged
- `info`: Only info logs are logged
- `debug`: All logs are logged

Per default the logging is disabled as it can slow down the extension. If logging is enabled, the logs can be found in the output panel of VS Code under "Material Icon Theme".

> **Note**
> Please restart the extension after changing the logging settings to apply the changes.
Binary file modified bun.lockb
Binary file not shown.
38 changes: 25 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"url": "https://github.com/sponsors/PKief"
},
"engines": {
"vscode": "^1.51.0"
"vscode": "^1.55.0"
},
"homepage": "https://github.com/material-extensions/vscode-material-icon-theme/blob/main/README.md",
"repository": {
Expand Down Expand Up @@ -309,31 +309,43 @@
"minimum": 0,
"maximum": 1,
"description": "%configuration.saturation%"
},
"material-icon-theme.enableLogging": {
"type": "boolean",
"default": false,
"description": "%configuration.enableLogging%"
},
"material-icon-theme.logLevel": {
"type": "string",
"default": "info",
"enum": ["info", "error", "debug"],
"description": "%configuration.logLevel%"
}
}
}
},
"dependencies": {
"chroma-js": "^2.4.2",
"fast-deep-equal": "^3.1.3",
"svgson": "^5.3.1"
},
"devDependencies": {
"@biomejs/biome": "1.8.2",
"@softarc/sheriff-core": "^0.15.1",
"@types/chroma-js": "^2.4.4",
"@types/glob": "^7.2.0",
"@types/puppeteer": "^5.4.6",
"@types/vscode": "~1.51.0",
"@vscode/test-electron": "^2.3.9",
"axios": "^1.4.0",
"bun-types": "^1.1.12",
"changelog-machine": "^1.0.2",
"esbuild": "^0.21.4",
"glob": "^8.0.3",
"puppeteer": "^22.11.0",
"rimraf": "^6.0.0",
"svg-color-linter": "^1.3.0",
"@types/puppeteer": "^5.4.7",
"@types/vscode": "~1.55.0",
"@vscode/test-electron": "^2.4.1",
"axios": "^1.7.2",
"bun-types": "^1.1.20",
"changelog-machine": "^1.1.0",
"esbuild": "^0.21.5",
"glob": "^8.1.0",
"puppeteer": "^22.13.1",
"rimraf": "^6.0.1",
"svg-color-linter": "^1.4.0",
"svgo": "^2.8.0",
"typescript": "^5.5.3"
"typescript": "^5.5.4"
}
}
4 changes: 3 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,7 @@
"configuration.files.color": "Change the color of the file icons.",
"configuration.hidesExplorerArrows": "Hide explorer arrows before folder.",
"configuration.opacity": "Change the opacity of the icons.",
"configuration.saturation": "Change the saturation of the icons."
"configuration.saturation": "Change the saturation of the icons.",
"configuration.enableLogging": "Enable logging to the output channel.",
"configuration.logLevel": "Set the log level for output messages."
}
36 changes: 36 additions & 0 deletions src/core/generator/applyConfigToIcons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Config } from '../models/icons/config';
import { generateFileIcons } from './fileGenerator';
import { generateFolderIcons } from './folderGenerator';
import { setIconOpacity } from './iconOpacity';
import { setIconSaturation } from './iconSaturation';

/**
* Apply the configuration to the icons. But only if the configuration has changed.
* If the affectedConfig is not set then all icons will be updated.
*
* @param config Configuration that customizes the icons and the manifest.
* @param affectedConfig Set of configuration keys that have changed so that not all functions need to be executed.
*/
export const applyConfigToIcons = async (config: Config, oldConfig: Config) => {
if (config.files.color !== oldConfig.files.color) {
await generateFileIcons(
config.files.color,
config.opacity,
config.saturation
);
}
if (config.folders.color !== oldConfig.folders.color) {
await generateFolderIcons(
config.folders.color,
config.opacity,
config.saturation
);
}

if (config.opacity !== oldConfig.opacity) {
await setIconOpacity(config.opacity, config.files.associations);
}
if (config.saturation !== oldConfig.saturation) {
await setIconSaturation(config.saturation, config.files.associations);
}
};
67 changes: 34 additions & 33 deletions src/core/generator/clones/clonesGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { writeFileSync } from 'node:fs';
import { getFileConfigHash } from '../../helpers/configHash';
import { merge } from '../../helpers/object';
import { writeToFile } from '../../helpers/writeFile';
import { logger } from '../../logging/logger';
import type {
Config,
CustomClone,
Expand All @@ -18,37 +19,37 @@ import { cloneIcon, createCloneConfig } from './utils/cloning';
* Creates custom icons by cloning already existing icons and changing
* their colors, based on the user's provided configurations.
*/
export function customClonesIcons(
export const customClonesIcons = async (
manifest: Manifest,
config: Config
): Manifest {
): Promise<Manifest> => {
let clonedIconsManifest = merge<Manifest>({}, manifest);
const hash = getFileConfigHash(config);

// create folder clones as specified by the user in the options
config.folders?.customClones?.forEach((clone) => {
const cloneCfg = createIconClone(clone, manifest, hash);
for (const clone of config.folders?.customClones ?? []) {
const cloneCfg = await createIconClone(clone, manifest, hash);
clonedIconsManifest = merge(clonedIconsManifest, cloneCfg);
});
}

// create file clones as specified by the user in the options
config.files?.customClones?.forEach((clone) => {
const cloneCfg = createIconClone(clone, manifest, hash);
for (const clone of config.files?.customClones ?? []) {
const cloneCfg = await createIconClone(clone, manifest, hash);
clonedIconsManifest = merge(clonedIconsManifest, cloneCfg);
});
}

return clonedIconsManifest;
}
};

/**
* Creates custom icons by cloning already existing icons and changing
* their colors, based on the configurations provided by the extension.
* (this is meant to be called at build time)
*/
export function generateConfiguredClones(
export const generateConfiguredClones = async (
iconsList: FolderTheme[] | FileIcons,
manifest: Manifest
) {
) => {
let iconsToClone: CustomClone[] = [];

if (Array.isArray(iconsList)) {
Expand All @@ -75,34 +76,34 @@ export function generateConfiguredClones(
);
}

iconsToClone?.forEach((clone) => {
const clones = getCloneData(clone, manifest, '', '', cloneIconExtension);
for (const icon of iconsToClone) {
const clones = getCloneData(icon, manifest, '', '', cloneIconExtension);
if (!clones) {
return;
}

clones.forEach((clone) => {
for (const clone of clones) {
try {
// generates the new icon content (svg)
const content = cloneIcon(clone.base.path, clone.color);
const content = await cloneIcon(clone.base.path, clone.color);

// write the new .svg file to the disk
writeFileSync(clone.path, content);
await writeToFile(clone.path, content);
} catch (error) {
console.error(error);
logger.error(error);
return;
}
});
});
}
}
}
};

/** Checks if there are any custom clones to be created */
export function hasCustomClones(config: Config): boolean {
export const hasCustomClones = (config: Config): boolean => {
return (
(config.folders?.customClones?.length ?? 0) > 0 ||
(config.files?.customClones?.length ?? 0) > 0
);
}
};

/**
* Generates a clone of an icon.
Expand All @@ -111,11 +112,11 @@ export function hasCustomClones(config: Config): boolean {
* @param hash current hash being applied to the icons
* @returns a partial icon configuration for the new icon
*/
function createIconClone(
const createIconClone = async (
cloneOpts: FolderIconClone | FileIconClone,
manifest: Manifest,
hash: string
): Manifest {
): Promise<Manifest> => {
// get clones to be created
const clones = getCloneData(cloneOpts, manifest, clonesFolder, hash);
if (!clones) {
Expand All @@ -124,17 +125,17 @@ function createIconClone(

const clonesConfig = createCloneConfig();

clones.forEach((clone) => {
for (const clone of clones) {
try {
// generates the new icon content (svg)
const content = cloneIcon(clone.base.path, clone.color, hash);
const content = await cloneIcon(clone.base.path, clone.color, hash);

try {
// write the new .svg file to the disk
writeFileSync(clone.path, content);
await writeToFile(clone.path, content);
} catch (error) {
console.error(error);
return;
logger.error(error);
return manifest;
}

// sets the icon path for the cloned icon in the configuration
Expand Down Expand Up @@ -176,9 +177,9 @@ function createIconClone(
});
}
} catch (error) {
console.error(error);
logger.error(error);
}
});
}

return clonesConfig;
}
};
Loading