Skip to content

Commit

Permalink
Implementation of new GET interpreters, defaults for config R & Pytho…
Browse files Browse the repository at this point in the history
…n sections and filling in of defaults when deploying. Also added new types and new unit tests.
  • Loading branch information
sagerb committed Feb 12, 2025
1 parent 1054486 commit af8681a
Show file tree
Hide file tree
Showing 39 changed files with 1,268 additions and 183 deletions.
4 changes: 3 additions & 1 deletion cmd/publisher/commands/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/posit-dev/publisher/internal/deployment"
"github.com/posit-dev/publisher/internal/events"
"github.com/posit-dev/publisher/internal/initialize"
"github.com/posit-dev/publisher/internal/logging"
"github.com/posit-dev/publisher/internal/publish"
"github.com/posit-dev/publisher/internal/state"
"github.com/posit-dev/publisher/internal/util"
Expand All @@ -28,6 +29,7 @@ type DeployCmd struct {
}

func (cmd *DeployCmd) Run(args *cli_types.CommonArgs, ctx *cli_types.CLIContext) error {
log := logging.New()
absPath, err := cmd.Path.Abs()
if err != nil {
return err
Expand Down Expand Up @@ -58,7 +60,7 @@ func (cmd *DeployCmd) Run(args *cli_types.CommonArgs, ctx *cli_types.CLIContext)
if err != nil {
return err
}
stateStore, err := state.New(absPath, cmd.AccountName, cmd.ConfigName, "", cmd.SaveName, ctx.Accounts, nil, false)
stateStore, err := state.New(absPath, cmd.AccountName, cmd.ConfigName, "", cmd.SaveName, ctx.Accounts, nil, false, nil, nil, log)
if err != nil {
return err
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/publisher/commands/redeploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/posit-dev/publisher/internal/deployment"
"github.com/posit-dev/publisher/internal/events"
"github.com/posit-dev/publisher/internal/initialize"
"github.com/posit-dev/publisher/internal/logging"
"github.com/posit-dev/publisher/internal/publish"
"github.com/posit-dev/publisher/internal/state"
"github.com/posit-dev/publisher/internal/util"
Expand All @@ -27,6 +28,7 @@ type RedeployCmd struct {
}

func (cmd *RedeployCmd) Run(args *cli_types.CommonArgs, ctx *cli_types.CLIContext) error {
log := logging.New()
absPath, err := cmd.Path.Abs()
if err != nil {
return err
Expand All @@ -43,7 +45,7 @@ func (cmd *RedeployCmd) Run(args *cli_types.CommonArgs, ctx *cli_types.CLIContex
if err != nil {
return fmt.Errorf("invalid deployment name '%s': %w", cmd.TargetName, err)
}
stateStore, err := state.New(absPath, "", cmd.ConfigName, cmd.TargetName, "", ctx.Accounts, nil, false)
stateStore, err := state.New(absPath, "", cmd.ConfigName, cmd.TargetName, "", ctx.Accounts, nil, false, nil, nil, log)
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions extensions/vscode/src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Credentials } from "./resources/Credentials";
import { ContentRecords } from "./resources/ContentRecords";
import { Configurations } from "./resources/Configurations";
import { Files } from "./resources/Files";
import { Interpreters } from "./resources/Interpreters";
import { Packages } from "./resources/Packages";
import { Secrets } from "./resources/Secrets";
import { EntryPoints } from "./resources/Entrypoints";
Expand All @@ -15,6 +16,7 @@ class PublishingClientApi {
private client;

configurations: Configurations;
interpreters: Interpreters;
credentials: Credentials;
contentRecords: ContentRecords;
files: Files;
Expand Down Expand Up @@ -52,6 +54,7 @@ class PublishingClientApi {
this.credentials = new Credentials(this.client);
this.contentRecords = new ContentRecords(this.client);
this.files = new Files(this.client);
this.interpreters = new Interpreters(this.client);
this.packages = new Packages(this.client);
this.secrets = new Secrets(this.client);
this.entrypoints = new EntryPoints(this.client);
Expand Down
12 changes: 6 additions & 6 deletions extensions/vscode/src/api/resources/Configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ConfigurationError,
ConfigurationInspectionResult,
} from "../types/configurations";
import { PythonExecutable, RExecutable } from "../../types/shared";

export class Configurations {
private client: AxiosInstance;
Expand Down Expand Up @@ -80,19 +81,18 @@ export class Configurations {
// 500 - internal server error
inspect(
dir: string,
python?: string,
r?: string,
python: PythonExecutable | undefined,
r: RExecutable | undefined,
params?: { entrypoint?: string; recursive?: boolean },
) {
return this.client.post<ConfigurationInspectionResult[]>(
"/inspect",
{
python,
r,
},
{},
{
params: {
dir,
python: python !== undefined ? python.pythonPath : undefined,
r: r !== undefined ? r.rPath : "",
...params,
},
},
Expand Down
9 changes: 5 additions & 4 deletions extensions/vscode/src/api/resources/ContentRecords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ContentRecord,
Environment,
} from "../types/contentRecords";
import { PythonExecutable, RExecutable } from "../../types/shared";

export class ContentRecords {
private client: AxiosInstance;
Expand Down Expand Up @@ -74,17 +75,15 @@ export class ContentRecords {
configName: string,
insecure: boolean,
dir: string,
r: RExecutable | undefined,
python: PythonExecutable | undefined,
secrets?: Record<string, string>,
r?: string,
python?: string,
) {
const data = {
account: accountName,
config: configName,
secrets: secrets,
insecure: insecure,
r: r,
python: python,
};
const encodedTarget = encodeURIComponent(targetName);
return this.client.post<{ localId: string }>(
Expand All @@ -93,6 +92,8 @@ export class ContentRecords {
{
params: {
dir,
r: r !== undefined ? r.rPath : "",
python: python !== undefined ? python.pythonPath : "",
},
},
);
Expand Down
31 changes: 31 additions & 0 deletions extensions/vscode/src/api/resources/Interpreters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) 2025 by Posit Software, PBC.

import { AxiosInstance } from "axios";

import { PythonExecutable, RExecutable } from "../../types/shared";
import { InterpreterDefaults } from "../types/interpreters";

export class Interpreters {
private client: AxiosInstance;

constructor(client: AxiosInstance) {
this.client = client;
}

// Returns:
// 200 - success
// 500 - internal server error
get(
dir: string,
r: RExecutable | undefined,
python: PythonExecutable | undefined,
) {
return this.client.get<InterpreterDefaults>(`/interpreters`, {
params: {
dir,
r: r !== undefined ? r.rPath : "",
python: python !== undefined ? python.pythonPath : "",
},
});
}
}
31 changes: 25 additions & 6 deletions extensions/vscode/src/api/resources/Packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
PythonPackagesResponse,
ScanPythonPackagesResponse,
} from "../types/packages";
import { PythonExecutable, RExecutable } from "../../types/shared";

export class Packages {
private client: AxiosInstance;
Expand Down Expand Up @@ -48,25 +49,43 @@ export class Packages {
// 500 - internal server error
createPythonRequirementsFile(
dir: string,
python?: string,
python: PythonExecutable | undefined,
saveName?: string,
) {
return this.client.post<ScanPythonPackagesResponse>(
"packages/python/scan",
{ python, saveName },
{ params: { dir } },
{
saveName,
},
{
params: {
dir,
python: python !== undefined ? python.pythonPath : undefined,
},
},
);
}

// Returns:
// 200 - success
// 400 - bad request
// 500 - internal server error
createRRequirementsFile(dir: string, saveName?: string, r?: string) {
createRRequirementsFile(
dir: string,
r: RExecutable | undefined,
saveName?: string,
) {
return this.client.post<void>(
"packages/r/scan",
{ saveName, r },
{ params: { dir } },
{
saveName,
},
{
params: {
dir,
r: r !== undefined ? r.rPath : "",
},
},
);
}
}
46 changes: 46 additions & 0 deletions extensions/vscode/src/api/types/configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { AgentError } from "./error";
import { ConnectConfig } from "./connect";
import { SchemaURL } from "./schema";
import { InterpreterDefaults } from "./interpreters";

export type ConfigurationLocation = {
configurationName: string;
Expand Down Expand Up @@ -176,3 +177,48 @@ export type Group = {
name?: string;
permissions: string;
};

export function UpdateAllConfigsWithDefaults(
configs: (Configuration | ConfigurationError)[],
defaults: InterpreterDefaults,
) {
for (let i = 0; i < configs.length; i++) {
configs[i] = UpdateConfigWithDefaults(configs[i], defaults);
}
return configs;
}

export function UpdateConfigWithDefaults(
config: Configuration | ConfigurationError,
defaults: InterpreterDefaults,
) {
if (isConfigurationError(config)) {
return config;
}

// Fill in empty definitions with the current defaults
// but only if the section is defined (which indicates the dependency)
if (config.configuration.r !== undefined) {
if (config.configuration.r.version === "") {
config.configuration.r.version = defaults.r.version;
}
if (config.configuration.r.packageFile === "") {
config.configuration.r.packageFile = defaults.r.packageFile;
}
if (config.configuration.r.packageManager === "") {
config.configuration.r.packageManager = defaults.r.packageManager;
}
}
if (config.configuration.python !== undefined) {
if (config.configuration.python.version === "") {
config.configuration.python.version = defaults.r.version;
}
if (config.configuration.python.packageFile === "") {
config.configuration.python.packageFile = defaults.r.packageFile;
}
if (config.configuration.python.packageManager === "") {
config.configuration.python.packageManager = defaults.r.packageManager;
}
}
return config;
}
10 changes: 10 additions & 0 deletions extensions/vscode/src/api/types/interpreters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (C) 2025 by Posit Software, PBC.

import { PythonConfig, RConfig } from "./configurations";

export type InterpreterDefaults = {
python: PythonConfig;
preferredPythonPath: string;
r: RConfig;
preferredRPath: string;
};
22 changes: 20 additions & 2 deletions extensions/vscode/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
isContentRecordError,
PreContentRecord,
PreContentRecordWithConfig,
UpdateAllConfigsWithDefaults,
UpdateConfigWithDefaults,
useApi,
} from "src/api";
import { normalizeURL } from "src/utils/url";
Expand All @@ -27,6 +29,7 @@ import {
} from "src/utils/errorTypes";
import { DeploymentSelector, SelectionState } from "src/types/shared";
import { LocalState, Views } from "./constants";
import { getPythonInterpreterPath, getRInterpreterPath } from "./utils/vscode";

function findContentRecord<
T extends ContentRecord | PreContentRecord | PreContentRecordWithConfig,
Expand Down Expand Up @@ -202,11 +205,19 @@ export class PublisherState implements Disposable {
// if not found, then retrieve it and add it to our cache.
try {
const api = await useApi();
const python = await getPythonInterpreterPath();
const r = await getRInterpreterPath();

const response = await api.configurations.get(
contentRecord.configurationName,
contentRecord.projectDir,
);
const cfg = response.data;
const defaults = await api.interpreters.get(
contentRecord.projectDir,
r,
python,
);
const cfg = UpdateConfigWithDefaults(response.data, defaults.data);
// its not foolproof, but it may help
if (!this.findConfig(cfg.configurationName, cfg.projectDir)) {
this.configurations.push(cfg);
Expand Down Expand Up @@ -267,10 +278,17 @@ export class PublisherState implements Disposable {
Views.HomeView,
async () => {
const api = await useApi();
const python = await getPythonInterpreterPath();
const r = await getRInterpreterPath();

const response = await api.configurations.getAll(".", {
recursive: true,
});
this.configurations = response.data;
const defaults = await api.interpreters.get(".", r, python);
this.configurations = UpdateAllConfigsWithDefaults(
response.data,
defaults.data,
);
},
);
} catch (error: unknown) {
Expand Down
18 changes: 18 additions & 0 deletions extensions/vscode/src/types/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,21 @@ export type DeploymentObjects = {
configuration: Configuration;
credential: Credential;
};

export type RExecutable = {
rPath: string;
};
export function NewRExecutable(rPath: string): RExecutable {
return {
rPath,
};
}

export type PythonExecutable = {
pythonPath: string;
};
export function NewPythonExecutable(pythonPath: string): PythonExecutable {
return {
pythonPath,
};
}
Loading

0 comments on commit af8681a

Please sign in to comment.