Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 0 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ jobs:
uses: fermyon/actions/spin/setup@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
version: "v3.0.0-rc.1"

- name: Run Test
shell: bash
Expand Down
111 changes: 69 additions & 42 deletions bin/j2w.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import path from 'path';

const componentizeVersion = '0.16.0';
const __filename = new URL(import.meta.url).pathname;
const __dirname = __filename.substring(0, __filename.lastIndexOf('/'));

Expand Down Expand Up @@ -39,16 +40,22 @@ const args = yargs(hideBin(process.argv))

const src = args.input;
const outputPath = args.output;
const inputChecksumPath = `${src}.checksum`;
const buildDataPath = `${src}.buildData.json`;

// Function to calculate file checksum
async function calculateChecksum(filePath) {
const fileBuffer = await readFile(filePath);
const hash = createHash('sha256');
hash.update(fileBuffer);
return hash.digest('hex');
try {
const fileBuffer = await readFile(filePath);
const hash = createHash('sha256');
hash.update(fileBuffer);
return hash.digest('hex');
} catch (error) {
console.error(`Error calculating checksum for file ${filePath}:`, error);
throw error;
}
}


// Function to check if a file exists
async function fileExists(filePath) {
try {
Expand All @@ -59,47 +66,67 @@ async function fileExists(filePath) {
}
}

async function getExistingChecksum(checksumPath) {
if (await fileExists(checksumPath)) {
return await readFile(checksumPath, 'utf8');
async function getExistingBuildData(buildaDataPath) {
try {
if (await fileExists(buildaDataPath)) {
const buildData = await readFile(buildDataPath, 'utf8');
return JSON.parse(buildData);
}
return null;
} catch (error) {
console.error(`Error reading existing checksum file at ${buildDataPath}:`, error);
throw error;
}
return null;
}

async function saveChecksum(checksumPath, checksum) {
await writeFile(checksumPath, checksum);
async function saveBuildData(buildDataPath, checksum, version) {
try {
const checksumData = {
version,
checksum
};
await writeFile(buildDataPath, JSON.stringify(checksumData, null, 2));
} catch (error) {
console.error(`Error saving checksum file at ${buildDataPath}:`, error);
throw error;
}
}

(async () => {
const sourceChecksum = await calculateChecksum(src);
const existingChecksum = await getExistingChecksum(inputChecksumPath);

if ((existingChecksum === sourceChecksum) && fileExists(outputPath)) {
console.log("No changes detected in source file. Skipping componentization.");
return;
}

const source = await readFile(src, 'utf8');

// Check if a non-default wit directory is supplied
const witPath = args.witPath ? resolve(args.witPath) : path.join(__dirname, 'wit');
if (args.witPath) {
console.log(`Using user-provided wit in: ${witPath}`);
try {
const sourceChecksum = await calculateChecksum(src);
const existingBuildData = await getExistingBuildData(buildDataPath);

if (existingBuildData?.version == componentizeVersion && existingBuildData?.checksum === sourceChecksum && await fileExists(outputPath)) {
console.log("No changes detected in source file. Skipping componentization.");
return;
}

const source = await readFile(src, 'utf8');

// Check if a non-default wit directory is supplied
const witPath = args.witPath ? resolve(args.witPath) : path.join(__dirname, 'wit');
if (args.witPath) {
console.log(`Using user-provided wit in: ${witPath}`);
}

const { component } = await componentize(source, {
sourceName: basename(src),
witPath,
worldName: args.triggerType,
disableFeatures: [],
enableFeatures: ["http"],
enableAot: args.aot
});

await writeFile(outputPath, component);

// Save the checksum of the input file along with the componentize version
await saveBuildData(buildDataPath, sourceChecksum, componentizeVersion);

console.log("Component successfully written.");
} catch (error) {
console.error("An error occurred during the componentization process:", error);
process.exit(1);
}

const { component } = await componentize(source, {
sourceName: basename(src),
witPath,
worldName: args.triggerType,
disableFeatures: [],
enableFeatures: ["http"],
enableAot: args.aot
});

await writeFile(outputPath, component);

// Save the checksum of the input file
await saveChecksum(inputChecksumPath, sourceChecksum);

console.log("Component successfully written.");
})();
})();
5 changes: 4 additions & 1 deletion bin/wit/deps/cli/command.wit
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package wasi:[email protected].0;
package wasi:[email protected].3;

@since(version = 0.2.0)
world command {
@since(version = 0.2.0)
include imports;

@since(version = 0.2.0)
export run;
}
4 changes: 4 additions & 0 deletions bin/wit/deps/cli/environment.wit
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@since(version = 0.2.0)
interface environment {
/// Get the POSIX-style environment variables.
///
Expand All @@ -7,12 +8,15 @@ interface environment {
/// Morally, these are a value import, but until value imports are available
/// in the component model, this import function should return the same
/// values each time it is called.
@since(version = 0.2.0)
get-environment: func() -> list<tuple<string, string>>;

/// Get the POSIX-style arguments to the program.
@since(version = 0.2.0)
get-arguments: func() -> list<string>;

/// Return a path that programs should use as their initial current working
/// directory, interpreting `.` as shorthand for this.
@since(version = 0.2.0)
initial-cwd: func() -> option<string>;
}
13 changes: 13 additions & 0 deletions bin/wit/deps/cli/exit.wit
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
@since(version = 0.2.0)
interface exit {
/// Exit the current instance and any linked instances.
@since(version = 0.2.0)
exit: func(status: result);

/// Exit the current instance and any linked instances, reporting the
/// specified status code to the host.
///
/// The meaning of the code depends on the context, with 0 usually meaning
/// "success", and other values indicating various types of failure.
///
/// This function does not return; the effect is analogous to a trap, but
/// without the connotation that something bad has happened.
@unstable(feature = cli-exit-with-code)
exit-with-code: func(status-code: u8);
}
28 changes: 22 additions & 6 deletions bin/wit/deps/cli/imports.wit
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
package wasi:[email protected].0;
package wasi:[email protected].3;

@since(version = 0.2.0)
world imports {
include wasi:clocks/[email protected];
include wasi:filesystem/[email protected];
include wasi:sockets/[email protected];
include wasi:random/[email protected];
include wasi:io/[email protected];
@since(version = 0.2.0)
include wasi:clocks/[email protected];
@since(version = 0.2.0)
include wasi:filesystem/[email protected];
@since(version = 0.2.0)
include wasi:sockets/[email protected];
@since(version = 0.2.0)
include wasi:random/[email protected];
@since(version = 0.2.0)
include wasi:io/[email protected];

@since(version = 0.2.0)
import environment;
@since(version = 0.2.0)
import exit;
@since(version = 0.2.0)
import stdin;
@since(version = 0.2.0)
import stdout;
@since(version = 0.2.0)
import stderr;
@since(version = 0.2.0)
import terminal-input;
@since(version = 0.2.0)
import terminal-output;
@since(version = 0.2.0)
import terminal-stdin;
@since(version = 0.2.0)
import terminal-stdout;
@since(version = 0.2.0)
import terminal-stderr;
}
2 changes: 2 additions & 0 deletions bin/wit/deps/cli/run.wit
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@since(version = 0.2.0)
interface run {
/// Run the program.
@since(version = 0.2.0)
run: func() -> result;
}
15 changes: 12 additions & 3 deletions bin/wit/deps/cli/stdio.wit
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
@since(version = 0.2.0)
interface stdin {
use wasi:io/[email protected].{input-stream};
@since(version = 0.2.0)
use wasi:io/[email protected].{input-stream};

@since(version = 0.2.0)
get-stdin: func() -> input-stream;
}

@since(version = 0.2.0)
interface stdout {
use wasi:io/[email protected].{output-stream};
@since(version = 0.2.0)
use wasi:io/[email protected].{output-stream};

@since(version = 0.2.0)
get-stdout: func() -> output-stream;
}

@since(version = 0.2.0)
interface stderr {
use wasi:io/[email protected].{output-stream};
@since(version = 0.2.0)
use wasi:io/[email protected].{output-stream};

@since(version = 0.2.0)
get-stderr: func() -> output-stream;
}
13 changes: 13 additions & 0 deletions bin/wit/deps/cli/terminal.wit
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
/// In the future, this may include functions for disabling echoing,
/// disabling input buffering so that keyboard events are sent through
/// immediately, querying supported features, and so on.
@since(version = 0.2.0)
interface terminal-input {
/// The input side of a terminal.
@since(version = 0.2.0)
resource terminal-input;
}

Expand All @@ -13,37 +15,48 @@ interface terminal-input {
/// In the future, this may include functions for querying the terminal
/// size, being notified of terminal size changes, querying supported
/// features, and so on.
@since(version = 0.2.0)
interface terminal-output {
/// The output side of a terminal.
@since(version = 0.2.0)
resource terminal-output;
}

/// An interface providing an optional `terminal-input` for stdin as a
/// link-time authority.
@since(version = 0.2.0)
interface terminal-stdin {
@since(version = 0.2.0)
use terminal-input.{terminal-input};

/// If stdin is connected to a terminal, return a `terminal-input` handle
/// allowing further interaction with it.
@since(version = 0.2.0)
get-terminal-stdin: func() -> option<terminal-input>;
}

/// An interface providing an optional `terminal-output` for stdout as a
/// link-time authority.
@since(version = 0.2.0)
interface terminal-stdout {
@since(version = 0.2.0)
use terminal-output.{terminal-output};

/// If stdout is connected to a terminal, return a `terminal-output` handle
/// allowing further interaction with it.
@since(version = 0.2.0)
get-terminal-stdout: func() -> option<terminal-output>;
}

/// An interface providing an optional `terminal-output` for stderr as a
/// link-time authority.
@since(version = 0.2.0)
interface terminal-stderr {
@since(version = 0.2.0)
use terminal-output.{terminal-output};

/// If stderr is connected to a terminal, return a `terminal-output` handle
/// allowing further interaction with it.
@since(version = 0.2.0)
get-terminal-stderr: func() -> option<terminal-output>;
}
21 changes: 13 additions & 8 deletions bin/wit/deps/clocks/monotonic-clock.wit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package wasi:[email protected].0;
package wasi:[email protected].3;
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time.
///
Expand All @@ -7,38 +7,43 @@ package wasi:[email protected];
///
/// A monotonic clock is a clock which has an unspecified initial value, and
/// successive reads of the clock will produce non-decreasing values.
///
/// It is intended for measuring elapsed time.
@since(version = 0.2.0)
interface monotonic-clock {
use wasi:io/[email protected].{pollable};
@since(version = 0.2.0)
use wasi:io/[email protected].{pollable};

/// An instant in time, in nanoseconds. An instant is relative to an
/// unspecified initial value, and can only be compared to instances from
/// the same monotonic-clock.
@since(version = 0.2.0)
type instant = u64;

/// A duration of time, in nanoseconds.
@since(version = 0.2.0)
type duration = u64;

/// Read the current value of the clock.
///
/// The clock is monotonic, therefore calling this function repeatedly will
/// produce a sequence of non-decreasing values.
@since(version = 0.2.0)
now: func() -> instant;

/// Query the resolution of the clock. Returns the duration of time
/// corresponding to a clock tick.
@since(version = 0.2.0)
resolution: func() -> duration;

/// Create a `pollable` which will resolve once the specified instant
/// occured.
/// has occurred.
@since(version = 0.2.0)
subscribe-instant: func(
when: instant,
) -> pollable;

/// Create a `pollable` which will resolve once the given duration has
/// elapsed, starting at the time at which this function was called.
/// occured.
/// Create a `pollable` that will resolve after the specified duration has
/// elapsed from the time this function is invoked.
@since(version = 0.2.0)
subscribe-duration: func(
when: duration,
) -> pollable;
Expand Down
Loading
Loading