Skip to content

Commit

Permalink
feat: sort contracts when generating files
Browse files Browse the repository at this point in the history
  • Loading branch information
hstove committed Oct 14, 2022
1 parent c9f19e4 commit 6636047
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 57 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-worms-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"clarigen-deno": patch
---

When generating files, contracts are sorted by name. This prevents git changes due to the indeterminant way that Clarinet outputs contract order
20 changes: 10 additions & 10 deletions artifacts/clarigen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,6 @@ export type OkType<R> = R extends ResponseOk<infer V, unknown> ? V : never;
export type ErrType<R> = R extends ResponseErr<unknown, infer V> ? V : never;

export const contracts = {
ftTrait: {
'functions': {},
'maps': {},
'variables': {},
constants: {},
'fungible_tokens': [],
'non_fungible_tokens': [],
'clarity_version': 'Clarity1',
contractName: 'ft-trait',
},
counter: {
'functions': {
decrement: {
Expand Down Expand Up @@ -191,6 +181,16 @@ export const contracts = {
'clarity_version': 'Clarity1',
contractName: 'counter',
},
ftTrait: {
'functions': {},
'maps': {},
'variables': {},
constants: {},
'fungible_tokens': [],
'non_fungible_tokens': [],
'clarity_version': 'Clarity1',
contractName: 'ft-trait',
},
tester: {
'functions': {
complexArgs: {
Expand Down
4 changes: 4 additions & 0 deletions scripts/check-git.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ if ! [[ -z $(git status -s) ]]; then
echo "Git is not clean. Exiting release"
exit 1
fi
if [[ $(git log origin/main..main) ]]; then
echo "Some commits not pushed"
exit 1
fi
exit 0
2 changes: 1 addition & 1 deletion src/cli/clarinet-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { array, parseToml, Schema, string, Type, unknown } from '../deps.ts';
import { cwdResolve } from './utils.ts';
import { cwdResolve } from './cli-utils.ts';

export const ClarinetSchema = Schema({
project: {
Expand Down
45 changes: 45 additions & 0 deletions src/cli/cli-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { relative, resolve } from '../deps.ts';
import { SessionContract } from '../session.ts';
import { getContractName, toCamelCase } from '../utils.ts';
export { getContractName, toCamelCase, toKebabCase } from '../utils.ts';

export function encodeVariableName(name: string) {
if (/^[A-Z\-_]*$/.test(name)) return name.replaceAll('-', '_');
return toCamelCase(name);
}

export async function fileExists(filename: string): Promise<boolean> {
try {
await Deno.stat(filename);
// successful, file or directory must exist
return true;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
// file or directory does not exist
return false;
} else {
// unexpected error, maybe permissions, pass it along
throw error;
}
}
}

export function cwdResolve(...paths: string[]) {
return resolve(Deno.cwd(), ...paths);
}

export function cwdRelative(path: string) {
return relative(Deno.cwd(), path);
}

// Sort contracts alphabetically by their contract name.
// Used to preserve ordering when generating files
export function sortContracts(contracts: SessionContract[]) {
const nameSorted = [...contracts].sort((a, b) => {
if (getContractName(a.contract_id) < getContractName(b.contract_id)) {
return -1;
}
return 1;
});
return nameSorted;
}
2 changes: 1 addition & 1 deletion src/cli/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolve } from '../../deps.ts';
import { Command } from '../cli-deps.ts';
import { cwdRelative, fileExists } from '../utils.ts';
import { cwdRelative, fileExists } from '../cli-utils.ts';
import { CONFIG_FILE, configFilePath } from '../config.ts';
import { log } from '../logger.ts';

Expand Down
2 changes: 1 addition & 1 deletion src/cli/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '../deps.ts';
import { ClarinetConfig, getClarinetConfig } from './clarinet-config.ts';
import { log } from './logger.ts';
import { cwdRelative, cwdResolve, fileExists } from './utils.ts';
import { cwdRelative, cwdResolve, fileExists } from './cli-utils.ts';

export const CONFIG_FILE = 'Clarigen.toml' as const;

Expand Down
2 changes: 1 addition & 1 deletion src/cli/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
isClarityAbiTuple,
} from '../encoder.ts';
import { ClarityAbiArg, ClarityAbiFunction, ClarityAbiType } from '../types.ts';
import { toCamelCase } from './utils.ts';
import { toCamelCase } from './cli-utils.ts';

export const jsTypeFromAbiType = (
val: ClarityAbiType,
Expand Down
8 changes: 6 additions & 2 deletions src/cli/files/base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { abiFunctionType, jsTypeFromAbiType } from '../declaration.ts';
import type { Session, SessionContract } from '../../session.ts';
import { encodeVariableName, toCamelCase } from '../utils.ts';
import {
encodeVariableName,
sortContracts,
toCamelCase,
} from '../cli-utils.ts';
import { types } from '../type-stub.ts';
import { ClarityAbiVariable } from '../../types.ts';

Expand Down Expand Up @@ -47,7 +51,7 @@ export function generateContractMeta(
export function generateBaseFile(
session: Session,
) {
const contractDefs = session.contracts.map((contract) => {
const contractDefs = sortContracts(session.contracts).map((contract) => {
const meta = generateContractMeta(contract);
const id = contract.contract_id.split('.')[1];
const keyName = toCamelCase(id);
Expand Down
2 changes: 1 addition & 1 deletion src/cli/files/docs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Config, OutputType } from '../config.ts';
import { Session } from '../../session.ts';
import { generateMarkdown, generateReadme } from '../../docs/markdown.ts';
import { getContractName } from '../utils.ts';
import { getContractName } from '../cli-utils.ts';
import { relative } from '../../deps.ts';
import { log } from '../logger.ts';
import { runDenoFmt } from '../format.ts';
Expand Down
4 changes: 2 additions & 2 deletions src/cli/files/esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '../deployments.ts';
// import { log } from '../logger.ts';
import { Session } from '../../session.ts';
import { cwdRelative, getContractName } from '../utils.ts';
import { cwdRelative, getContractName, sortContracts } from '../cli-utils.ts';
import { generateAccountsCode } from './accounts.ts';

export async function parseDeployment(path: string) {
Expand Down Expand Up @@ -100,7 +100,7 @@ export function collectContractDeployments(
config: Config,
): FullContractDeployments {
const full = Object.fromEntries(
session.contracts.map((contract) => {
sortContracts(session.contracts).map((contract) => {
const contractName = getContractName(contract.contract_id);
const contractDeployments = Object.fromEntries(
DEPLOYMENT_NETWORKS.map((network) => {
Expand Down
2 changes: 1 addition & 1 deletion src/cli/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Config, configFilePath } from './config.ts';
import { generate } from './generate.ts';
import { colors, dirname, join } from '../deps.ts';
import { log } from './logger.ts';
import { cwdRelative } from './utils.ts';
import { cwdRelative } from './cli-utils.ts';

const runDelay = 3000;
let lastRun = new Date().getTime();
Expand Down
4 changes: 2 additions & 2 deletions src/docs/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
createContractDocInfo,
} from './index.ts';
import { Session, SessionContract } from '../session.ts';
import { getContractName } from '../cli/utils.ts';
import { getContractName, sortContracts } from '../cli/cli-utils.ts';

export function generateMarkdown(
{ contract, contractFile }: {
Expand Down Expand Up @@ -131,7 +131,7 @@ ${privates.map(tocLine).join('\n')}`;
}

export function generateReadme(session: Session) {
const contractLines = session.contracts.map((contract) => {
const contractLines = sortContracts(session.contracts).map((contract) => {
const name = getContractName(contract.contract_id, false);
const fileName = `${name}.md`;
return `- [\`${name}\`](${fileName})`;
Expand Down
2 changes: 1 addition & 1 deletion src/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
ResponseOk,
} from './types.ts';
import { types } from './clarinet-deps.ts';
import { toCamelCase, toKebabCase } from './cli/utils.ts';
import { toCamelCase, toKebabCase } from './utils.ts';

export function ok<T, Err = never>(value: T): ResponseOk<T, Err> {
return {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './runner.ts';
export * from './factory-types.ts';
export * from './session.ts';
export * from './chain.ts';
export * from './utils.ts';
31 changes: 0 additions & 31 deletions src/cli/utils.ts → src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { relative, resolve } from '../deps.ts';

export const toCamelCase = (
input: string | number | symbol,
titleCase?: boolean,
Expand Down Expand Up @@ -28,35 +26,6 @@ export function toKebabCase(
return matches.join('-').toLowerCase();
}

export function encodeVariableName(name: string) {
if (/^[A-Z\-_]*$/.test(name)) return name.replaceAll('-', '_');
return toCamelCase(name);
}

export async function fileExists(filename: string): Promise<boolean> {
try {
await Deno.stat(filename);
// successful, file or directory must exist
return true;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
// file or directory does not exist
return false;
} else {
// unexpected error, maybe permissions, pass it along
throw error;
}
}
}

export function cwdResolve(...paths: string[]) {
return resolve(Deno.cwd(), ...paths);
}

export function cwdRelative(path: string) {
return relative(Deno.cwd(), path);
}

export function getContractName(identifier: string, camelCase = true) {
const name = identifier.split('.')[1];
return camelCase ? toCamelCase(name) : name;
Expand Down
2 changes: 1 addition & 1 deletion test_pkg/config_test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Config, OutputType } from '../src/cli/config.ts';
import { cwdRelative } from '../src/cli/utils.ts';
import { cwdRelative } from '../src/cli/cli-utils.ts';
import { assert, assertEquals } from '../src/deps.ts';

Deno.test({
Expand Down
26 changes: 24 additions & 2 deletions test_pkg/docs_test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { runClarinet } from '../src/cli/clarinet-wrapper.ts';
import { Config } from '../src/cli/config.ts';
import { getContractName } from '../src/cli/utils.ts';
import { getContractName } from '../src/cli/cli-utils.ts';
import { assert, assertEquals } from '../src/dev-deps.ts';
import { createContractDocInfo } from '../src/docs/index.ts';
import { generateMarkdown } from '../src/docs/markdown.ts';
import { generateMarkdown, generateReadme } from '../src/docs/markdown.ts';

Deno.test({
name: 'Generating contract docs',
Expand Down Expand Up @@ -66,3 +66,25 @@ Return a number`));
});
},
});

Deno.test({
name: 'Ordering is always the same for README',
async fn() {
let file: string | undefined;
const count = 10;
const config = await Config.load();
async function testReadme() {
const session = await runClarinet(config);
const readme = generateReadme(session);
if (file) {
assertEquals(readme, file);
}
file = readme;
}
const runs: Promise<void>[] = [];
for (let i = 0; i < count; i++) {
runs.push(testReadme());
}
await Promise.all(runs);
},
});

0 comments on commit 6636047

Please sign in to comment.