Skip to content

Commit

Permalink
Merge pull request #282 from github/add-python
Browse files Browse the repository at this point in the history
Add Python
  • Loading branch information
BekaValentine authored Jan 29, 2024
2 parents 8e99165 + cd9f3eb commit c16b8cf
Show file tree
Hide file tree
Showing 51 changed files with 3,197 additions and 2 deletions.
3 changes: 3 additions & 0 deletions languages/tree-sitter-stack-graphs-python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.html
/Cargo.lock
/target
6 changes: 6 additions & 0 deletions languages/tree-sitter-stack-graphs-python/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog for tree-sitter-stack-graphs-python

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
38 changes: 38 additions & 0 deletions languages/tree-sitter-stack-graphs-python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "tree-sitter-stack-graphs-python"
version = "0.1.0"
description = "Stack graphs definition for Python using tree-sitter-python"
readme = "README.md"
keywords = ["tree-sitter", "stack-graphs", "python"]
authors = [
"GitHub <[email protected]>",
]
license = "MIT OR Apache-2.0"
edition = "2018"

[[bin]]
name = "tree-sitter-stack-graphs-python"
path = "rust/bin.rs"
required-features = ["cli"]

[lib]
path = "rust/lib.rs"
test = false

[[test]]
name = "test"
path = "rust/test.rs"
harness = false

[features]
cli = ["anyhow", "clap", "tree-sitter-stack-graphs/cli"]

[dependencies]
anyhow = { version = "1.0", optional = true }
clap = { version = "4", optional = true, features = ["derive"] }
tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs" }
tree-sitter-python = "=0.20.4"

[dev-dependencies]
anyhow = "1.0"
tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs", features = ["cli"] }
Empty file.
138 changes: 138 additions & 0 deletions languages/tree-sitter-stack-graphs-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# tree-sitter-stack-graphs definition for Python

This project defines tree-sitter-stack-graphs rules for Python using the [tree-sitter-python][] grammar.

[tree-sitter-python]: https://crates.io/crates/tree-sitter-python

