Skip to content

Commit

Permalink
B.O.H
Browse files Browse the repository at this point in the history
  • Loading branch information
bitBeater committed Jan 11, 2024
1 parent 18cd746 commit bd37b18
Show file tree
Hide file tree
Showing 15 changed files with 639 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,6 @@ dist
#deno
deno.lock

scripts
.tmp
tests/tmp/
tests/tmp/
.history
39 changes: 39 additions & 0 deletions scripts/check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env -S deno run -A
/**
* script to check code quality and consistency
*/
import { getEmptyFiles, getSkipTestSrcs, getsMissingTestSrcs, SRC_DIR, TESTS_DIR } from './utils.ts';

let exitCode = 0;

// check if there are src files with the @skip-test comment
const skipTestSrcFiles = getSkipTestSrcs();
if (skipTestSrcFiles.length > 0) {
for (const srcFile of skipTestSrcFiles) {
console.log(`%c[SKIP TEST] %c${srcFile}`, 'color: orange', 'color: yellow');
}
}

// check if there are src files WITHOUT TEST files
const srcFilesWithoutTestFile = getsMissingTestSrcs();
if (srcFilesWithoutTestFile.length > 0) {
for (const srcFile of srcFilesWithoutTestFile) {
console.log(`%c[WITHOUT TEST] %c${srcFile}`, 'color: red', 'color: #ff4900');
}
exitCode = 1;
}

// check if there are EMPTY TS FILES, in src or test
const emptyTsFiles = [...getEmptyFiles(SRC_DIR, 'ts'), ...getEmptyFiles(TESTS_DIR, 'test.ts')];
if (emptyTsFiles.length > 0) {
for (const tsFile of emptyTsFiles) {
console.log(`%c[EMPTY TS FILE] %c${tsFile}`, 'color: red', 'color: gray');
}
exitCode = 1;
}

if (exitCode === 0) {
console.log(`%c[CHECK PASS]`, 'color: green');
} else {
Deno.exit(exitCode);
}
19 changes: 19 additions & 0 deletions scripts/generate_test_files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env -S deno run -A
/** script to generate an empty .test.ts file for each .ts file that doesnt have one*/
import { writeFileAndDir } from 'utils/fs.ts';
import { getSkipTestSrcs, sourceFilePathToTestFilePath } from './utils.ts';

const skipTestSrcFiles = getSkipTestSrcs();

if (skipTestSrcFiles.length > 0) {
for (const srcFile of skipTestSrcFiles) {
console.log(`%c[SKIP TEST] %c${srcFile}`, 'color: orange', 'color: yellow');
}
}

for (const sourceFilePath of getSkipTestSrcs()) {
const testFilePath = sourceFilePathToTestFilePath(sourceFilePath);

console.log(`%c[GENERATE TEST] %c${testFilePath}`, 'color: green', 'color: yellow');
writeFileAndDir(testFilePath, '');
}
3 changes: 3 additions & 0 deletions scripts/mk_deb_pkg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env -S deno run --allow-read --allow-write --allow-env --allow-run
import { mkDebPkg } from './mk_deb_pkg_mod.ts';
await mkDebPkg();
124 changes: 124 additions & 0 deletions scripts/mk_deb_pkg_mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/** ./set_build_env.ts it needs to be evaluated befor everething so should be at top*/
import './set_build_env.ts';

import { log } from 'iggs-utils';
import { join, resolve } from 'std/path/mod.ts';
import { defaultConfig } from 'utils/config.ts';
import { copyFileRecursive, silentRemove, writeFileAndDir } from 'utils/fs.ts';
import { logger } from 'utils/logger.ts';
import { CONFIG_FILE_NAME, DEFAULT_SERVER_PROPERTIES_PATH, SYS_CONFIG_FILE_PATH } from 'utils/paths.ts';
import { pkgInfo } from '../src/utils/package_info.ts';
import { exe } from './utils.ts';

// setting application logger level. '-s' (silent) is used to shut down logger.
logger.logLevel = Deno.args.includes('-s') ? log.LogLevel.OFF : log.LogLevel.TRACE;
logger.prefix = `[MK_DEB_PKG]`;

