Skip to content

Commit

Permalink
Added spinner and additional documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
MitchPierias committed Apr 22, 2019
1 parent 9810ef6 commit 71ce3c6
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 42 deletions.
101 changes: 74 additions & 27 deletions src/configManager.ts
Original file line number Diff line number Diff line change
@@ -1,81 +1,128 @@
import axios from 'axios';
import * as path from 'path';
import * as mkdirpCallback from 'mkdirp';
import * as rimrafCallback from 'rimraf';
import {
readFile as readFileCallback,
writeFile as writeFileCallback,
exists as existsCallback,
} from 'fs';
import { promisify } from 'util';
import * as spinner from './cli/logIndicator';

const exists = promisify(existsCallback);
const mkdirp = promisify(mkdirpCallback);
const rimraf = promisify(rimrafCallback);
const writeFile = promisify(writeFileCallback);
const readFile = promisify(readFileCallback);

const configDirectory = '.lamington';
const configFilePath = path.join(configDirectory, 'config.json');
const encoding = 'utf8';
/** Root config directory path */
const CONFIG_DIRECTORY = '.lamington';
/** Config file fullpath */
const CONFIG_FILE_PATH = path.join(CONFIG_DIRECTORY, 'config.json');
/** Default encoding */
const ENCODING = 'utf8';

/** EOSIO and EOSIO.CDT configuration file paths */
export interface LamingtonConfig {
cdt: string;
eos: string;
keepAlive: boolean;
}

