import { Project } from "@atomist/automation-client"; import { AutoCodeInspection, Autofix, AutofixRegistration, AutoInspectRegistration, Goal, SdmContext } from "@atomist/sdm"; import { Interpretation, Interpreter } from "./Interpretation"; import { ManagedFeature } from "./ManagedFeature"; import { HasAnalysis, ProjectAnalysis, ProjectAnalysisOptions, TechnologyElement } from "./ProjectAnalysis"; import { Score } from "./Score"; import { FastProject, PhasedTechnologyScanner, ScannerAction, TechnologyClassification, TechnologyScanner } from "./TechnologyScanner"; import { TransformRecipeContributionRegistration } from "./TransformRecipeContributor"; /** * When an action should be run */ export declare type RunCondition = (options: ProjectAnalysisOptions | ProjectAnalysisOptions & HasAnalysis, sdmContext: SdmContext) => boolean; /** * Registration of a TechnologyScanner, Interpreter etc that should run conditionally * depending on analysis options and SdmContext. */ export interface ConditionalRegistration { /** * Action we are registering, such as a TechnologyScanner or Interpreter */ action: W; /** * Test for when this action should run, * depending on analysis options and the current SDM context * (allowing for feature flagging). * Default is always run. * @param {ProjectAnalysisOptions} options * @return {boolean} */ runWhen: RunCondition; } export declare function hasAnalysis(a: any): a is HasAnalysis; export declare function isConditionalRegistration(a: any): a is ConditionalRegistration; export declare type Scorer = (i: Interpretation, ctx: SdmContext) => Promise; /** * Result of classifying the project quickly to determine its nature. */ export interface Classification { elements: Record; } /** * Type with ability to analyze individual projects and determine their delivery. * We use a fixed set of goals created ahead of time with function implementations * that are parameterized based on analyzing and interpreting the project on push. */ export interface ProjectAnalyzer { /** * Classify this project. The implementations should be faster than delivery steps of interpretation and analysis. * Allows a project to be classified quickly to determine the relevance of this SDM to handling it. */ classify(p: FastProject, sdmContext: SdmContext): Promise; /** * Analyze the given project. Analysis will always be in sufficient detail to back delivery. * If options are provided and specify a full analysis, go deeper. */ analyze(p: Project, sdmContext: SdmContext, options?: ProjectAnalysisOptions): Promise; /** * Interpret the project, analyzing it first if necessary */ interpret(p: Project | ProjectAnalysis, sdmContext: SdmContext, options?: ProjectAnalysisOptions): Promise; readonly interpreters: Array>; readonly scanners: Array>>; /** * All features registered anywhere */ readonly features: ManagedFeature[]; readonly scorers: Array>; readonly possibleAutofixes: AutofixRegistration[]; readonly possibleCodeInspections: Array>; readonly autofixGoal: Autofix; readonly codeInspectionGoal: AutoCodeInspection; readonly messageGoal: Goal; } /** * Integrated support for a new stack. * At least one scanner is always required. * Interpreters are optional, as are * any number of transform recipe contributors to * facilitate use as a seed project. */ export interface StackSupport { /** * Scanner or scanners that identify the new stack. Necessary to drive * any Interpreters, TransformRecipeContributors or Scorers. */ scanners: Array | ConditionalRegistration> | PhasedTechnologyScanner | ConditionalRegistration>>; interpreters: Array>; /** * Return the features that can be managed in this project */ features?: ManagedFeature[]; scorers?: Array>; transformRecipeContributors: TransformRecipeContributionRegistration[]; /** * If this is set, it will conditionalize all registrations except those with their own explicit conditions. */ condition?: RunCondition; } /** * Fluent builder interface we can use to build an immutable ProjectAnalyzer */ export interface ProjectAnalyzerBuilder { /** * Add a scanner that can discern a technology stack. * Ordering is important. Later analyzers can see the work * of previous analyzers. This ensure that expensive parsing * can be done only once. */ withScanner(scanner: ScannerAction | ConditionalRegistration>): ProjectAnalyzerBuilder; /** * Add a feature */ withFeature(feature: ManagedFeature): ProjectAnalyzerBuilder; withFeatures(features: ManagedFeature[]): ProjectAnalyzerBuilder; /** * Add an interpreter that can interpret the analysis. * Ordering is important, as interpreters registered later * can choose to stand down if relevant goals have already been * computed by higher priority interpreters. * @param {Interpreter} interpreter * @return {ProjectAnalyzerBuilder} */ withInterpreter(interpreter: Interpreter | ConditionalRegistration): ProjectAnalyzerBuilder; /** * Add a scorer to this analyzer */ withScorer(scorer: Scorer | ConditionalRegistration): ProjectAnalyzerBuilder; /** * Add a contributor that can analyze this project as a potential seed * @param {TransformRecipeContributionRegistration} trc * @return {ProjectAnalyzerBuilder} */ withTransformRecipeContributor(trc: TransformRecipeContributionRegistration): ProjectAnalyzerBuilder; /** * Add support for a new stack */ withStack(stackSupport: StackSupport): this; /** * Create a ProjectAnalyzer instance * @return {ProjectAnalyzer} */ build(): ProjectAnalyzer; }