/**
* Interface representing the structure of a Debian package's control file.
*/
interface DebianControlFile {
/** The unique identifier name of the package. */
Package: string;

/** The version of the package, following the Debian versioning scheme. */
Version: string;

/** The section to which the package belongs, such as 'utils', 'net', etc. */
Section?: string;

/** The priority of the package, indicating its importance. */
Priority?: 'required' | 'important' | 'standard' | 'optional' | 'extra';

/** The architecture for which the package is built, like 'amd64', 'i386'. */
Architecture: string;

/** Packages that must be installed for this package to work. */
Depends?: string;

/** Packages that are recommended for enhanced functionality. */
Recommends?: string;

/** Packages that are suggested but not necessary. */
Suggests?: string;

/** Indicates that the package enhances the functionality of other packages. */
Enhances?: string;

/** Packages that are required to be configured before this package is unpacked. */
PreDepends?: string;

/** Lists packages that are incompatible with this package. */
Breaks?: string;

/** Lists packages that cannot be installed alongside this package. */
Conflicts?: string;

/** Indicates that this package replaces other packages. */
Replaces?: string;

/** Declares that this package provides the functionality of another package. */
Provides?: string;

/** The disk space required by the package in kilobytes. */
'Installed-Size'?: number;

/** The name and email of the person or team responsible for the package. */
Maintainer: string;

/** A brief description of the package. */
Description: string;

/** URL of the homepage for the software or package. */
Homepage?: string;

/** Indicates the source packages used to build this package. */
'Built-Using'?: string;
}

export async function mkDebPkg(): Promise<string> {
const controlFile: DebianControlFile = {
Package: pkgInfo.name,
Version: pkgInfo.version,
Architecture: 'amd64',
Maintainer: pkgInfo.maintainer,
Description: pkgInfo.description,
Homepage: pkgInfo.homepage,
};

const controlFileContent = Object.entries(controlFile)
.reduce((prev, [key, value]) => `${prev}${key}: ${value}\n`, '');

logger.debug(`creating debian package`, '\n', controlFileContent);

const LINUXx64_BIN_PATH = join(resolve('dist'), 'bin', 'linux', 'x64', pkgInfo.name);
exe('deno', 'compile', '--unstable', '--target=x86_64-unknown-linux-gnu', '-A', '--output=' + LINUXx64_BIN_PATH, './src/main.ts');

// generating deb package directories
const ASSETS_DIR = resolve('assets');
const DEFAULT_CONFIG_FILE_PATH = resolve(ASSETS_DIR, 'defaults', CONFIG_FILE_NAME);
const DEFAULT_DEFAULT_SERVER_PROPERTIES_PATH = resolve(ASSETS_DIR, 'defaults', 'server.properties');

const PKG_DIR = resolve('dist', 'deb_package');
const PKG_ROOT = resolve(PKG_DIR, pkgInfo.name);
const PKG_BIN_PATH = join(PKG_ROOT, 'usr', 'bin', 'misela');
const PKG_CONTROL_FILE_PATH = join(PKG_ROOT, 'DEBIAN', 'control');
const PKG_DOC_PATH = join(PKG_ROOT, 'usr', 'share', 'doc', pkgInfo.name, 'README.md');
const PKG_SYS_CONFIG_FILE_PATH = join(PKG_ROOT, SYS_CONFIG_FILE_PATH);
const PKG_DEFAULT_SERVER_PROPERTIES_PATH = join(PKG_ROOT, DEFAULT_SERVER_PROPERTIES_PATH);
const DEB_PKG_PATH = resolve('dist', `${pkgInfo.name}_${pkgInfo.version}_linux_amd64.deb`);

silentRemove(PKG_DIR, { recursive: true });
writeFileAndDir(PKG_CONTROL_FILE_PATH, controlFileContent);
copyFileRecursive(LINUXx64_BIN_PATH, PKG_BIN_PATH);
copyFileRecursive('./README.md', PKG_DOC_PATH);
copyFileRecursive(DEFAULT_CONFIG_FILE_PATH, PKG_SYS_CONFIG_FILE_PATH);
copyFileRecursive(DEFAULT_DEFAULT_SERVER_PROPERTIES_PATH, PKG_DEFAULT_SERVER_PROPERTIES_PATH);
writeFileAndDir(PKG_DEFAULT_SERVER_PROPERTIES_PATH, JSON.stringify(defaultConfig, null, 4));

exe('dpkg-deb', '--build', PKG_ROOT, DEB_PKG_PATH);

console.log('%csuccessfully created deb package!!! 🍾🎉🎇', 'color:green');

return DEB_PKG_PATH;
}
117 changes: 117 additions & 0 deletions scripts/mk_tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env -S deno run -A
import { log } from 'iggs-utils';
import { logger } from 'utils/logger.ts';
import { pkgInfo } from 'utils/package_info.ts';
import { mkDebPkg } from './mk_deb_pkg_mod.ts';
import { exe } from './utils.ts';

