Skip to content
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
57 changes: 57 additions & 0 deletions .github/workflows/quasar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,63 @@ jobs:
if: always()
run: sccache --show-stats

# Rustfmt and Clippy for the Quasar crates.
#
# The repository-wide `Rust Lint` workflow runs `cargo fmt --check` and
# `cargo clippy` from the repository root, and those only ever see members of
# the root workspace. Every Quasar crate declares its own `[workspace]`,
# because `quasar build` runs `cargo metadata --locked` against a per-project
# lockfile, so they cannot be members and that workflow never sees them.
#
# This walks Cargo manifests rather than reusing `build-and-test`'s project
# list, which is directories named exactly `quasar`. That list misses
# `tokens/quasar-metadata`, a vendored library three of the examples depend on.
# Linting is a host build that needs neither the Quasar CLI nor platform-tools,
# and it does not vary by Solana version, so it runs once rather than per
# matrix entry.
lint:
needs: changes
if: needs.changes.outputs.total_projects != '0'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache Cargo registry and git
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-lint-${{ runner.os }}-${{ hashFiles('**/Cargo.toml') }}
restore-keys: |
cargo-lint-${{ runner.os }}-
- name: Rustfmt and Clippy
run: |
failed=()
while read -r manifest; do
crate=$(dirname "$manifest")
echo "::group::$crate"
if ! ( cd "$crate" && cargo fmt --check ); then
echo "::error::cargo fmt --check failed for $crate"
failed+=("$crate (fmt)")
fi
# Matches the repository-wide Clippy job: diverging_sub_expression is
# a false positive from the program macro's expansion.
if ! ( cd "$crate" && cargo clippy -- -D warnings -A clippy::diverging_sub_expression ); then
echo "::error::cargo clippy failed for $crate"
failed+=("$crate (clippy)")
fi
echo "::endgroup::"
done < <(grep -rl --include=Cargo.toml 'quasar-lang' . | grep -v '/target/' | sort)

