Skip to content

Commit

Permalink
Merge branch 'main' into bgw/rm-core-concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonyshew authored Nov 19, 2024
2 parents fe35cf5 + 3a494fe commit 1eebd2c
Show file tree
Hide file tree
Showing 21 changed files with 219 additions and 47 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/lint-pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Lint pull request title

on:
pull_request_target:
types:
- opened
- edited
- synchronize
- reopened

permissions:
pull-requests: read

jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Configure that a scope must always be provided.
requireScope: false
# Configure additional validation for the subject based on a regex.
# Ensures that the subject doesn't start with an uppercase character.
subjectPattern: ^[A-Z].*$
# If `subjectPattern` is configured, you can use this property to override
# the default error message that is shown when the pattern doesn't match.
# The variables `subject` and `title` can be used within the message.
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}" doesn't match the configured pattern.
Please ensure that the subject doesn't start with a lowercase character.
4 changes: 1 addition & 3 deletions .github/workflows/turborepo-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,9 @@ jobs:
target: "aarch64-apple-darwin"
container-options: "--rm"
- host: ubuntu-latest
container: ubuntu:xenial
container-options: "--platform=linux/amd64 --rm"
container-setup: "apt-get update && apt-get install -y curl musl-tools sudo unzip"
target: "x86_64-unknown-linux-musl"
setup: "apt-get install -y build-essential clang-5.0 lldb-5.0 llvm-5.0-dev libclang-5.0-dev"
setup: "sudo apt-get update && sudo apt-get install -y build-essential clang lldb llvm libclang-dev curl musl-tools sudo unzip"
- host: ubuntu-latest
container-options: "--rm"
target: "aarch64-unknown-linux-musl"
Expand Down
19 changes: 13 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion crates/turborepo-lib/src/cli/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use turborepo_telemetry::events::command::CommandEventBuilder;
use turborepo_ui::{color, BOLD, GREY};