export interface GhRelease {
url: string;
assets_url: string;
upload_url: string;
html_url: string;
id: number;
author: Author;
node_id: string;
tag_name: string;
target_commitish: string;
name: string;
draft: boolean;
prerelease: boolean;
created_at: string;
published_at: string;
assets: object[];
tarball_url: string;
zipball_url: string;
body: string;
reactions: Reactions;
mentions_count: number;
}

export interface Author {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
}

export interface Reactions {
url: string;
total_count: number;
'+1': number;
'-1': number;
laugh: number;
hooray: number;
confused: number;
heart: number;
rocket: number;
eyes: number;
}

logger.logLevel = log.LogLevel.TRACE;
logger.prefix = `[MK_TAG]`;

// lint
logger.info('linting...');
exe('deno', 'lint');

// format
logger.info('formatting...');
exe('deno', 'fmt');

// do code checks
logger.info('checking...');
exe('./scripts/check.ts');

// run tests
logger.info('testing...');
exe('deno', 'task', 'test');

// check if tag exists
logger.info(`checking if Tag ${pkgInfo.version} exists...`);
await checkIfTagExists();

// build deb package
logger.info('building deb package...');
const LINUX_BIN_PATH = await mkDebPkg();

// commit changes
logger.info('committing changes...');
exe('git', 'commit', '-m', `tag ${pkgInfo.version}`);

// tag the commit with the current version
logger.info(`tagging ${pkgInfo.version}...`);
exe('git', 'tag', pkgInfo.version);

// push the tag
logger.info('pushing tag...');
exe('git', 'push', 'origin', pkgInfo.version);

//Upload deb backage as release assets
logger.info(`uploading ${LINUX_BIN_PATH} asset...`);
exe('gh', 'release', 'create', pkgInfo.version, LINUX_BIN_PATH);

console.log('%csuccessfully togged!!! 🍾🎉🎇', 'color:green');

async function checkIfTagExists() {
const tags: GhRelease[] = await fetch('https://api.github.com/repos/alexrr2iggs/minecraft_server_updater/releases').then((r) => r.json());
const tagAlreadyExists = tags?.find((t: GhRelease) => t?.tag_name === pkgInfo.version);
if (tagAlreadyExists) {
console.warn(`Tag ${pkgInfo.version} already exists\nsee ${tagAlreadyExists.html_url}`);
Deno.exit(1);
}
}
9 changes: 9 additions & 0 deletions scripts/set_build_env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* This script is a simple workaround for ecmascript module import mechanism, that loads and evaluates modules in a top-down manner,
* which means it first loads and evaluates all import statements before executing the rest of the code in a module.
*
* Since the project relies on the deno's ".env" feature to determine the runing environment, with a default value of 'development'.
*
* take a look at utils/paths.ts
*/
Deno.env.set('DENO_ENV', 'compile_production');
29 changes: 29 additions & 0 deletions scripts/set_up_test_env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env -S deno run -A
import { log } from 'iggs-utils';
import { defaultConfig } from 'utils/config.ts';
import { writeFileAndDir } from 'utils/fs.ts';
import { logger } from 'utils/logger.ts';
import { DEFAULT_SERVER_PROPERTIES_PATH, SYS_CONFIG_FILE_PATH, USR_CONFIG_FILE_PATH } from 'utils/paths.ts';
import { FAKE_SERVER_VERSION_MANIFEST_V2_URL } from '../tests/test_utils/fake_api_server.ts';
Deno.env.set('DENO_ENV', 'development');
logger.logLevel = log.LogLevel.TRACE;

/**
* error: NotFound: No such file or directory (os error 2): open '/home/<user>/.development/minecraft-server-launcher/usr/share/minecraft-server-launcher/server.properties'
* const defaultServerPropertiesFile = Deno.openSync(DEFAULT_SERVER_PROPERTIES_PATH);
*/
writeFileAndDir(DEFAULT_SERVER_PROPERTIES_PATH, '#Minecraft server properties');

/**
* error: NotFound: No such file or directory (os error 2): readfile '/home/<user>/.development/minecraft-server-launcher/etc/minecraft-server-launcher/config.json'
* sysConf = Deno.readFileSync(SYS_CONFIG_FILE_PATH);
*/
writeFileAndDir(SYS_CONFIG_FILE_PATH, JSON.stringify(defaultConfig, undefined, 4));

//----------------------------------------------------------------------------------------------------------------------
// setting tests config file

const testConfig = { ...defaultConfig };
testConfig.versionManifestV2Url = FAKE_SERVER_VERSION_MANIFEST_V2_URL;

writeFileAndDir(USR_CONFIG_FILE_PATH, JSON.stringify(testConfig, undefined, 4));
Loading

0 comments on commit bd37b18

Please sign in to comment.