if [ ${#failed[@]} -ne 0 ]; then
printf '%s\n' "Lint failures:" "${failed[@]}"
exit 1
fi
echo "All Quasar crates pass rustfmt and clippy."

summary:
needs: [changes, build-and-test]
if: always()
Expand Down
5 changes: 5 additions & 0 deletions basics/account-data/quasar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ idl-build = ["quasar-lang/idl-build"]
# git. Keep this rev in lockstep with the CLI rev installed by
# .github/workflows/quasar.yml.
quasar-lang = { git = "https://github.com/blueshift-gg/quasar", rev = "be60fca" }
# Pinned: quasar-lang asks for zeropod "0.3.3" and wincode 0.4, but zeropod
# 0.3.4 moved to wincode 0.5, so a fresh resolve (no lockfile is committed)
# splits the graph across two wincode versions and every Pod* trait bound
# fails. Unpin when quasar-lang's pinned rev accepts zeropod 0.3.4+.
zeropod = "=0.3.3"
solana-instruction = { version = "3.2.0" }

[dev-dependencies]
Expand Down
7 changes: 6 additions & 1 deletion basics/account-data/quasar/src/instructions/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ pub fn handle_create_address_info(
) -> Result<(), ProgramError> {
let rent = Rent::get()?;
accounts.address_info.set_inner(
AddressInfoInner { house_number, name, street, city },
AddressInfoInner {
house_number,
name,
street,
city,
},
accounts.payer.to_account_view(),
rent.lamports_per_byte(),
rent.exemption_threshold_raw(),
Expand Down
12 changes: 9 additions & 3 deletions basics/account-data/quasar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use quasar_lang::prelude::*;

mod instructions;
pub mod instructions;
use instructions::*;
mod state;
pub mod state;
#[cfg(test)]
mod tests;

Expand All @@ -30,6 +30,12 @@ mod quasar_account_data {
street: String<50>,
city: String<50>,
) -> Result<(), ProgramError> {
instructions::handle_create_address_info(&mut ctx.accounts, name, house_number, street, city)
instructions::handle_create_address_info(
&mut ctx.accounts,
name,
house_number,
street,
city,
)
}
}
5 changes: 5 additions & 0 deletions basics/checking-accounts/quasar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ idl-build = ["quasar-lang/idl-build"]
# git. Keep this rev in lockstep with the CLI rev installed by
# .github/workflows/quasar.yml.
quasar-lang = { git = "https://github.com/blueshift-gg/quasar", rev = "be60fca" }
# Pinned: quasar-lang asks for zeropod "0.3.3" and wincode 0.4, but zeropod
# 0.3.4 moved to wincode 0.5, so a fresh resolve (no lockfile is committed)
# splits the graph across two wincode versions and every Pod* trait bound
# fails. Unpin when quasar-lang's pinned rev accepts zeropod 0.3.4+.
zeropod = "=0.3.3"
solana-instruction = { version = "3.2.0" }

[dev-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ pub struct CheckAccountsAccountConstraints {
}

#[inline(always)]
pub fn handle_check_accounts(_accounts: &mut CheckAccountsAccountConstraints) -> Result<(), ProgramError> {
pub fn handle_check_accounts(
_accounts: &mut CheckAccountsAccountConstraints,
) -> Result<(), ProgramError> {
// All validation happens declaratively via the account types above.
// If any check fails, the runtime rejects the transaction before this runs.
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion basics/checking-accounts/quasar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use quasar_lang::prelude::*;

mod instructions;
pub mod instructions;
use instructions::*;
#[cfg(test)]
mod tests;
Expand Down
5 changes: 5 additions & 0 deletions basics/close-account/quasar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ idl-build = ["quasar-lang/idl-build"]
# git. Keep this rev in lockstep with the CLI rev installed by
# .github/workflows/quasar.yml.
quasar-lang = { git = "https://github.com/blueshift-gg/quasar", rev = "be60fca" }
# Pinned: quasar-lang asks for zeropod "0.3.3" and wincode 0.4, but zeropod
# 0.3.4 moved to wincode 0.5, so a fresh resolve (no lockfile is committed)
# splits the graph across two wincode versions and every Pod* trait bound
# fails. Unpin when quasar-lang's pinned rev accepts zeropod 0.3.4+.
zeropod = "=0.3.3"
solana-instruction = { version = "3.2.0" }

[dev-dependencies]
Expand Down
6 changes: 5 additions & 1 deletion basics/close-account/quasar/src/instructions/create_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ pub fn handle_create_user(
let user_address = *accounts.user.to_account_view().address();
let rent = Rent::get()?;
accounts.user_account.set_inner(
UserInner { bump, user: user_address, name },
UserInner {
bump,
user: user_address,
name,
},
accounts.user.to_account_view(),
rent.lamports_per_byte(),
rent.exemption_threshold_raw(),
Expand Down
4 changes: 2 additions & 2 deletions basics/close-account/quasar/src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod create_user;
pub mod close_user;
pub mod create_user;

pub use create_user::*;
pub use close_user::*;
pub use create_user::*;
9 changes: 6 additions & 3 deletions basics/close-account/quasar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use quasar_lang::prelude::*;

mod instructions;
pub mod instructions;
use instructions::*;
mod state;
pub mod state;
#[cfg(test)]
mod tests;

Expand All @@ -16,7 +16,10 @@ mod quasar_close_account {

/// Create a user account with a name.
#[instruction(discriminator = 0)]
pub fn create_user(ctx: Ctx<CreateUserAccountConstraints>, name: String<50>) -> Result<(), ProgramError> {
pub fn create_user(
ctx: Ctx<CreateUserAccountConstraints>,
name: String<50>,
) -> Result<(), ProgramError> {
let bump = ctx.bumps.user_account;
instructions::handle_create_user(&mut ctx.accounts, name, bump)
}
Expand Down
3 changes: 2 additions & 1 deletion basics/close-account/quasar/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ fn close_user_rejects_a_non_owner(test: &mut Test) {

test.send(instruction).fails_with(QuasarError::InvalidPda);
assert!(
test.account(victim_account).is_some_and(|account| !account.data.is_empty()),
test.account(victim_account)
.is_some_and(|account| !account.data.is_empty()),
"the victim's account must survive the failed close"
);
}
5 changes: 5 additions & 0 deletions basics/counter/quasar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ idl-build = ["quasar-lang/idl-build"]
# git. Keep this rev in lockstep with the CLI rev installed by
# .github/workflows/quasar.yml.
quasar-lang = { git = "https://github.com/blueshift-gg/quasar", rev = "be60fca" }
# Pinned: quasar-lang asks for zeropod "0.3.3" and wincode 0.4, but zeropod
# 0.3.4 moved to wincode 0.5, so a fresh resolve (no lockfile is committed)
# splits the graph across two wincode versions and every Pod* trait bound
# fails. Unpin when quasar-lang's pinned rev accepts zeropod 0.3.4+.
zeropod = "=0.3.3"
solana-instruction = { version = "3.2.0" }

[dev-dependencies]
Expand Down
4 changes: 1 addition & 3 deletions basics/counter/quasar/src/instructions/increment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ pub struct IncrementAccountConstraints {
#[inline(always)]
pub fn handle_increment(accounts: &mut IncrementAccountConstraints) -> Result<(), ProgramError> {
let current: u64 = accounts.counter.count.into();
let next = current
.checked_add(1)
.ok_or(CounterError::MathOverflow)?;
let next = current.checked_add(1).ok_or(CounterError::MathOverflow)?;
accounts.counter.count = PodU64::from(next);
Ok(())
}
4 changes: 3 additions & 1 deletion basics/counter/quasar/src/instructions/initialize_counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ pub struct InitializeCounterAccountConstraints {
}

#[inline(always)]
pub fn handle_initialize_counter(accounts: &mut InitializeCounterAccountConstraints) -> Result<(), ProgramError> {
pub fn handle_initialize_counter(
accounts: &mut InitializeCounterAccountConstraints,
) -> Result<(), ProgramError> {
accounts.counter.set_inner(CounterInner { count: 0 });
Ok(())
}
4 changes: 2 additions & 2 deletions basics/counter/quasar/src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod initialize_counter;
pub mod increment;
pub mod initialize_counter;

pub use initialize_counter::*;
pub use increment::*;
pub use initialize_counter::*;
8 changes: 5 additions & 3 deletions basics/counter/quasar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use quasar_lang::prelude::*;

mod error;
mod instructions;
pub mod instructions;
use instructions::*;
mod state;
pub mod state;
#[cfg(test)]
mod tests;

Expand All @@ -16,7 +16,9 @@ mod quasar_counter {
use super::*;

#[instruction(discriminator = 0)]
pub fn initialize_counter(ctx: Ctx<InitializeCounterAccountConstraints>) -> Result<(), ProgramError> {
pub fn initialize_counter(
ctx: Ctx<InitializeCounterAccountConstraints>,
) -> Result<(), ProgramError> {
instructions::handle_initialize_counter(&mut ctx.accounts)
}

Expand Down
6 changes: 4 additions & 2 deletions basics/counter/quasar/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ fn initialize_counter_creates_the_pda(test: &mut Test) {

// The counter PDA and system program are canonical derivations, so the
// generated instruction only asks for the payer.
test.send(InitializeCounterInstruction { payer: PAYER }).succeeds();
test.send(InitializeCounterInstruction { payer: PAYER })
.succeeds();

let state = test.read::<Counter>(counter);
assert_eq!(u64::from(state.count), 0);
Expand All @@ -26,7 +27,8 @@ fn initialize_counter_creates_the_pda(test: &mut Test) {
fn increment_advances_the_count(test: &mut Test) {
test.add(Wallet::new().at(PAYER));
let counter = test.derive_pda(Counter::seeds(&PAYER));
test.send(InitializeCounterInstruction { payer: PAYER }).succeeds();
test.send(InitializeCounterInstruction { payer: PAYER })
.succeeds();

test.send(IncrementInstruction { counter }).succeeds();

Expand Down
5 changes: 5 additions & 0 deletions basics/create-account/quasar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ idl-build = ["quasar-lang/idl-build"]
# git. Keep this rev in lockstep with the CLI rev installed by
# .github/workflows/quasar.yml.
quasar-lang = { git = "https://github.com/blueshift-gg/quasar", rev = "be60fca" }
# Pinned: quasar-lang asks for zeropod "0.3.3" and wincode 0.4, but zeropod
# 0.3.4 moved to wincode 0.5, so a fresh resolve (no lockfile is committed)
# splits the graph across two wincode versions and every Pod* trait bound
# fails. Unpin when quasar-lang's pinned rev accepts zeropod 0.3.4+.
zeropod = "=0.3.3"
solana-instruction = { version = "3.2.0" }

[dev-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ pub fn handle_create_system_account(
let lamports = rent.minimum_balance_unchecked(0);
accounts
.system_program
.create_account(&accounts.payer, &accounts.new_account, lamports, 0u64, &system_program_address)
.create_account(
&accounts.payer,
&accounts.new_account,
lamports,
0u64,
&system_program_address,
)
.invoke()
}
6 changes: 4 additions & 2 deletions basics/create-account/quasar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use quasar_lang::prelude::*;

mod instructions;
pub mod instructions;
use instructions::*;
#[cfg(test)]
mod tests;
Expand All @@ -15,7 +15,9 @@ mod quasar_create_account {

/// Create a new system-owned account via CPI to the system program.
#[instruction(discriminator = 0)]
pub fn create_system_account(ctx: Ctx<CreateSystemAccountAccountConstraints>) -> Result<(), ProgramError> {
pub fn create_system_account(
ctx: Ctx<CreateSystemAccountAccountConstraints>,
) -> Result<(), ProgramError> {
instructions::handle_create_system_account(&mut ctx.accounts)
}
}
5 changes: 5 additions & 0 deletions basics/cross-program-invocation/quasar/hand/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ idl-build = ["quasar-lang/idl-build"]
# git. Keep this rev in lockstep with the CLI rev installed by
# .github/workflows/quasar.yml.
quasar-lang = { git = "https://github.com/blueshift-gg/quasar", rev = "be60fca" }
# Pinned: quasar-lang asks for zeropod "0.3.3" and wincode 0.4, but zeropod
# 0.3.4 moved to wincode 0.5, so a fresh resolve (no lockfile is committed)
# splits the graph across two wincode versions and every Pod* trait bound
# fails. Unpin when quasar-lang's pinned rev accepts zeropod 0.3.4+.
zeropod = "=0.3.3"
solana-instruction = { version = "3.2.0" }

[dev-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ pub struct PullLeverAccountConstraints {
}

#[inline(always)]
pub fn handle_pull_lever(accounts: &PullLeverAccountConstraints, name: &str) -> Result<(), ProgramError> {
pub fn handle_pull_lever(
accounts: &PullLeverAccountConstraints,
name: &str,
) -> Result<(), ProgramError> {
log("Hand is pulling the lever!");

// Build the switch_power instruction data for the lever program.
Expand Down
9 changes: 6 additions & 3 deletions basics/cross-program-invocation/quasar/hand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use quasar_lang::prelude::*;

mod instructions;
pub mod instructions;
use instructions::*;
#[cfg(test)]
mod tests;
Expand All @@ -26,7 +26,10 @@ mod quasar_hand {

/// Pull the lever by invoking the lever program's switch_power via CPI.
#[instruction(discriminator = 0)]
pub fn pull_lever(ctx: Ctx<PullLeverAccountConstraints>, name: String<50>) -> Result<(), ProgramError> {
instructions::handle_pull_lever(&mut ctx.accounts, name)
pub fn pull_lever(
ctx: Ctx<PullLeverAccountConstraints>,
name: String<50>,
) -> Result<(), ProgramError> {
instructions::handle_pull_lever(&ctx.accounts, name)
}
}
Loading
Loading