Skip to content

Commit

Permalink
feat: find pck manager
Browse files Browse the repository at this point in the history
  • Loading branch information
musdotdigital committed Nov 30, 2023
1 parent 30e74f2 commit cf748d2
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 49 deletions.
16 changes: 0 additions & 16 deletions __tests__/dockerfile.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {test, expect} from '@jest/globals'
import * as path from 'path'
import {load} from '../src/dockerfile'
import {AlpineImage, DebImage} from '../src/image'

test('load invalid dockerfile', () => {
let dockerfilePath = path.join(__dirname, 'data', 'InvalidDockerfile')
Expand All @@ -14,20 +13,5 @@ test('load invalid dockerfile', () => {
test('load alpine dockerfile', () => {
const dockerfilePath = path.join(__dirname, 'data', 'Dockerfile')
const dockerfile = load(dockerfilePath)
expect(dockerfile).toBeInstanceOf(AlpineImage)
expect(dockerfile.name).toBe('alpine:latest')
})

test('load debian dockerfile', () => {
const dockerfilePath = path.join(__dirname, 'data', 'debianDockerfile')
const dockerfile = load(dockerfilePath)
expect(dockerfile).toBeInstanceOf(DebImage)
expect(dockerfile.name).toBe('debian:bullseye-slim')
})

test('load cuda dockerfile', () => {
const dockerfilePath = path.join(__dirname, 'data', 'cudaDockerfile')
const dockerfile = load(dockerfilePath)
expect(dockerfile).toBeInstanceOf(DebImage)
expect(dockerfile.name).toBe('nvidia/cuda:11.8.0-runtime-ubuntu22.04')
})
2 changes: 1 addition & 1 deletion __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as process from 'process'
import * as cp from 'child_process'
import * as path from 'path'
import {test, expect} from '@jest/globals'
import {test} from '@jest/globals'

// shows how the runner will run a javascript action with env / stdout protocol
test('test runs', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/dockerfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function extract_docker_image(dockerfile_content: string): image.Image {
imageName = line.split(' ')[1].trim()
}
if (line.includes('apk add') || line.includes('apt-get install')) {
return image.factory(imageName)
return new image.Image(imageName)
}
}
throw Error('Unable to extract image from Dockerfile')
Expand Down
62 changes: 31 additions & 31 deletions src/image.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import {Docker, Options} from 'docker-cli-js'
import {Package} from './dependencies'

export type PackageManager = 'apk' | 'apt-get'

export class Image {
name: string
pkgManager: PackageManager | null
docker: Docker

constructor(name: string) {
this.name = name
this.pkgManager = null
const options = new Options(
undefined,
undefined,
Expand All @@ -17,28 +21,38 @@ export class Image {
this.docker = new Docker(options)
}

async get_latest_version(installed_package: Package): Promise<Package> {
throw Error(
`Not implemented can't get latest version of ${installed_package}`
)
async init_package_manager(): Promise<void> {
try {
await this.docker.command(`run ${this.name} sh -c "apk --version > /dev/null"`)
this.pkgManager = "apk"
} catch (error) {
this.pkgManager = "apt-get"
}
}
}

export class AlpineImage extends Image {
async get_latest_version(installed_package: Package): Promise<Package> {
const response = await this.docker.command(
`run ${this.name} sh -c "apk update > /dev/null && apk info ${installed_package.name}"`
)
const updated_version = remove_prefix(
response.raw.split(' ')[0],
`${installed_package.name}-`
)
return {...installed_package, version: updated_version}
switch (this.pkgManager) {
case "apk":
return this.get_latest_version_apk(installed_package)
case "apt-get":
return this.get_latest_version_apt(installed_package)
default:
throw Error('Unable to get package manager')
}
}
}

export class DebImage extends Image {
async get_latest_version(installed_package: Package): Promise<Package> {
async get_latest_version_apk(installed_package: Package): Promise<Package> {
const response = await this.docker.command(
`run ${this.name} sh -c "apk update > /dev/null && apk info ${installed_package.name}"`
)
const updated_version = remove_prefix(
response.raw.split(' ')[0],
`${installed_package.name}-`
)
return {...installed_package, version: updated_version}
}

async get_latest_version_apt(installed_package: Package): Promise<Package> {
const response = await this.docker.command(
`run ${this.name} sh -c "apt-get update > /dev/null && apt-cache policy ${installed_package.name}"`
)
Expand All @@ -57,20 +71,6 @@ export class DebImage extends Image {
}
}

export function factory(name: string): Image {
if (name.includes('alpine')) {
return new AlpineImage(name)
}
if (
name.includes('debian') ||
name.includes('bulleye') ||
name.includes('buster') ||
name.includes('ubuntu')
) {
return new DebImage(name)
}
throw Error('Unsupported image type')
}

function remove_prefix(text: string, prefix: string): string {
if (text.startsWith(prefix)) {
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ async function run(): Promise<void> {
const apply = core.getBooleanInput('apply')

const image = dockerfile.load(dockerfile_path)
await image.init_package_manager()

const dependencies_info = dependencies.load(dependencies_path)
const packages_update = dependencies_info.map(async function (
installed_pkg
Expand Down

0 comments on commit cf748d2

Please sign in to comment.