/**
* Fetches and stores the latest EOS configuration images
* @author Kevin Brown <github.com/thekevinbrown>
*/
export class ConfigManager {

/**
* EOSIO and EOSIO.CDT configuration settings
* @author Kevin Brown <github.com/thekevinbrown>
*/
private static config: LamingtonConfig;

private static async getAssetURL(organisation: string, repository: string, filter: string) {
// Get the latest releases from GitHub and search for the asset.
const result = await axios.get(
`https://api.github.com/repos/${organisation}/${repository}/releases/latest`
);

/**
* Downloads the organization's latest repository release image and
* returns the assets matching the specified filter
* @author Kevin Brown <github.com/thekevinbrown>
* @param organization Asset's case-sensitive repository organization
* @param repository Asset's case-sensitive repository name
* @param filter Resource filter
*/
private static async getAssetURL(organization: string, repository: string, filter: string) {
// Get the projects latest GitHub repository release
const result = await axios.get(`https://api.github.com/repos/${organization}/${repository}/releases/latest`);
// Handle failed GitHub request
if (!result.data || !result.data.assets || !Array.isArray(result.data.assets)) {
console.error(result);
throw new Error('Unexpected response from GitHub API.');
}

// Capture the GitHub url from response
const asset = result.data.assets.find((asset: any) =>
asset.browser_download_url.includes(filter)
);

if (!asset) {
throw new Error(
`Could not locate asset with ${filter} in the download URL in the ${organisation}/${repository} repository`
);
}

// Handle no assets found
if (!asset) throw new Error (
`Could not locate asset with ${filter} in the download URL in the ${organization}/${repository} repository`
);
// Return captured download url
return asset.browser_download_url as string;
}

/**
* Fetches the latest EOS repository release and freezes version changes
* in [[CONFIG_FILE_PATH]] to maintain a consistent development environment
* @author Kevin Brown <github.com/thekevinbrown>
*/
public static async initWithDefaults() {
// Get the latest releases from GitHub, then freeze them into a config file
// so as people work the versions don't change.
if (!(await exists(configFilePath))) {
// Begin log output
spinner.create('Loading configuration...');
// Check if configuration exists
if (!(await exists(CONFIG_FILE_PATH))) {
// Fetch the latest repository configuration
const defaultConfig: LamingtonConfig = {
cdt: await ConfigManager.getAssetURL('EOSIO', 'eosio.cdt', 'amd64.deb'),
eos: await ConfigManager.getAssetURL('EOSIO', 'eos', 'ubuntu-18.04'),
keepAlive:false
};

await mkdirp(configDirectory);
await writeFile(configFilePath, JSON.stringify(defaultConfig, null, 4), encoding);
// Create and/or update configuration file
await mkdirp(CONFIG_DIRECTORY);
await writeFile(CONFIG_FILE_PATH, JSON.stringify(defaultConfig, null, 4), ENCODING);
}

// Load existing configuration
await ConfigManager.loadConfigFromDisk();
spinner.end();
}

/**
* Loads the existing configuration file into [[ConfigManager.config]]
* @author Kevin Brown <github.com/thekevinbrown>
*/
private static async loadConfigFromDisk() {
ConfigManager.config = JSON.parse(await readFile(configFilePath, encoding));
// Read existing configuration and store
ConfigManager.config = JSON.parse(await readFile(CONFIG_FILE_PATH, ENCODING));
}

/**
* Returns the current EOSIO configuration
* @author Kevin Brown <github.com/thekevinbrown>
*/
static get eos() {
return ConfigManager.config.eos;
}

/**
* Returns the current EOSIO.CDT configuration
* @author Kevin Brown <github.com/thekevinbrown>
*/
static get cdt() {
return ConfigManager.config.cdt;
}

/**
* Returns the EOSIO keep alive setting or false
* @author Mitch Pierias <github.com/MitchPierias>
*/
static get keepAlive() {
return ConfigManager.config.keepAlive || false;
}
}
36 changes: 21 additions & 15 deletions src/contracts/typeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as fs from 'fs';
import * as path from 'path';
import { promisify } from 'util';
import mapTypes from './typeMap';
import * as spinner from './../cli/logIndicator';

const glob = promisify(globWithCallbacks);

Expand All @@ -16,8 +17,7 @@ type IndentedGeneratorLevel = { [key: string]: Array<string> | IndentedGenerator
type GeneratorLevel = Array<string | IndentedGeneratorLevel>;

/**
* Map Paramater Type
* @desc Parses a C++ type definition into a Typescript definition
* Parses a C++ type definition into a Typescript definition
* @author Kevin Brown <github.com/thekevinbrown>
* @author Mitch Pierias <github.com/MitchPierias>
* @param eosType
Expand All @@ -33,21 +33,28 @@ export const mapParameterType = (eosType: string) => {
}
};

/**
* Loads all `.abi` files and generates types
* @author Kevin Brown <github.com/thekevinbrown>
*/
export const generateAllTypes = async () => {
// Make sure there are files to even generate from.
// Load all `.abi` files
const files = await glob('**/*.abi');

if (files.length === 0) {
throw new Error('No ABI files to generate from. Exiting.');
}

for (const file of files) {
await generateTypes(file);
}
// Handle no files found
if (files.length === 0) throw new Error('No ABI files to generate from. Exiting.');
// Generate types for each file
for (const file of files) await generateTypes(file);
};

/**
* Generates a Typescript definition file from a contract ABI file
* @author Kevin Brown <github.com/thekevinbrown>
* @author Mitch Pierias <github.com/MitchPierias>
* @param contractIdentifier Path to file without extension
*/
export const generateTypes = async (contractIdentifier: string) => {
console.log(`Generating types for ${contractIdentifier}`);
// Notify generating has begun
spinner.create(`Generating types definitions`);

const contractName = path.basename(contractIdentifier);
const abiPath = path.join('.lamington', 'compiled_contracts', `${contractIdentifier}.abi`);
Expand All @@ -58,7 +65,7 @@ export const generateTypes = async (contractIdentifier: string) => {
{},
...abi.structs.map((struct: any) => ({ [struct['name']]: struct }))
);

// Prepend warning text
const result: GeneratorLevel = [
'// =====================================================',
'// WARNING: GENERATED FILE',
Expand All @@ -67,7 +74,6 @@ export const generateTypes = async (contractIdentifier: string) => {
'// =====================================================',
'',
];

// Imports
const imports = ['Account', 'Contract'];
if (contractTables.length > 0) imports.push('TableRowsResult');
Expand All @@ -86,7 +92,6 @@ export const generateTypes = async (contractIdentifier: string) => {
result.push(tableInterface);
result.push('');
}

// Generate contract type from ABI
const generatedContractActions = contractActions.map((action: any) => {
// With a function for each action
Expand Down Expand Up @@ -119,6 +124,7 @@ export const generateTypes = async (contractIdentifier: string) => {
result.push('');

await saveInterface(contractIdentifier, result);
spinner.end('');
};

const saveInterface = async (
Expand Down

0 comments on commit 71ce3c6

Please sign in to comment.