On this page:
source-group?
empty-source-group
source-group-union
source-group-union-all
single-source-group
directory-source-group
package-source-group
git-repository-source-group
source-group-resolve
9.2

4.2 Source Groups🔗ℹ

 (require resyntax/grimoire/source-group) package: resyntax

A source group is a specification of what source code Resyntax should analyze, along with which lines within those sources Resyntax is allowed to suggest changes to. Source groups come in four kinds, each corresponding to one of the target flags accepted by the command-line interface:

  • Single-source groups, constructed with single-source-group, containing one file restricted to a given set of lines. The --file flag constructs these, with all lines allowed. Note that the CLI doesn’t include a way to specify which lines should be modified at this time, despite the fact that the single-source-group constructor accepts that information. The only difference between a single-source group and a file-source? value is that the source group may contain information about which lines to analyze.

  • Directory groups, constructed with directory-source-group, containing every source file within a directory, including files in subdirectories. The --directory flag constructs these.

  • Package groups, constructed with package-source-group, containing every file of a locally installed Racket package. The --package flag constructs these. This does not refer to remote packages on the package catalog; Resyntax cannot analyze a package unless it’s currently installed.

  • Git repository groups, constructed with git-repository-source-group, containing the files of a local Git repository that have changed relative to some base reference. The --local-git-repository flag constructs these. As with package groups, Resyntax can only analyze Git repositories that have already been cloned onto the current machine. Git repository groups are the only source groups that take advantage of Resyntax’s ability to restrict which lines are analyzed — only the lines actually touched in the diff against the specified base reference, plus a small margin of surrounding context lines (see git-repository-source-group), will be included.

Additionally, any number of source groups can be combined into a single group with source-group-union. This is how the command-line interface handles multiple target flags: each flag becomes a source group, and all of them are unioned into one group describing the entire analysis.

A source group is only a description: it must be resolved with source-group-resolve to produce the actual source code values that Resyntax analyzes. Resolution is when the filesystem, the local package system, or the local Git repository is actually consulted. Resolution does not consult external networked sources; only local information is considered. After resolution, Resyntax "locks in" the set of sources it’s editing. If, after this point, new files are added to a directory group (or a similar addition is made to the files described by a different kind of source group) they will be ignored by Resyntax. However, edits to the contents of files that were included in the source set, but which Resyntax has not started to analyze, will be perceived by Resyntax. This is because source group resolution does not read the contents of each source file into memory yet. That occurs at a later step, on a per-file basis, as Resyntax is analyzing each file.

procedure

(source-group? v)  boolean?

  v : any/c
A predicate that recognizes source groups of any kind.

The empty source group, which specifies no sources at all. Resolving it produces an empty hash, and unioning it with any other source group has no effect — it is the identity element of source-group-union.

procedure

(source-group-union group ...)  source-group?

  group : source-group?
Combines each group into a single source group specifying all of their sources. Given no groups, the result is empty-source-group.

Unioning is commutative, associative, and idempotent, and empty-source-group is its identity element: source groups form a commutative monoid under union (in fact, a bounded join-semilattice, thanks to idempotence). These laws hold up to equal?:

This operation is a convenience wrapper around source-group-union-all.

procedure

(source-group-union-all groups)  source-group?

  groups : (sequence/c source-group?)
Combines every source group in groups into a single source group, exactly as source-group-union does for its arguments, but accepting the groups as a single sequence of any kind. An empty sequence produces empty-source-group. This is how the command-line interface combines its collection of target flags into one group.

procedure

(single-source-group path lines)  source-group?

  path : path-string?
  lines : immutable-range-set?
Constructs a source group containing only the file at path, with suggestions restricted to the line numbers in lines. The path is normalized with simple-form-path upon construction.

procedure

(directory-source-group path)  source-group?

  path : path-string?
Constructs a source group containing every file within the directory at path, including files within subdirectories, with all lines of each file eligible for suggestions. The path is normalized with simple-form-path upon construction.

procedure

(package-source-group package-name)  source-group?

  package-name : string?
Constructs a source group containing every file of the installed Racket package named package-name, with all lines of each file eligible for suggestions. The package’s installation directory is located with pkg-directory during resolution, and resolution raises a user error if no such package is installed.

procedure

(git-repository-source-group repository-path    
  base-ref)  source-group?
  repository-path : path-string?
  base-ref : string?
Constructs a source group containing the files of the Git repository at repository-path that have changed relative to base-ref, as determined by git diff during resolution. The repository path is normalized with simple-form-path upon construction.

Only the modified lines of each changed file are eligible for suggestions, expanded to include the three lines before and after each modified region. The three-line margin matches what GitHub allows in pull request reviews: comments may only be placed on modified lines and the three lines of context surrounding them, so suggestions within the margin can still be posted as review comments. More generally, a three-line margin is the default amount of extra context that many Unix tools choose when interoperating via the unified diff format, particularly the diff tool.

Resolves group into concrete files, returning a hash whose keys are file-source? values and whose values are the line numbers eligible for suggestions in each file. When the same file is included multiple times by a unioned group, its line sets are unioned.

Resolution discards all files that don’t have the .rkt extension. This is where the command-line interface’s restriction to .rkt files is implemented.