Skip to content

Commit 99a11b0

Browse files
authored
Merge pull request #1090 from pkgxdev/plus-display-names
Allow eg. `pkgx +rust` like pkgx^1 does
2 parents 57ee9ed + f5ae8e6 commit 99a11b0

File tree

5 files changed

+48
-14
lines changed

5 files changed

+48
-14
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ jobs:
107107
- run: pkgx /usr/bin/awk --version
108108
- run: pkgx +yarnpkg.com yarn --version
109109
- run: pkgx +yarnpkg.com -- yarn --version
110+
# coverage for conflict error messages
110111
- run: '! pkgx yarn --version'
112+
# coverage for display-name resolution
113+
- run: pkgx +agg
111114

112115
- name: generate coverage
113116
run: |

crates/cli/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
4141

4242
let cache_dir = config.pantry_dir.parent().unwrap();
4343
std::fs::create_dir_all(cache_dir)?;
44-
let mut conn = Connection::open(cache_dir.join("pantry.db"))?;
44+
let mut conn = Connection::open(cache_dir.join("pantry.2.db"))?;
4545

4646
let spinner = if flags.silent || flags.quiet {
4747
None
@@ -51,7 +51,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
5151
Some(spinner)
5252
};
5353

54-
let did_sync = if sync::should(&config) {
54+
let did_sync = if sync::should(&config)? {
5555
if let Some(spinner) = &spinner {
5656
spinner.set_message("syncing pkg-db…");
5757
}
@@ -263,7 +263,7 @@ impl std::fmt::Display for WhichError {
263263
impl std::error::Error for WhichError {}
264264

265265
async fn which(cmd: &String, conn: &Connection, pkgs: &[PackageReq]) -> Result<String, WhichError> {
266-
let candidates = pantry_db::which(cmd, conn).map_err(WhichError::DbError)?;
266+
let candidates = pantry_db::projects_for_symbol(cmd, conn).map_err(WhichError::DbError)?;
267267
if candidates.len() == 1 {
268268
Ok(candidates[0].clone())
269269
} else if candidates.is_empty() {

crates/lib/src/pantry.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub struct PantryEntry {
1212
pub programs: Vec<String>,
1313
pub companions: Vec<PackageReq>,
1414
pub env: HashMap<String, String>,
15+
pub display_name: Option<String>,
1516
}
1617

1718
impl PantryEntry {
@@ -73,12 +74,15 @@ impl PantryEntry {
7374
HashMap::new()
7475
};
7576

77+
let display_name = entry.display_name;
78+
7679
Ok(Self {
7780
deps,
7881
project,
7982
env,
8083
companions,
8184
programs,
85+
display_name,
8286
})
8387
}
8488
}
@@ -131,6 +135,8 @@ struct RawPantryEntry {
131135
provides: Option<Provides>,
132136
companions: Option<Deps>,
133137
runtime: Option<Runtime>,
138+
#[serde(rename = "display-name")]
139+
display_name: Option<String>,
134140
}
135141

136142
#[derive(Debug)]

crates/lib/src/pantry_db.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ pub fn cache(config: &Config, conn: &mut Connection) -> Result<(), Box<dyn Error
3030
project TEXT,
3131
envline TEXT
3232
);
33+
CREATE TABLE aliases (
34+
project TEXT,
35+
alias TEXT
36+
);
3337
CREATE INDEX idx_project ON provides(project);
3438
CREATE INDEX idx_program ON provides(program);
3539
CREATE INDEX idx_project_dependencies ON dependencies(project);
3640
CREATE INDEX idx_project_companions ON companions(project);
41+
CREATE INDEX idx_alias_project ON aliases(alias);
3742
",
3843
)?;
3944

@@ -53,6 +58,13 @@ pub fn cache(config: &Config, conn: &mut Connection) -> Result<(), Box<dyn Error
5358
)?;
5459
}
5560

61+
if let Some(display_name) = pkg.display_name {
62+
tx.execute(
63+
"INSERT INTO aliases (project, alias) VALUES (?1, ?2);",
64+
params![pkg.project, display_name],
65+
)?;
66+
}
67+
5668
for dep in pkg.deps {
5769
tx.execute(
5870
"INSERT INTO dependencies (project, pkgspec) VALUES (?1, ?2);",
@@ -103,6 +115,24 @@ pub fn which(cmd: &String, conn: &Connection) -> Result<Vec<String>, rusqlite::E
103115
Ok(rv)
104116
}
105117

118+
pub fn projects_for_symbol(
119+
symbol: &String,
120+
conn: &Connection,
121+
) -> Result<Vec<String>, rusqlite::Error> {
122+
let mut stmt = conn.prepare(
123+
"
124+
SELECT project FROM provides WHERE program = ?1
125+
UNION
126+
SELECT project FROM aliases WHERE LOWER(alias) = LOWER(?1);",
127+
)?;
128+
let mut rv = Vec::new();
129+
let mut rows = stmt.query(params![symbol])?;
130+
while let Some(row) = rows.next()? {
131+
rv.push(row.get(0)?);
132+
}
133+
Ok(rv)
134+
}
135+
106136
pub fn runtime_env_for_project(
107137
project: &String,
108138
conn: &Connection,

crates/lib/src/sync.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,14 @@ use tokio_tar::Archive;
88
use tokio_util::compat::FuturesAsyncReadCompatExt;
99

1010
#[allow(clippy::all)]
11-
pub fn should(config: &Config) -> bool {
11+
pub fn should(config: &Config) -> Result<bool, Box<dyn Error>> {
1212
if !config.pantry_dir.join("projects").is_dir() {
13-
true
14-
} else if !config
15-
.pantry_dir
16-
.parent()
17-
.unwrap()
18-
.join("pantry.db")
19-
.is_file()
20-
{
21-
true
13+
Ok(true)
2214
} else {
23-
false
15+
let path = config.pantry_dir.parent().unwrap().join("pantry.2.db");
16+
// the file always exists because we create the connection
17+
// but will be 0 bytes if we need to fill it
18+
Ok(std::fs::metadata(&path)?.len() == 0)
2419
}
2520
}
2621

0 commit comments

Comments
 (0)