MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / _mkdirRecursive

Method _mkdirRecursive

packages/kaos/src/ssh.ts:795–848  ·  view source on GitHub ↗
(path: string, existOk: boolean)

Source from the content-addressed store, hash-verified

793 }
794
795 private async _mkdirRecursive(path: string, existOk: boolean): Promise<void> {
796 // Split path into components and create each level.
797 const parts = path.split('/').filter(Boolean);
798 let current = path.startsWith('/') ? '/' : '';
799 const lastIndex = parts.length - 1;
800 for (const [i, part] of parts.entries()) {
801 current = current ? join(current, part) : part;
802
803 const isFinal = i === lastIndex;
804
805 // eslint-disable-next-line no-await-in-loop
806 const exists = await sftpExists(this._sftp, current);
807 if (exists) {
808 // For intermediate components, it's fine (and expected) for the
809 // path to already exist. For the final target, honor `existOk`.
810 if (isFinal && !existOk) {
811 throw new KaosFileExistsError(`${current} already exists`);
812 }
813 // Regardless of whether this is an intermediate or the final
814 // component, an existing path must actually be a directory.
815 // An intermediate non-directory would cause the next `sftpMkdir`
816 // to fail with a confusing error; a final non-directory would
817 // otherwise be silently accepted when `existOk` is true.
818 // eslint-disable-next-line no-await-in-loop
819 const st = await sftpStat(this._sftp, current);
820 if (!st.isDirectory()) {
821 throw new KaosFileExistsError(`${current} already exists but is not a directory`);
822 }
823 continue;
824 }
825 try {
826 // eslint-disable-next-line no-await-in-loop
827 await sftpMkdir(this._sftp, current);
828 } catch (error) {
829 // Race condition: another process may have created it.
830 // eslint-disable-next-line no-await-in-loop
831 const nowExists = await sftpExists(this._sftp, current);
832 if (!nowExists) throw new Error(`Failed to create directory: ${current}`, { cause: error });
833 // A raced path must still be a directory. Another process may have
834 // created a regular file at the same pathname after our exists()
835 // check but before mkdir(), which must remain a hard conflict.
836 // eslint-disable-next-line no-await-in-loop
837 const st = await sftpStat(this._sftp, current);
838 if (!st.isDirectory()) {
839 throw new KaosFileExistsError(`${current} already exists but is not a directory`);
840 }
841 // If the final component lost a race and existOk=false, surface the
842 // conflict to match the non-race path above.
843 if (isFinal && !existOk) {
844 throw new KaosFileExistsError(`${current} already exists`);
845 }
846 }
847 }
848 }
849
850 // ── Process execution ──────────────────────────────────────────────
851

Callers 1

mkdirMethod · 0.95

Calls 3

sftpExistsFunction · 0.85
sftpStatFunction · 0.85
sftpMkdirFunction · 0.85

Tested by

no test coverage detected