- [API documentation](https://docs.rs/tree-sitter-stack-graphs-python/)
- [Release notes](https://github.com/github/stack-graphs/blob/main/languages/tree-sitter-stack-graphs-python/CHANGELOG.md)

## Using the API

To use this library, add the following to your `Cargo.toml`:

```toml
[dependencies]
tree-sitter-stack-graphs-python = "0.1.0"
```

Check out our [documentation](https://docs.rs/tree-sitter-stack-graphs-python/*/) for more details on how to use this library.

## Using the Command-line Program

The command-line program for `tree-sitter-stack-graphs-python` lets you do stack graph based analysis and lookup from the command line.

The CLI can be run as follows:

1. _(Installed)_ Install the CLI using Cargo as follows:

```sh
cargo install --features cli tree-sitter-stack-graphs-python
```

After this, the CLI should be available as `tree-sitter-stack-graphs-python`.

2. _(From source)_ Instead of installing the CLI, it can also be run directly from the crate directory, as a replacement for a `tree-sitter-stack-graphs-python` invocation, as follows:

```sh
cargo run --features cli --
```

The basic CLI workflow for the command-line program is to index source code and issue queries against the resulting database:

1. Index a source folder as follows:

```sh
tree-sitter-stack-graphs-python index SOURCE_DIR
```

_Indexing will skip any files that have already be indexed. To force a re-index, add the `-f` flag._

To check the status if a source folder, run:

```sh
tree-sitter-stack-graphs-python status SOURCE_DIR
```

To clean the database and start with a clean slate, run:

```sh
tree-sitter-stack-graphs-python clean
```

_Pass the `--delete` flag to not just empty the database, but also delete it. This is useful to resolve `unsupported database version` errors that may occur after a version update._

2. Run a query to find the definition(s) for a reference on a given line and column, run:

```sh
tree-sitter-stack-graphs-python query definition SOURCE_PATH:LINE:COLUMN
```

Resulting definitions are printed, including a source line if the source file is available.

Discover all available commands and flags by passing the `-h` flag to the CLI directly, or to any of the subcommands.

## Development

The project is written in Rust, and requires a recent version installed. Rust can be installed and updated using [rustup][].

[rustup]: https://rustup.rs/

The project is organized as follows:

- The stack graph rules are defined in `src/stack-graphs.tsg`.
- Builtins sources and configuration are defined in `src/builtins.it` and `builtins.cfg` respectively.
- Tests are put into the `test` directory.

### Running Tests

Run the tests as follows:

```sh
cargo test
```

The project consists of a library and a CLI. By default, running `cargo` only applies to the library. To run `cargo` commands on the CLI as well, add `--features cli` or `--all-features`.

Run the CLI from source as follows:

```sh
cargo run --features cli -- ARGS
```

Sources are formatted using the standard Rust formatted, which is applied by running:

```sh
cargo fmt
```

### Writing TSG

The stack graph rules are written in [tree-sitter-graph][]. Checkout the [examples][],
which contain self-contained TSG rules for specific language features. A VSCode
[extension][] is available that provides syntax highlighting for TSG files.

[tree-sitter-graph]: https://github.com/tree-sitter/tree-sitter-graph
[examples]: https://github.com/github/stack-graphs/blob/main/tree-sitter-stack-graphs/examples/
[extension]: https://marketplace.visualstudio.com/items?itemName=tree-sitter.tree-sitter-graph

Parse and test a single file by executing the following commands:

```sh
cargo run --features cli -- parse FILES...
cargo run --features cli -- test TESTFILES...
```

Generate a visualization to debug failing tests by passing the `-V` flag:

```sh
cargo run --features cli -- test -V TESTFILES...
```

To generate the visualization regardless of test outcome, execute:

```sh
cargo run --features cli -- test -V --output-mode=always TESTFILES...
```

Go to <https://crates.io/crates/tree-sitter-stack-graphs> for links to examples and documentation.
32 changes: 32 additions & 0 deletions languages/tree-sitter-stack-graphs-python/rust/bin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// -*- coding: utf-8 -*-
// ------------------------------------------------------------------------------------------------
// Copyright © 2023, stack-graphs authors.
// Licensed under either of Apache License, Version 2.0, or MIT license, at your option.
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
// ------------------------------------------------------------------------------------------------

use anyhow::anyhow;
use clap::Parser;
use tree_sitter_stack_graphs::cli::database::default_user_database_path_for_crate;
use tree_sitter_stack_graphs::cli::provided_languages::Subcommands;
use tree_sitter_stack_graphs::NoCancellation;

fn main() -> anyhow::Result<()> {
let lc = match tree_sitter_stack_graphs_python::try_language_configuration(&NoCancellation) {
Ok(lc) => lc,
Err(err) => {
eprintln!("{}", err.display_pretty());
return Err(anyhow!("Language configuration error"));
}
};
let cli = Cli::parse();
let default_db_path = default_user_database_path_for_crate(env!("CARGO_PKG_NAME"))?;
cli.subcommand.run(default_db_path, vec![lc])
}

#[derive(Parser)]
#[clap(about, version)]
pub struct Cli {
#[clap(subcommand)]
subcommand: Subcommands,
}
48 changes: 48 additions & 0 deletions languages/tree-sitter-stack-graphs-python/rust/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// -*- coding: utf-8 -*-
// ------------------------------------------------------------------------------------------------
// Copyright © 2023, stack-graphs authors.
// Licensed under either of Apache License, Version 2.0, or MIT license, at your option.
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
// ------------------------------------------------------------------------------------------------

use tree_sitter_stack_graphs::loader::LanguageConfiguration;
use tree_sitter_stack_graphs::loader::LoadError;
use tree_sitter_stack_graphs::CancellationFlag;

/// The stack graphs tsg source for this language.
pub const STACK_GRAPHS_TSG_PATH: &str = "src/stack-graphs.tsg";
/// The stack graphs tsg source for this language.
pub const STACK_GRAPHS_TSG_SOURCE: &str = include_str!("../src/stack-graphs.tsg");

/// The stack graphs builtins configuration for this language.
pub const STACK_GRAPHS_BUILTINS_CONFIG: &str = include_str!("../src/builtins.cfg");
/// The stack graphs builtins path for this language
pub const STACK_GRAPHS_BUILTINS_PATH: &str = "src/builtins.py";
/// The stack graphs builtins source for this language.
pub const STACK_GRAPHS_BUILTINS_SOURCE: &str = include_str!("../src/builtins.py");

/// The name of the file path global variable.
pub const FILE_PATH_VAR: &str = "FILE_PATH";

pub fn language_configuration(cancellation_flag: &dyn CancellationFlag) -> LanguageConfiguration {
try_language_configuration(cancellation_flag).unwrap_or_else(|err| panic!("{}", err))
}

pub fn try_language_configuration(
cancellation_flag: &dyn CancellationFlag,
) -> Result<LanguageConfiguration, LoadError> {
LanguageConfiguration::from_sources(
tree_sitter_python::language(),
Some(String::from("source.py")),
None,
vec![String::from("py")],
STACK_GRAPHS_TSG_PATH.into(),
STACK_GRAPHS_TSG_SOURCE,
Some((
STACK_GRAPHS_BUILTINS_PATH.into(),
STACK_GRAPHS_BUILTINS_SOURCE,
)),
Some(STACK_GRAPHS_BUILTINS_CONFIG),
cancellation_flag,
)
}
23 changes: 23 additions & 0 deletions languages/tree-sitter-stack-graphs-python/rust/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// -*- coding: utf-8 -*-
// ------------------------------------------------------------------------------------------------
// Copyright © 2023, stack-graphs authors.
// Licensed under either of Apache License, Version 2.0, or MIT license, at your option.
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
// ------------------------------------------------------------------------------------------------

use anyhow::anyhow;
use std::path::PathBuf;
use tree_sitter_stack_graphs::ci::Tester;
use tree_sitter_stack_graphs::NoCancellation;

fn main() -> anyhow::Result<()> {
let lc = match tree_sitter_stack_graphs_python::try_language_configuration(&NoCancellation) {
Ok(lc) => lc,
Err(err) => {
eprintln!("{}", err.display_pretty());
return Err(anyhow!("Language configuration error"));
}
};
let test_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test");
Tester::new(vec![lc], vec![test_path]).run()
}
1 change: 1 addition & 0 deletions languages/tree-sitter-stack-graphs-python/src/builtins.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[globals]
Empty file.
Loading

0 comments on commit c16b8cf

Please sign in to comment.