Skip to content

Commit aeb44cc

Browse files
committed
Merge branch 'main' into cran-2.3.4
Brings the 2.3.4 hotfix to `main` once this branch is merged with a merge commit, which makes the `v2.3.4` tag reachable from `main`. Conflicts resolved: - `.github/`, `.Rbuildignore`, `.gitignore`, `DESCRIPTION` and `tests/testthat/test-other.R` from `main`. `main` keeps its development version, and its `test-other.R` fixture lives in a helper and already uses `names =` in `structure()`. - Rd files from `main`, which has the newer roxygen2. `man/pipe.Rd` merges cleanly and keeps `\usage` from the hotfix. - `CITATION.cff` from the hotfix, which names the released 2.3.4. - `NEWS.md` with `main`'s development sections on top, then the 2.3.4 section as in the tag message, then 2.3.3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019iwyUfQ6pFAhL3jUUocHFm
2 parents fe3538b + b4a4d33 commit aeb44cc

742 files changed

Lines changed: 54278 additions & 22830 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.Rbuildignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
^scripts$
6868
^\.claude$
6969
^\.build$
70+
^lifecycle$
71+
^jarl\.toml$
72+
^touchstone$
7073
^man/dot-igraph.progress\.Rd$
7174
^man/dot-igraph.status\.Rd$
7275
^man/dot-extract_constructor_and_modifiers\.Rd$

‎.github/workflows/custom/after-install/action.yml‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@ runs:
1717
# automatically via tests/testthat/helper-migrations.R.
1818
- name: Regenerate argument-migration blocks and check for drift
1919
run: |
20-
# Release branches cut from a tag that predates the registry have no generator.
21-
if [ ! -f tools/generate-migrations.R ]; then
22-
echo "tools/generate-migrations.R not found, nothing to check."
23-
exit 0
24-
fi
2520
Rscript tools/generate-migrations.R
2621
if ! git diff --exit-code -- R; then
2722
echo "::error::Generated ARG_HANDLE blocks are out of sync with the registry (tools/migrations/)."

‎.github/workflows/touchstone-comment.yaml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
name: Continuous Benchmarks (Comment)
22

33
concurrency:
4-
group: ${{ github.workflow }}-${{ github.head_ref }}
4+
# `github.head_ref` is empty for `workflow_run` events,
5+
# which put every PR into one shared group,
6+
# so a comment job for one PR cancelled the one for another.
7+
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
58
cancel-in-progress: true
69

710
on:

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ cran
3131
/tests/testthat/_problems/
3232
/.build/
3333
.ccache/
34+
lifecycle

‎AGENTS.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ pak::pak(dependencies = "Config/Needs/build")
7878
- Document all arguments and return values
7979
- Document internal functions using devtag (work in progress)
8080
- Link to C documentation using `@cdocs` tag: `#' @cdocs igraph_function_name`
81+
- Write "ID"/"IDs" (not "id"/"ids") when referring to vertex/edge IDs in documentation *prose*. Lowercase stays only where the token is code: argument names, runnable `@examples`, and spans in `` `...` `` or `\code{}`. Run `Rscript tools/check-id-casing.R` to find violations in roxygen prose.
8182
- Always run `devtools::document()` after updating documentation
8283

8384
### Naming Conventions
8485

8586
- Use `max` for maximal (graph theory term: a vertex is maximal if no other vertex dominates it) and `largest` for maximum (the biggest value in a set)
87+
- Use `make_xxx()` for functions creating graphs in a deterministic way, and `sample_xxx()` for functions sampling graphs from some ensemble
8688

8789
### New functions
8890