use crate::{
commands::{bin, generate, ls, prune, run::get_signal, CommandBase},
commands::{bin, generate, link, ls, prune, run::get_signal, CommandBase},
daemon::DaemonError,
query,
rewrite_json::RewriteError,
Expand Down Expand Up @@ -45,6 +45,8 @@ pub enum Error {
#[diagnostic(transparent)]
Ls(#[from] ls::Error),
#[error(transparent)]
Link(#[from] link::Error),
#[error(transparent)]
#[diagnostic(transparent)]
Prune(#[from] prune::Error),
#[error(transparent)]
Expand Down
106 changes: 102 additions & 4 deletions crates/turborepo-lib/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,13 @@ pub enum Command {
#[clap(long)]
no_gitignore: bool,

/// The scope, i.e. Vercel team, to which you are linking
#[clap(long)]
scope: Option<String>,

/// Answer yes to all prompts (default false)
#[clap(long, short)]
yes: bool,
/// Specify what should be linked (default "remote cache")
#[clap(long, value_enum, default_value_t = LinkTarget::RemoteCache)]
target: LinkTarget,
Expand Down Expand Up @@ -1299,23 +1306,30 @@ pub async fn run(
}
Command::Link {
no_gitignore,
scope,
yes,
target,
} => {
CommandEventBuilder::new("link")
.with_parent(&root_telemetry)
.track_call();

if cli_args.team.is_some() {
warn!("team flag does not set the scope for linking. Use --scope instead.");
}

if cli_args.test_run {
println!("Link test run successful");
return Ok(0);
}

let modify_gitignore = !*no_gitignore;
let to = *target;
let yes = *yes;
let scope = scope.clone();
let mut base = CommandBase::new(cli_args, repo_root, version, color_config);

if let Err(err) = link::link(&mut base, modify_gitignore, to).await {
error!("error: {}", err.to_string())
}
link::link(&mut base, scope, modify_gitignore, yes, to).await?;

Ok(0)
}
Expand Down Expand Up @@ -1469,7 +1483,7 @@ mod test {
use itertools::Itertools;
use pretty_assertions::assert_eq;

use crate::cli::{ExecutionArgs, RunArgs};
use crate::cli::{ExecutionArgs, LinkTarget, RunArgs};

struct CommandTestCase {
command: &'static str,
Expand Down Expand Up @@ -2300,6 +2314,90 @@ mod test {
.test();
}

#[test]
fn test_parse_link() {
assert_eq!(
Args::try_parse_from(["turbo", "link"]).unwrap(),
Args {
command: Some(Command::Link {
no_gitignore: false,
scope: None,
yes: false,
target: LinkTarget::RemoteCache,
}),
..Args::default()
}
);

CommandTestCase {
command: "link",
command_args: vec![],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
no_gitignore: false,
scope: None,
yes: false,
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();

CommandTestCase {
command: "link",
command_args: vec![vec!["--yes"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
yes: true,
no_gitignore: false,
scope: None,
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();

CommandTestCase {
command: "link",
command_args: vec![vec!["--scope", "foo"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
yes: false,
no_gitignore: false,
scope: Some("foo".to_string()),
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();

CommandTestCase {
command: "link",
command_args: vec![vec!["--no-gitignore"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
yes: false,
no_gitignore: true,
scope: None,
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();
}

#[test]
fn test_parse_login() {
assert_eq!(
Expand Down
20 changes: 16 additions & 4 deletions crates/turborepo-lib/src/commands/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ pub(crate) async fn verify_caching_enabled<'a>(

pub async fn link(
base: &mut CommandBase,
scope: Option<String>,
modify_gitignore: bool,
yes: bool,
target: LinkTarget,
) -> Result<(), Error> {
let homedir_path = home_dir().ok_or_else(|| Error::HomeDirectoryNotFound)?;
Expand All @@ -183,7 +185,7 @@ pub async fn link(
REMOTE_CACHING_URL
);

if !should_link_remote_cache(base, &repo_root_with_tilde)? {
if !yes && !should_link_remote_cache(base, &repo_root_with_tilde)? {
return Err(Error::NotLinking);
}

Expand All @@ -203,7 +205,17 @@ pub async fn link(
.await
.map_err(Error::TeamsRequest)?;

let selected_team = select_team(base, &teams_response.teams)?;
let selected_team = if let Some(team_slug) = scope {
SelectedTeam::Team(
teams_response
.teams
.iter()
.find(|team| team.slug == team_slug)
.ok_or_else(|| Error::TeamNotFound(team_slug.to_string()))?,
)
} else {
select_team(base, &teams_response.teams)?
};

let team_id = match selected_team {
SelectedTeam::User => user_response.user.id.as_str(),
Expand Down Expand Up @@ -632,7 +644,7 @@ mod test {
)
.unwrap();

link::link(&mut base, false, LinkTarget::RemoteCache)
link::link(&mut base, None, false, false, LinkTarget::RemoteCache)
.await
.unwrap();

Expand Down Expand Up @@ -707,7 +719,7 @@ mod test {
)
.unwrap();

link::link(&mut base, false, LinkTarget::Spaces)
link::link(&mut base, None, false, false, LinkTarget::Spaces)
.await
.unwrap();

Expand Down
9 changes: 8 additions & 1 deletion crates/turborepo-lib/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,14 @@ impl Diagnostic for RemoteCacheDiagnostic {
return;
};
stopped.await.unwrap();
let link_res = link(&mut base, false, crate::cli::LinkTarget::RemoteCache).await;
let link_res = link(
&mut base,
None,
false,
false,
crate::cli::LinkTarget::RemoteCache,
)
.await;
resume.send(()).unwrap();
link_res
};
Expand Down
13 changes: 4 additions & 9 deletions docs/pack-docs/incremental-computation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,23 @@ description: Learn about the innovative architecture that powers Turbopack's spe

import { ThemeAwareImage } from '#/components/theme-aware-image';

{/*
The excalidraw diagrams are available here:
https://excalidraw.com/#json=NJtM9yXvteQdPLBco0InQ,K5zND2XpqXCHUe_VJj4roA
*/}

Turbopack uses an automatic demand-driven incremental computation architecture to provide [React Fast Refresh](https://nextjs.org/docs/architecture/fast-refresh) with massive Next.js and React applications in *tens of milliseconds*.
Turbopack uses an automatic demand-driven incremental computation architecture to provide [React Fast Refresh](https://nextjs.org/docs/architecture/fast-refresh) with massive Next.js and React applications.

This architecture uses caching to remember what values functions were called with and what values they returned. Incremental builds scale by the size of your local changes, not the size of your application.

<ThemeAwareImage
className="flex justify-center"
light={{
alt: 'A formula with big-o notation showing a change in time spent from "your entire application" to "your changes"',
src: '/images/docs/pack/big-o-changes-equation-light.svg',
src: '/images/docs/pack/big-o-changes-equation-light.png',
props: {
width: 500,
height: 24,
},
}}
dark={{
alt: 'A formula with big-o notation showing a change in time spent from "your entire application" to "your changes"',
src: '/images/docs/pack/big-o-changes-equation-dark.svg',
src: '/images/docs/pack/big-o-changes-equation-dark.png',f
props: {
width: 500,
height: 24,
Expand Down Expand Up @@ -74,7 +69,7 @@ To facilitate automatic caching and dependency tracking, Turbopack introduces a
}}
/>

By not marking cells as dependencies until they are read, Turbopack achieves finer-grained caching than [a traditional top-down memoization approach](https://en.wikipedia.org/wiki/Memoization) would provide. For example, an argument might be an object or mapping of *many* value cells. Instead of needing to recompute our tracked function when *any part of* the object or mapping changes, it only needs to recompute the tracked function when a cell that *it has actually read* changes.
By not marking cells as dependencies until they are read, Turbopack achieves finer-grained caching than [a traditional top-down memoization approach](https://en.wikipedia.org/wiki/Memoization) would provide. For example, an argument might be an object or mapping of _many_ value cells. Instead of needing to recompute our tracked function when _any part of_ the object or mapping changes, it only needs to recompute the tracked function when a cell that _it has actually read_ changes.

Value cells represent nearly everything inside of Turbopack, such as a file on disk, an abstract syntax tree (AST), metadata about imports and exports of modules, or clustering information used for chunking and bundling.

Expand Down
10 changes: 9 additions & 1 deletion docs/repo-docs/reference/link.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ The selected owner (either a user or an organization) will be able to share [cac

Specifies the URL of your Remote Cache provider.

### `--yes`

Answer yes to all prompts

### `--scope <scope>`

The scope, i.e. Vercel team, to which you are linking

```bash title="Terminal"
turbo link --api https://acme.com
```
```
Loading

0 comments on commit 1eebd2c

Please sign in to comment.