[tsp-client] Add support for private repo specs (#7525)

* assume by default the tspconfig is a url

* check if config file exists in local file system

* remove unused fetch function

* get tspconfig.yaml through git to account for private repo links

* changelog
This commit is contained in:
catalinaperalta 2024-01-22 18:34:47 -08:00 коммит произвёл GitHub
Родитель 9868d72723
Коммит adc439e21b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 25 добавлений и 21 удалений

Просмотреть файл

@ -1,5 +1,11 @@
# Release
## Unreleased - 0.4.0
- Added support for initializing a project from a private repository specification.
- Changed `doesFileExist()` function to check local file system.
- Removed `fetch()` function.
## 2023-12-21 - 0.3.0
- Fix TypeSpec compilation issue with module-resolver.

Просмотреть файл

@ -5,7 +5,6 @@ import { TspLocation, compileTsp, discoverMainFile, resolveTspConfigUrl } from "
import { getOptions } from "./options.js";
import { mkdir, writeFile, cp, readFile } from "node:fs/promises";
import { addSpecFiles, checkoutCommit, cloneRepo, getRepoRoot, sparseCheckout } from "./git.js";
import { fetch } from "./network.js";
import { parse as parseYaml } from "yaml";
import { joinPaths, resolvePath } from "@typespec/compiler";
import { formatAdditionalDirectories, getAdditionalDirectoryName } from "./utils.js";
@ -29,10 +28,18 @@ async function sdkInit(
}): Promise<string> {
if (isUrl) {
// URL scenario
const repoRoot = await getRepoRoot(outputDir);
const resolvedConfigUrl = resolveTspConfigUrl(config);
Logger.debug(`Resolved config url: ${resolvedConfigUrl.resolvedUrl}`)
const tspConfig = await fetch(resolvedConfigUrl.resolvedUrl);
const configYaml = parseYaml(tspConfig);
const cloneDir = joinPaths(repoRoot, "..", "sparse-spec");
await mkdir(cloneDir, { recursive: true });
Logger.debug(`Created temporary sparse-checkout directory ${cloneDir}`);
Logger.debug(`Cloning repo to ${cloneDir}`);
await cloneRepo(outputDir, cloneDir, `https://github.com/${resolvedConfigUrl.repo}.git`);
await sparseCheckout(cloneDir);
const tspConfigPath = joinPaths(resolvedConfigUrl.path, "tspconfig.yaml");
await addSpecFiles(cloneDir, tspConfigPath)
await checkoutCommit(cloneDir, resolvedConfigUrl.commit);
const configYaml = parseYaml(joinPaths(cloneDir, tspConfigPath));
const serviceDir = configYaml?.parameters?.["service-dir"]?.default;
if (!serviceDir) {
throw new Error(`Parameter service-dir is not defined correctly in tspconfig.yaml. Please refer to https://github.com/Azure/azure-rest-api-specs/blob/main/specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml for the right schema.`)
@ -48,6 +55,8 @@ async function sdkInit(
await writeFile(
joinPaths(newPackageDir, "tsp-location.yaml"),
`directory: ${resolvedConfigUrl.path}\ncommit: ${resolvedConfigUrl.commit}\nrepo: ${resolvedConfigUrl.repo}\nadditionalDirectories:${additionalDirOutput}\n`);
Logger.debug(`Removing sparse-checkout directory ${cloneDir}`);
await removeDirectory(cloneDir);
return newPackageDir;
} else {
// Local directory scenario

Просмотреть файл

@ -1,14 +1,4 @@
import { createDefaultHttpClient, createPipelineRequest } from "@azure/core-rest-pipeline";
const httpClient = createDefaultHttpClient();
export async function fetch(url: string, method: "GET" | "HEAD" = "GET"): Promise<string> {
const result = await httpClient.sendRequest(createPipelineRequest({ url, method }));
if (result.status !== 200) {
throw new Error(`failed to fetch ${url}: ${result.status}`);
}
return String(result.bodyAsText);
}
import { stat } from "fs/promises";
export function isValidUrl(url: string) {
try {
@ -19,8 +9,7 @@ export function isValidUrl(url: string) {
}
}
export function doesFileExist(url: string): Promise<boolean> {
return fetch(url, "HEAD")
.then(() => true)
.catch(() => false);
// Checks if a file exists locally
export function doesFileExist(path: string): Promise<boolean> {
return stat(path).then(() => true).catch(() => false);
}

Просмотреть файл

@ -85,7 +85,7 @@ export async function getOptions(): Promise<Options> {
process.exit(1);
}
let isUrl = false;
let isUrl = true;
if (positionals[0] === "init") {
if (!values["tsp-config"]) {
Logger.error("tspConfig is required");
@ -93,7 +93,7 @@ export async function getOptions(): Promise<Options> {
process.exit(1);
}
if (await doesFileExist(values["tsp-config"])) {
isUrl = true;
isUrl = false;
}
if (!isUrl) {
if (!values.commit || !values.repo) {