@@ -94,7 +96,7 @@ All new functions must include:
9496
- A concept so that it exists in the pkgdown reference index
9597
- An "experimental" badge via `r lifecycle::badge("experimental")`
9698
- All arguments in `snake_case`, with documentation and suitable defaults
97-
- An ellipsis guarded with `check_dots_empty()` separating mandatory and optional arguments
99+
- An ellipsis guarded with `check_dots_empty()` separating the head (required and defining arguments) from keyword-only options, following the zoning rules in [CONTRIBUTING.md](CONTRIBUTING.md#argument-order-and-the-ellipsis)
98100
- Argument validation using built-in `check_*()` functions or `igraph_arg_match()`
99101

100102
**For callback functions:**

‎CONTRIBUTING.md‎

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,93 @@ style to the code (see also the [lintr package](https://lintr.r-lib.org/)).
141141
Look at the style (indentation, braces, etc.) of some recently committed bigger
142142
change, and try to mimic that.
143143

144+
### Argument Order and the Ellipsis
145+
146+
Every exported function separates its arguments into two zones
147+
with an ellipsis (`...`):
148+
arguments *before* the ellipsis may be passed by position,
149+
arguments *after* it are keyword-only.
150+
This lets us add, reorder, and rename keyword-only arguments
151+
in later releases without breaking user code,
152+
and it keeps user code readable
153+
because rarely-used options must be spelled out.
154+
155+
Which arguments go before the ellipsis (the "head")?
156+
157+
1. **All required arguments** (arguments without a default),
158+
with the graph or other primary data first.
159+
This holds even when a function has three or more required arguments:
160+
a required argument after `...` could still only be passed by name,
161+
which hides it from the signature-reading eye
162+
and produces worse error messages when it is forgotten.
163+
2. **Defining optional arguments** may follow —
164+
but only when they answer *what* is computed rather than *how*:
165+
- the vertices, edges, or other objects the function operates on,
166+
such as `v` in `degree()` or `nodes` in `ego()`;
167+
- the parameters of a model or generator,
168+
such as `power` and `m` in `sample_pa()`;
169+
- an enum that selects the essential variant of the operation,
170+
such as `type` in `as_adjacency_matrix()`.
171+
172+
As a rule of thumb, the head should not exceed three or four arguments;
173+
when in doubt, put an argument after the ellipsis.
174+
The head must never be empty, though:
175+
at least the function's primary argument stays positional,
176+
and a signature whose arguments *all* sit behind the ellipsis
177+
is a sign that the function should not carry an ellipsis at all.
178+
179+
Everything else goes after the ellipsis (the "tail"),
180+
roughly in this order:
181+
182+
1. interpretation modifiers, such as `mode`, `directed`, `weights`, `loops`;
183+
2. output shape and format, such as `normalized`, `names`, `sparse`;
184+
3. algorithm selection and tuning, such as `algorithm`, `options`, callbacks;
185+
4. deprecated arguments, always last.
186+
187+
This follows the tidyverse design guide
188+
([required args before `...`, optional after](https://design.tidyverse.org/dots-after-required.html),
189+
[important args first](https://design.tidyverse.org/important-args-first.html),
190+
[required args have no defaults](https://design.tidyverse.org/required-no-defaults.html))
191+
with one deliberate deviation:
192+
the tidyverse places `...` directly after the *required* arguments,
193+
whereas we allow a small number of *defining optional* arguments
194+
to stay ahead of it (rule 2 above).
195+
igraph's API predates these conventions by two decades,
196+
and idiomatic calls like `degree(g, 1:3)` or `sample_pa(100, 1.5)`
197+
are pervasive in scripts, books, and teaching material.
198+
Deprecating the idiomatic form of a function
199+
would generate warning noise without a safety benefit;
200+
the value of keyword-only arguments lies in the long tail of options,
201+
not in the one or two arguments everyone knows by heart.
202+
203+
Defaults on either side of the ellipsis
204+
must be *constant expressions* --
205+
literals, `NULL`/`TRUE`/`FALSE`/`NA`,
206+
`c()` or `list()` of constants,
207+
or the `deprecated()` sentinel.
208+
A complex default -- an option lookup, `V(graph)`,
209+
a reference to another argument, a random draw --
210+
is evaluated lazily at an unpredictable time
211+
and hides the real behavior from the signature:
212+
declare the formal as `NULL`
213+
and resolve it in the body
214+
after all arguments are available.
215+
The migration generator enforces this rule for migrated signatures.
216+
217+
New functions follow the same zoning,
218+
with `rlang::check_dots_empty()` guarding the ellipsis
219+
(no migration machinery needed);
220+
document the ellipsis with `@inheritParams rlang::args_dots_empty`.
221+
222+
For existing functions, the signature change is *migrated*:
223+
a generated block recovers legacy positional or abbreviated calls
224+
and emits a single soft deprecation,
225+
so old code keeps working during a transition period.
226+
See [Argument-migration blocks](tools/README.md#argument-migration-blocks)
227+
for the mechanics,
228+
and declare migrations in a per-topic registry file
229+
under `tools/migrations/`.
230+
144231
### Documentation
145232

146233
- Install roxygen2 but also [igraph.r2cdocs](https://github.com/igraph/igraph.r2cdocs).
@@ -156,6 +243,15 @@ igraph` to update the `.Rd` files.
156243

157244
- Links to C docs are added automatically thanks to the igraph.r2cdocs's roclet.
158245

246+
- Write "ID"/"IDs" (not "id"/"ids") when referring to vertex or edge IDs in
247+
documentation prose. Lowercase stays only where the token is code: argument
248+
names, runnable `@examples`, and spans wrapped in `` `...` `` or `\code{}`. You
249+
can check roxygen prose for stray lowercase forms with:
250+
251+
```sh
252+
Rscript tools/check-id-casing.R
253+
```
254+
159255
### Maintaining igraph.r2cdocs
160256

161257
To update the data (when the C docs index has changed after a release) in https://github.com/igraph/igraph.r2cdocs/, run the script that is `data-raw`, commit the csv file and push.

‎DESCRIPTION‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: igraph
22
Title: Network Analysis and Visualization
3-
Version: 2.3.4
3+
Version: 2.3.3.9042
44
Authors@R: c(
55
person("Gábor", "Csárdi", , "csardi.gabor@gmail.com", role = "aut",
66
comment = c(ORCID = "0000-0001-7098-9676")),
@@ -35,7 +35,7 @@ URL: https://r.igraph.org/, https://igraph.org/,
3535
BugReports: https://github.com/igraph/rigraph/issues
3636
Depends:
3737
methods,
38-
R (>= 3.5.0)
38+
R (>= 4.0.0)
3939
Imports:
4040
cli,
4141
graphics,
@@ -60,7 +60,7 @@ Suggests:
6060
scales,
6161
stats4,
6262
tcltk,
63-
testthat,
63+
testthat (>= 3.3.0),
6464
vdiffr,
6565
withr
6666
Enhances:
@@ -93,4 +93,4 @@ Encoding: UTF-8
9393
Roxygen: list(markdown = TRUE, roclets = c("collate", "namespace",
9494
"igraph.r2cdocs::docs_rd", "devtag::dev_roclet"))
9595
SystemRequirements: libxml2 (optional), glpk (>= 4.57, optional)
96-
Config/roxygen2/version: 8.1.0.9000
96+
Config/roxygen2/version: 8.1.1.9000

‎Makefile-cigraph‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ $(RAY2): src/vendor/%: vendor/%
100100

101101
# R files that are generated/copied
102102

103-
RGEN = R/aaa-auto.R src/rinterface.c \
103+
RGEN = .build/r-wrappers.stamp src/rinterface.c \
104104
configure src/config.h.in
105105

106106
# Files generated by stimulus
@@ -121,21 +121,32 @@ src/rinterface.c: \
121121
-t tools/stimulus/types-RC.yaml \
122122
-l RC
123123

124-
R/aaa-auto.R: \
124+
# Stimulus generates a single R/aaa-auto.R blob, which tools/split-aaa-auto.R
125+
# then splits into per-category R/aaa-<cat>.R files driven by
126+
# tools/aaa-categories.yaml. The monolithic blob is written to .build/ so it
127+
# never lands in R/ itself.
128+
.build/r-wrappers.stamp: \
125129
venv \
126130
$(vendored_srcdir)/interfaces/functions.yaml \
127131
$(vendored_srcdir)/interfaces/types.yaml \
128132
tools/stimulus/aaa-auto.R.in \
129133
tools/stimulus/functions-R.yaml \
130-
tools/stimulus/types-RR.yaml
134+
tools/stimulus/types-RR.yaml \
135+
tools/aaa-categories.yaml \
136+
tools/split-aaa-auto.R
137+
mkdir -p .build
131138
$(STIMULUS) \
132139
-f $(vendored_srcdir)/interfaces/functions.yaml \
133140
-f tools/stimulus/functions-R.yaml \
134141
-i tools/stimulus/aaa-auto.R.in \
135-
-o R/aaa-auto.R \
142+
-o .build/aaa-auto.R \
136143
-t $(vendored_srcdir)/interfaces/types.yaml \
137144
-t tools/stimulus/types-RR.yaml \
138145
-l RR
146+
Rscript tools/split-aaa-auto.R .build/aaa-auto.R
147+
touch $@
148+
149+
r_wrappers: .build/r-wrappers.stamp
139150

140151
# This is the list of all object files in the R package,
141152
# we write it to a file to be able to depend on it.
@@ -157,9 +168,9 @@ pre_build: venv patches $(RSRC) \
157168
$(PARSER2)
158169

159170
clean:
160-
rm -rf src/core src/vendor src/include src/config.h.in src/rinterface.c R/aaa-auto.R
171+
rm -rf src/core src/vendor src/include src/config.h.in src/rinterface.c R/aaa-*.R .build
161172
git -C $(top_srcdir) reset --hard
162173

163-
.PHONY: all igraph force clean check check-cran check-rhub check-links install test src/sources.mk
174+
.PHONY: all igraph force clean check check-cran check-rhub check-links install test r_wrappers src/sources.mk
164175

165176
.NOTPARALLEL:

‎NAMESPACE‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ S3method("[",communities)
1313
S3method("[",igraph)
1414
S3method("[",igraph.es)
1515
S3method("[",igraph.vs)
16+
S3method("[",igraphSDF)
1617
S3method("[<-",igraph)
1718
S3method("[<-",igraph.es)
1819
S3method("[<-",igraph.vs)
20+
S3method("[<-",igraphSDF)
1921
S3method("[[",communities)
2022
S3method("[[",igraph)
2123
S3method("[[",igraph.es)
2224
S3method("[[",igraph.vs)
2325
S3method("[[<-",igraph.es)
2426
S3method("[[<-",igraph.vs)
27+
S3method(as.data.frame,igraphSDF)
2528
S3method(as.dendrogram,communities)
29+
S3method(as.dendrogram,igraphHRG)
2630
S3method(as.hclust,communities)
2731
S3method(as.hclust,igraphHRG)
2832
S3method(as.igraph,igraphHRG)
@@ -376,7 +380,6 @@ export(get.adjlist)
376380
export(get.all.shortest.paths)
377381
export(get.data.frame)
378382
export(get.diameter)
379-
export(get.edge)
380383
export(get.edge.attribute)
381384
export(get.edge.ids)
382385
export(get.edgelist)
@@ -610,7 +613,6 @@ export(layout.fruchterman.reingold.grid)
610613
export(layout.gem)
611614
export(layout.graphopt)
612615
export(layout.grid)
613-
export(layout.grid.3d)
614616
export(layout.kamada.kawai)
615617
export(layout.lgl)
616618
export(layout.mds)

0 commit comments

Comments
 (0)