Skip to content

Commit 379cc2b

Browse files
fix(core/path): remove suffix in basename only once (#9165)
* fix(core/path): remove suffix in `basename` only once closes #9064 * Update tooling/api/src/path.ts * remove extra assert --------- Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
1 parent ea0242d commit 379cc2b

3 files changed

Lines changed: 62 additions & 21 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'tauri': 'patch:bug'
3+
'@tauri-apps/api': patch:bug
4+
---
5+
6+
Fix `basename(path, 'ext')` JS API when removing all occurances of `ext` where it should only remove the last one.

core/tauri/src/path/plugin.rs

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,17 @@ pub fn extname(path: String) -> Result<String> {
179179
}
180180

181181
#[command(root = "crate")]
182-
pub fn basename(path: String, ext: Option<String>) -> Result<String> {
183-
match Path::new(&path)
184-
.file_name()
185-
.and_then(std::ffi::OsStr::to_str)
186-
{
187-
Some(p) => Ok(if let Some(ext) = ext {
188-
p.replace(ext.as_str(), "")
189-
} else {
190-
p.to_string()
191-
}),
182+
pub fn basename(path: &str, ext: Option<&str>) -> Result<String> {
183+
let file_name = Path::new(path).file_name().map(|f| f.to_string_lossy());
184+
match file_name {
185+
Some(p) => {
186+
let maybe_stripped = if let Some(ext) = ext {
187+
p.strip_suffix(ext).unwrap_or(&p).to_string()
188+
} else {
189+
p.to_string()
190+
};
191+
Ok(maybe_stripped)
192+
}
192193
None => Err(Error::NoBasename),
193194
}
194195
}
@@ -245,3 +246,40 @@ pub(crate) fn init<R: Runtime>() -> TauriPlugin<R> {
245246
})
246247
.build()
247248
}
249+
250+
#[cfg(test)]
251+
mod tests {
252+
253+
#[test]
254+
fn basename() {
255+
let path = "/path/to/some-json-file.json";
256+
assert_eq!(
257+
super::basename(path, Some(".json")).unwrap(),
258+
"some-json-file"
259+
);
260+
261+
let path = "/path/to/some-json-file.json";
262+
assert_eq!(
263+
super::basename(path, Some("json")).unwrap(),
264+
"some-json-file."
265+
);
266+
267+
let path = "/path/to/some-json-file.html.json";
268+
assert_eq!(
269+
super::basename(path, Some(".json")).unwrap(),
270+
"some-json-file.html"
271+
);
272+
273+
let path = "/path/to/some-json-file.json.json";
274+
assert_eq!(
275+
super::basename(path, Some(".json")).unwrap(),
276+
"some-json-file.json"
277+
);
278+
279+
let path = "/path/to/some-json-file.json.html";
280+
assert_eq!(
281+
super::basename(path, Some(".json")).unwrap(),
282+
"some-json-file.json.html"
283+
);
284+
}
285+
}

tooling/api/src/path.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,9 @@ async function join(...paths: string[]): Promise<string> {
609609
* Returns the directory name of a `path`. Trailing directory separators are ignored.
610610
* @example
611611
* ```typescript
612-
* import { dirname, appDataDir } from '@tauri-apps/api/path';
613-
* const appDataDirPath = await appDataDir();
614-
* const dir = await dirname(appDataDirPath);
612+
* import { dirname } from '@tauri-apps/api/path';
613+
* const dir = await dirname('/path/to/somedir/');
614+
* assert(dir === 'somedir');
615615
* ```
616616
*
617617
* @since 1.0.0
@@ -624,10 +624,9 @@ async function dirname(path: string): Promise<string> {
624624
* Returns the extension of the `path`.
625625
* @example
626626
* ```typescript
627-
* import { extname, resolveResource } from '@tauri-apps/api/path';
628-
* const resourcePath = await resolveResource('app.conf');
629-
* const ext = await extname(resourcePath);
630-
* assert(ext === 'conf');
627+
* import { extname } from '@tauri-apps/api/path';
628+
* const ext = await extname('/path/to/file.html');
629+
* assert(ext === 'html');
631630
* ```
632631
*
633632
* @since 1.0.0
@@ -640,12 +639,10 @@ async function extname(path: string): Promise<string> {
640639
* Returns the last portion of a `path`. Trailing directory separators are ignored.
641640
* @example
642641
* ```typescript
643-
* import { basename, resolveResource } from '@tauri-apps/api/path';
644-
* const resourcePath = await resolveResource('app.conf');
645-
* const base = await basename(resourcePath);
642+
* import { basename } from '@tauri-apps/api/path';
643+
* const base = await basename('path/to/app.conf');
646644
* assert(base === 'app.conf');
647645
* ```
648-
*
649646
* @param ext An optional file extension to be removed from the returned path.
650647
*
651648
* @since 1.0.0

0 commit comments

Comments
 (0)