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

Feat/ansible language support #41

Merged
merged 3 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to the "kubernetes-yaml-formatter-x" extension will be docum

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## 2.0.0 (29 Feb 2024)

Ansible is now a targetable format!

Also this exension will set itself as the default for ansible files the same way that it does for yaml. (You can disable this)

## 1.4.0 (29 Feb 2024)

Hello from a day that doesn't exist!
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ It makes format yaml on save default to `true`, you can disable it:
}
```

## Default Language settings

```json
"[yaml]": {
"editor.defaultFormatter": "kiliantyler.kubernetes-yaml-formatter-x",
"editor.formatOnSave": true
},
"[ansible]": {
"editor.defaultFormatter": "kiliantyler.kubernetes-yaml-formatter-x",
"editor.formatOnSave": true
}
```

## Config Precidence

```
Expand Down
2 changes: 1 addition & 1 deletion dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"github-releases": {
"yamlfmt": {
"repo": "google/yamlfmt",
"version": "v0.11.0"
"version": "main"
}
}
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "Kubernetes YAML Formatter X",
"icon": "images/icon.png",
"description": "An even better YAML formatter for DevOps like Kubernetes, Ansible, CI/CD, etc.",
"version": "1.4.0",
"version": "2.0.0",
"publisher": "kiliantyler",
"repository": {
"url": "https://github.com/kiliantyler/kubernetes-yaml-formatter-x.git",
Expand Down Expand Up @@ -124,6 +124,10 @@
"[yaml]": {
"editor.defaultFormatter": "kiliantyler.kubernetes-yaml-formatter-x",
"editor.formatOnSave": true
},
"[ansible]": {
"editor.defaultFormatter": "kiliantyler.kubernetes-yaml-formatter-x",
"editor.formatOnSave": true
}
}
},
Expand Down
11 changes: 11 additions & 0 deletions src/cmd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as path from 'path';
import { platform } from 'node:process';

export function getCmd(): string {
// __dirname is `out`, so go back one level
let cmd = path.join(path.dirname(__dirname), 'bin', 'yamlfmt');
if (platform === 'win32') {
cmd = path.join(path.dirname(__dirname), 'bin', 'yamlfmt.exe');
}
return cmd;
}
195 changes: 195 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as process from 'child_process';
import { getCmd } from './cmd';

// Write the configuration file
export function writeConfig(context: vscode.ExtensionContext) {
// Get the path to the config file
const file = configFileLocation(context);

// If the file path is not defined, log an error and return
if (!file) {
console.error(`cannot get extension storage uri path`);
return;
}

if (writeConfigFile(file)) {
console.debug(`Wrote config file to ${file}`);
}
}

function writeConfigFile(file: string): boolean {

let config = generateConfig();
try {
// Write the config file
fs.writeFileSync(file, config, { encoding: "utf8" });
console.error(`Wrote config file to ${file}`);
(global as any).configFileLocation = file;
return true;
} catch (err) {
console.error(`write config: ${err}`);
vscode.window.showErrorMessage(`Write config file: ${err}`);
return false;
}
}

function generateConfig(): string {
const tabSize = vscode.workspace.getConfiguration("", {
languageId: `yaml`,
}).get(`editor.tabSize`, 2);
// Read the user's settings and write them to the config file
let conf = vscode.workspace.getConfiguration();
const formatterType = conf.get('kubernetes-yaml-formatter-x.formatterType', 'basic');
const retainLineBreaks = conf.get('kubernetes-yaml-formatter-x.retainLineBreaks', false);
const retainLineBreaksSingle = conf.get('kubernetes-yaml-formatter-x.retainLineBreaksSingle', false);
const scanFoldedAsLiteral = conf.get('kubernetes-yaml-formatter-x.scanFoldedAsLiteral', false);
const indentlessArrays = conf.get('kubernetes-yaml-formatter-x.indentlessArrays', false);
const disallowAnchors = conf.get('kubernetes-yaml-formatter-x.disallowAnchors', false);
const maxLineLength = conf.get('kubernetes-yaml-formatter-x.maxLineLength', 80);
const dropMergeTag = conf.get('kubernetes-yaml-formatter-x.dropMergeTag', false);
const padLineComments = conf.get('kubernetes-yaml-formatter-x.padLineComments', false);
const includeDocumentStart = conf.get('kubernetes-yaml-formatter-x.includeDocumentStart', false);
// Get the EOL character from the user's settings
let eof = "~";
switch (conf.get('files.eol')) {
case "\n":
eof = "lf";
break;
case "\r\n":
eof = "crlf";
break;
default:
eof = "~";
break;
}
let config = `formatter:
type: ${formatterType}
indent: ${tabSize}
line_ending: ${eof}
retain_line_breaks: ${retainLineBreaks}
retain_line_breaks_single: ${retainLineBreaksSingle}
scan_folded_as_literal: ${scanFoldedAsLiteral}
include_document_start: ${includeDocumentStart}
indentless_arrays: ${indentlessArrays}
disallow_anchors: ${disallowAnchors}
max_line_length: ${maxLineLength}
drop_merge_tag: ${dropMergeTag}
pad_line_comments: ${padLineComments}

`;
return config;
}

