Skip to content

Commit

Permalink
feat(ui): plugins update
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume Chau committed Mar 16, 2018
1 parent 1441c02 commit 7571e80
Show file tree
Hide file tree
Showing 15 changed files with 267 additions and 85 deletions.
1 change: 1 addition & 0 deletions packages/@vue/cli-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"lru-cache": "^4.1.2",
"mkdirp": "^0.5.1",
"rimraf": "^2.6.2",
"semver": "^5.5.0",
"shortid": "^2.2.8",
"subscriptions-transport-ws": "^0.9.5",
"vue": "^2.5.13",
Expand Down
38 changes: 28 additions & 10 deletions packages/@vue/cli-ui/src/components/ContentView.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<template>
<div class="content-view">
<div class="header">
<h2 v-if="title" class="title">{{ title }}</h2>
<slot name="header"/>
<div class="wrapper">
<h2 v-if="title" class="title">{{ title }}</h2>
<slot name="header"/>
</div>
</div>

<div class="content">
<slot/>
<div class="wrapper">
<slot/>
</div>
</div>
</div>
</template>
Expand All @@ -32,12 +36,19 @@ export default {
grid-template-rows auto 1fr
grid-template-areas "header" "content"
.wrapper
width 100%
height 100%
box-sizing border-box
.header
grid-area header
h-box()
box-center()
background $vue-ui-color-light-neutral
padding $padding-item
background darken($vue-ui-color-light-neutral, 3%)
.wrapper
background $vue-ui-color-light-neutral
h-box()
box-center()
padding $padding-item
.title
flex 100% 1 1
Expand All @@ -49,7 +60,14 @@ export default {
.content
grid-area content
position relative
overflow-x hidden
overflow-y auto
background darken($color-light-background, 3%)
.wrapper
background $color-light-background
position relative
overflow-x hidden
overflow-y auto
&.limit-width
.wrapper
max-width 1200px
</style>
147 changes: 106 additions & 41 deletions packages/@vue/cli-ui/src/components/ProjectPluginItem.vue
Original file line number Diff line number Diff line change
@@ -1,59 +1,122 @@
<template>
<div class="project-plugin-item list-item">
<ItemLogo :image="plugin.logo"/>

<ListItemInfo
:name="plugin.id"
:link="plugin.website"
show-description
>
<span slot="description" class="plugin-description">
<span class="info version">
<span class="label">{{ $t('components.project-plugin-item.version') }}</span>
<span class="value">{{ plugin.version.current }}</span>
</span>
<div class="content">
<ItemLogo :image="pluginLogo && pluginLogo.logo"/>

<span class="info latest">
<span class="label">{{ $t('components.project-plugin-item.latest') }}</span>
<VueIcon
v-if="plugin.version.current !== plugin.version.latest"
icon="warning"
class="top medium"
/>
<span class="value">{{ plugin.version.latest }}</span>
</span>
<ListItemInfo
:name="plugin.id"
:link="plugin.website"
show-description
>
<span slot="description" class="plugin-description">
<template v-if="pluginDetails">
<span class="info version">
<span class="label">{{ $t('components.project-plugin-item.version') }}</span>
<span class="value">{{ pluginDetails.version.current }}</span>
</span>

<span v-if="plugin.official" class="info">
<VueIcon
icon="star"
class="top medium"
/>
{{ $t('components.project-plugin-item.official') }}
</span>
<span class="info latest">
<span class="label">{{ $t('components.project-plugin-item.latest') }}</span>
<VueIcon
v-if="pluginDetails.version.current !== pluginDetails.version.latest"
icon="warning"
class="top medium"
/>
<span class="value">{{ pluginDetails.version.latest }}</span>
</span>
</template>

<span v-if="plugin.installed" class="info">
<VueIcon
icon="check_circle"
class="top medium"
/>
{{ $t('components.project-plugin-item.installed') }}
</span>
<span v-if="plugin.official" class="info">
<VueIcon
icon="star"
class="top medium"
/>
{{ $t('components.project-plugin-item.official') }}
</span>

<span v-if="plugin.description" class="package-description">
{{ plugin.description }}
<span v-if="plugin.installed" class="info">
<VueIcon
icon="check_circle"
class="top medium"
/>
{{ $t('components.project-plugin-item.installed') }}
</span>

<span v-if="pluginDetails && pluginDetails.description" class="package-description">
{{ pluginDetails.description }}
</span>
</span>
</span>
</ListItemInfo>
</ListItemInfo>

<VueButton
v-if="pluginDetails && pluginDetails.version.current !== pluginDetails.version.wanted"
icon-left="file_download"
class="icon-button"
v-tooltip="$t('components.project-plugin-item.actions.update', { target: plugin.id })"
:loading-left="updating"
@click="updatePlugin()"
/>
</div>
</div>
</template>

<script>
import PLUGIN_DETAILS from '../graphql/pluginDetails.gql'
import PLUGIN_LOGO from '../graphql/pluginLogo.gql'
import PLUGIN_UPDATE from '../graphql/pluginUpdate.gql'
export default {
props: {
plugin: {
type: Object,
required: true
}
},
data () {
return {
pluginDetails: null,
pluginLogo:! null,
updating: false
}
},
apollo: {
pluginDetails: {
query: PLUGIN_DETAILS,
variables () {
return {
id: this.plugin.id
}
},
fetchPolicy: 'cache-and-network'
},
pluginLogo: {
query: PLUGIN_LOGO,
variables () {
return {
id: this.plugin.id
}
}
}
},
methods: {
async updatePlugin () {
this.updating = true
try {
this.$apollo.mutate({
mutation: PLUGIN_UPDATE,
variables: {
id: this.plugin.id
}
})
} catch (e) {
console.error(e)
}
this.updating = false
}
}
}
</script>
Expand All @@ -63,8 +126,10 @@ export default {
.project-plugin-item
padding $padding-item
h-box()
box-center()
.content
h-box()
box-center()
.list-item-info
flex 100% 1 1
Expand Down
76 changes: 55 additions & 21 deletions packages/@vue/cli-ui/src/graphql-api/connectors/plugins.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const path = require('path')
const fs = require('fs')
const LRU = require('lru-cache')
const semver = require('semver')
const {
isPlugin,
isOfficialPlugin,
Expand All @@ -11,7 +12,8 @@ const getPackageVersion = require('@vue/cli/lib/util/getPackageVersion')
const {
progress: installProgress,
installPackage,
uninstallPackage
uninstallPackage,
updatePackage
} = require('@vue/cli/lib/util/installDeps')
const { loadOptions } = require('@vue/cli/lib/options')
const invoke = require('@vue/cli/lib/invoke')
Expand All @@ -20,6 +22,7 @@ const cwd = require('./cwd')
const folders = require('./folders')
const prompts = require('./prompts')
const progress = require('./progress')
const logs = require('./logs')

const metadataCache = new LRU({
max: 200,
Expand All @@ -34,9 +37,12 @@ const PROGRESS_ID = 'plugin-installation'

let currentPluginId
let eventsInstalled = false
let plugins = []

function getPath (id) {
return path.join(cwd.get(), 'node_modules', id)
return path.dirname(require.resolve(id, {
paths: [cwd.get()]
}))
}

function findPlugins (deps) {
Expand All @@ -55,12 +61,18 @@ function findPlugins (deps) {

function list (file, context) {
const pkg = folders.readPackage(file, context)
let plugins = []
plugins = []
plugins = plugins.concat(findPlugins(pkg.dependencies || {}))
plugins = plugins.concat(findPlugins(pkg.devDependencies || {}))
return plugins
}

function findOne (id, context) {
return plugins.find(
p => p.id === id
)
}

function readPackage (id, context) {
return folders.readPackage(getPath(id), context)
}
Expand All @@ -70,18 +82,10 @@ async function getMetadata (id, context) {
if (metadata) {
return metadata
}
if (isOfficialPlugin(id)) {
const res = await getPackageVersion('vue-cli-version-marker', 'latest')
if (res.statusCode === 200) {
metadata = res.body
}
const pkg = folders.readPackage(path.dirname(require.resolve(id)), context)
metadata.description = pkg.description
} else {
const res = await getPackageVersion(id, id.indexOf('@') === -1 ? 'latest' : '')
if (res.statusCode === 200) {
metadata = res.body
}

const res = await getPackageVersion(id)
if (res.statusCode === 200) {
metadata = res.body
}

if (metadata) {
Expand All @@ -98,20 +102,22 @@ async function getVersion ({ id, installed, versionRange }, context) {
} else {
current = null
}
let latest
let latest, wanted
const metadata = await getMetadata(id, context)
if (metadata) {
latest = (metadata['dist-tags'] && metadata['dist-tags'].latest) || metadata.version
}
latest = metadata['dist-tags'].latest

if (!latest) {
// fallback to local version
latest = current
const versions = Object.keys(metadata.versions)
wanted = semver.maxSatisfying(versions, versionRange)
}

if (!latest) latest = current
if (!wanted) wanted = current

return {
current,
latest,
wanted,
range: versionRange
}
}
Expand Down Expand Up @@ -230,13 +236,41 @@ async function initPrompts (id, context) {
prompts.start()
}

function update (id, context) {
return progress.wrap('plugin-update', context, async setProgress => {
setProgress({
status: 'plugin-update',
args: [id]
})

currentPluginId = id

const plugin = findOne(id, context)
const { current, wanted } = await getVersion(plugin, context)

const packageManager = loadOptions().packageManager || (hasYarn() ? 'yarn' : 'npm')
await updatePackage(cwd.get(), packageManager, null, id)

logs.add({
message: `Plugin ${id} updated from ${current} to ${wanted}`,
type: 'info'
}, context)

currentPluginId = null

return findOne(id)
})
}

module.exports = {
list,
findOne,
getVersion,
getDescription,
getLogo,
getInstallation,
install,
uninstall,
update,
runInvoke
}
Loading

0 comments on commit 7571e80

Please sign in to comment.