export function getConfigFileLocation(context: vscode.ExtensionContext): string | undefined {
return configFileLocation(context);
}

// Get the path to the configuration file
function configFileLocation(context: vscode.ExtensionContext): string | undefined {
let fsPath = context.storageUri?.fsPath;
// If the path is not defined, use the system temp directory
if (!fsPath) {
try {
// Create a temporary directory for the extension
fsPath = path.join(os.tmpdir(), context.extension.id);
if (!fs.existsSync(fsPath)) {
// Create the directory if it doesn't exist
fs.mkdirSync(fsPath);
}
} catch (err) {
throw new Error(`create tmp dir: ${err}`);
}
// maybe we are in the dev/debug mode.
console.log(`cannot get extension storage uri fs path, fallback ${fsPath}`);
}
try {
fs.mkdirSync(fsPath, { recursive: true });
} catch (err) {
console.error(`mkdir ${fsPath}: ${err}`);
vscode.window.showErrorMessage(`mkdir extension storage uri path ${fsPath}: ${err}`);
}
// Return the path to the config file
return path.join(fsPath, "config.yaml");
}

function getWorkspaceConfig(uri: vscode.Uri): string | undefined {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);
if (!workspaceFolder) {
console.info(`No workspace folder for ${uri}`);
return;
}
// search for the config file in the workspace
let cmd = getCmd();
const sp = process.spawnSync(cmd, ['-debug', 'config', '-quiet'], {
cwd: workspaceFolder.uri.fsPath
});
if (sp.error) {
console.error(`workspace config: ${sp.error}`);
return;
}
for (let line of sp.stdout.toString().split('\n')) {
if (line.includes('Found config at')) {
let file = line.substring(25);
console.debug(`workspace config file: ${file}`);
return file;
}
}
console.log(`No workspace config found`);
return;
}

function getGlobalConfig(context: vscode.ExtensionContext): string | undefined{
let cmd = getCmd();
const sp = process.spawnSync(cmd, ['-global_conf', '-debug', 'config']);
if (sp.error) {
console.error(`global config: ${sp.error}`);
return;
}
for (let line of sp.stdout.toString().split('\n')) {
if (line.includes('Found config at')) {
let file = line.substring(25);
console.debug(`global config file: ${file}`);
return file;
}
}
console.log(`No global config found`);
return;
}

export function getConfigOption(option: string, context?: vscode.ExtensionContext, document?: vscode.TextDocument): string | undefined {
let conf = vscode.workspace.getConfiguration();
if (option === "workspace") {
if (document) {
return conf.get('kubernetes-yaml-formatter-x.config.useWorkspaceConfig') ? getWorkspaceConfig(document.uri) : undefined;
}
}
if (option === "global") {
if (context) {
return conf.get('kubernetes-yaml-formatter-x.config.useGlobalConfig') ? getGlobalConfig(context) : undefined;
}
}
return;
}

export function getConfigBool(option: string): boolean | undefined {
let conf = vscode.workspace.getConfiguration();
return conf.get(`kubernetes-yaml-formatter-x.config.${option}`);
}

export function removeConfig(context: vscode.ExtensionContext) {
// Remove the config file when the extension is deactivated
let file = (global as any).configFileLocation;
if (file) {
try {
fs.unlinkSync(file);
} catch (err) {
console.error(`unlink ${file}: ${err}`);
}
} else {
console.error(`Cannot get extension storage uri path`);
}
}
Loading