Skip to content

Commit f2000ff

Browse files
author
Basit Ayantunde
committed
added conda support
update
1 parent b517b48 commit f2000ff

17 files changed

+260
-50
lines changed

src/api/clearlyDefined.js

+12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const BROWSE = 'browse'
1717
export const ORIGINS_GITHUB = 'origins/github'
1818
export const ORIGINS_NPM = 'origins/npm'
1919
export const ORIGINS_NUGET = 'origins/nuget'
20+
export const ORIGINS_CONDA = 'origins/conda'
2021
export const ORIGINS_CRATE = 'origins/crate'
2122
export const ORIGINS_MAVEN = 'origins/maven'
2223
export const ORIGINS_PYPI = 'origins/pypi'
@@ -25,9 +26,12 @@ export const ORIGINS_DEBIAN = 'origins/deb'
2526
export const ORIGINS_COMPOSER = 'origins/composer'
2627
export const ORIGINS_POD = 'origins/pod'
2728
export const ORIGINS = {
29+
"anaconda-main": { conda: ORIGINS_CONDA, condasource: ORIGINS_CONDA },
30+
"anaconda-r": { conda: ORIGINS_CONDA, condasource: ORIGINS_CONDA },
2831
github: { git: ORIGINS_GITHUB },
2932
npmjs: { npm: ORIGINS_NPM },
3033
nuget: { nuget: ORIGINS_NUGET },
34+
"conda-forge": { conda: ORIGINS_CONDA, condasource: ORIGINS_CONDA },
3135
cratesio: { crate: ORIGINS_CRATE },
3236
mavencentral: { maven: ORIGINS_MAVEN, sourcearchive: ORIGINS_MAVEN },
3337
pypi: { pypi: ORIGINS_PYPI },
@@ -188,6 +192,14 @@ export function getRubyGemsRevisions(token, path) {
188192
return get(url(`${ORIGINS_RUBYGEMS}/${path}/revisions`), token)
189193
}
190194

195+
export function getCondaSearch(token, path) {
196+
return get(url(`${ORIGINS_CONDA}/${path}`), token)
197+
}
198+
199+
export function getCondaRevisions(token, path) {
200+
return get(url(`${ORIGINS_CONDA}/${path}/revisions`), token)
201+
}
202+
191203
export function getCrateSearch(token, path) {
192204
return get(url(`${ORIGINS_CRATE}/${path}`), token)
193205
}

src/components/DefinitionEntry.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import git from '../images/Git-Logo-2Color.png'
1111
import npm from '../images/n-large.png'
1212
import pypi from '../images/pypi.png'
1313
import gem from '../images/gem.png'
14+
import conda from '../images/conda.svg'
1415
import cargo from '../images/cargo.png'
1516
import nuget from '../images/nuget.svg'
1617
import debian from '../images/debian.png'
@@ -49,7 +50,7 @@ class DefinitionEntry extends React.Component {
4950
static defaultProps = {}
5051

5152
isSourceComponent(component) {
52-
return ['github', 'sourcearchive', 'debsrc'].includes(component.provider)
53+
return ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider)
5354
}
5455

5556
fieldChange(field, equality = isEqual, transform = a => a) {
@@ -453,6 +454,7 @@ class DefinitionEntry extends React.Component {
453454
getImage(definition) {
454455
if (definition.coordinates.type === 'git') return git
455456
if (definition.coordinates.type === 'npm') return npm
457+
if (definition.coordinates.type === 'conda') return conda
456458
if (definition.coordinates.type === 'crate') return cargo
457459
if (definition.coordinates.type === 'pypi') return pypi
458460
if (definition.coordinates.type === 'gem') return gem

src/components/FilterBar.js

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import maven from '../images/maven.png'
1010
import nuget from '../images/nuget.png'
1111
import pod from '../images/pod.png'
1212
import git from '../images/Git-Logo-2Color.png'
13+
import conda from '../images/conda.svg'
1314
import crate from '../images/cargo.png'
1415
import gem from '../images/gem.png'
1516
import pypi from '../images/pypi.png'
@@ -23,6 +24,7 @@ const types = {
2324
maven: maven,
2425
nuget: nuget,
2526
git: git,
27+
conda: conda,
2628
crate: crate,
2729
pod: pod,
2830
deb: debian,

src/components/HarvestQueueList.js

+19
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
NpmVersionPicker,
1212
MavenVersionPicker,
1313
PyPiVersionPicker,
14+
CondaVersionPicker,
1415
CrateVersionPicker,
1516
DebianVersionPicker,
1617
NuGetVersionPicker,
@@ -25,6 +26,9 @@ import npm from '../images/n-large.png'
2526
import pypi from '../images/pypi.png'
2627
import debian from '../images/debian.png'
2728
import gem from '../images/gem.png'
29+
import anaconda_main from '../images/anaconda-main.svg'
30+
import anaconda_r from '../images/anaconda-r.png'
31+
import conda_forge from '../images/conda-forge.png'
2832
import cargo from '../images/cargo.png'
2933
import maven from '../images/maven.png'
3034
import nuget from '../images/nuget.png'
@@ -84,6 +88,15 @@ class HarvestQueueList extends React.Component {
8488
onChange={this.commitChanged.bind(this, request)}
8589
/>
8690
)}
91+
{request.provider === 'anaconda-main' && (
92+
<CondaVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
93+
)}
94+
{request.provider === 'anaconda-r' && (
95+
<CondaVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
96+
)}
97+
{request.provider === 'cratesio' && (
98+
<CrateVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
99+
)}
87100
{request.provider === 'npmjs' && (
88101
<NpmVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
89102
)}
@@ -96,6 +109,9 @@ class HarvestQueueList extends React.Component {
96109
{request.provider === 'rubygems' && (
97110
<RubyGemsVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
98111
)}
112+
{request.provider === 'conda-forge' && (
113+
<CondaVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
114+
)}
99115
{request.provider === 'cratesio' && (
100116
<CrateVersionPicker request={request} onChange={this.versionChanged.bind(this, request)} />
101117
)}
@@ -150,6 +166,9 @@ class HarvestQueueList extends React.Component {
150166
if (request.provider === 'npmjs') return npm
151167
if (request.provider === 'pypi') return pypi
152168
if (request.provider === 'rubygems') return gem
169+
if (request.provider === 'anaconda-main') return anaconda_main
170+
if (request.provider === 'anaconda-r') return anaconda_r
171+
if (request.provider === 'conda-forge') return conda_forge
153172
if (request.provider === 'cratesio') return cargo
154173
if (request.provider === 'mavencentral') return maven
155174
if (request.provider === 'nuget') return nuget

src/components/Navigation/Pages/PageHarvest/PageHarvest.js

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
NpmSelector,
1313
MavenSelector,
1414
NuGetSelector,
15+
CondaSelector,
1516
CrateSelector,
1617
DebianSelector,
1718
ComposerSelector,
@@ -114,11 +115,14 @@ class PageHarvest extends Component {
114115
<Row className="show-grid">
115116
<Col md={6}>{this.renderProviderButtons()}</Col>
116117
<Col md={4}>
118+
{activeProvider.value === 'anaconda-main' && <CondaSelector provider='anaconda-main' onChange={this.onAddRequest} />}
119+
{activeProvider.value === 'anaconda-r' && <CondaSelector provider='anaconda-r' onChange={this.onAddRequest} />}
117120
{activeProvider.value === 'github' && <GitHubSelector onChange={this.onAddRequest} />}
118121
{activeProvider.value === 'mavencentral' && <MavenSelector onChange={this.onAddRequest} />}
119122
{activeProvider.value === 'npmjs' && <NpmSelector onChange={this.onAddRequest} />}
120123
{activeProvider.value === 'nuget' && <NuGetSelector onChange={this.onAddRequest} />}
121124
{activeProvider.value === 'cratesio' && <CrateSelector onChange={this.onAddRequest} />}
125+
{activeProvider.value === 'conda-forge' && <CondaSelector provider='conda-forge' onChange={this.onAddRequest} />}
122126
{activeProvider.value === 'packagist' && <ComposerSelector onChange={this.onAddRequest} />}
123127
{activeProvider.value === 'pypi' && <PyPiSelector onChange={this.onAddRequest} />}
124128
{activeProvider.value === 'rubygems' && <RubyGemsSelector onChange={this.onAddRequest} />}

src/components/Navigation/Pages/PageStats/PageStats.js

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import maven from '../../../../images/maven.png'
1313
import nuget from '../../../../images/nuget.png'
1414
import pod from '../../../../images/pod.png'
1515
import git from '../../../../images/Git-Logo-2Color.png'
16+
import conda from '../../../../images/conda.svg'
1617
import crate from '../../../../images/cargo.png'
1718
import composer from '../../../../images/packagist.png'
1819
import gem from '../../../../images/gem.png'
@@ -34,6 +35,8 @@ const types = {
3435
maven: maven,
3536
nuget: nuget,
3637
git: git,
38+
conda: conda,
39+
condasource: conda,
3740
crate: crate,
3841
deb: debian,
3942
debsrc: debian,

src/components/Navigation/Ui/ComponentButtons.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ComponentButtons extends Component {
3232
}
3333

3434
isSourceComponent(component) {
35-
return ['github', 'sourcearchive', 'debsrc'].includes(component.provider)
35+
return ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider)
3636
}
3737

3838
_isProviderSupported(component) {
@@ -152,7 +152,7 @@ class ComponentButtons extends Component {
152152
)}
153153
{!isDefinitionEmpty && onInspect && (
154154
<ButtonWithTooltip tip="Dig into this definition">
155-
<Button className="list-fa-button" onClick={this.inspectComponent.bind(this, currentComponent, definition)}>
155+
<Button className="list-fa-button" onClick={this.inspectComponent.bind(this, currentComponent, definition)}>
156156
<i className="fas fa-search" />
157157
</Button>
158158
</ButtonWithTooltip>

src/components/Navigation/Ui/ComponentDetailsButtons.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ComponentDetailsButtons extends Component {
1414
}
1515

1616
isSourceComponent(component) {
17-
return ['github', 'sourcearchive', 'debsrc'].includes(component.provider)
17+
return ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider)
1818
}
1919

2020
openSourceForComponent = definition => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) Microsoft Corporation and others. Licensed under the MIT license.
2+
// SPDX-License-Identifier: MIT
3+
4+
import React, { Component } from 'react'
5+
import PropTypes from 'prop-types'
6+
import { getCondaSearch } from '../../../api/clearlyDefined'
7+
import { AsyncTypeahead } from 'react-bootstrap-typeahead'
8+
import searchSvg from '../../../images/icons/searchSvg.svg'
9+
10+
export default class CondaSelector extends Component {
11+
static propTypes = {
12+
onChange: PropTypes.func
13+
}
14+
15+
constructor(props) {
16+
super(props)
17+
this.state = { isLoading: false, options: [], focus: false }
18+
this.getOptions = this.getOptions.bind(this)
19+
this.onChange = this.onChange.bind(this)
20+
}
21+
22+
onChange(values) {
23+
const { onChange } = this.props
24+
const value = values.length === 0 ? null : values[0]
25+
value && onChange && onChange({ type: 'conda', provider: this.props.provider, name: value.id }, 'package')
26+
}
27+
28+
async getOptions(value) {
29+
try {
30+
this.setState({ ...this.state, isLoading: true })
31+
console.log(`value: ${value}, provider: ${this.props.provider}`)
32+
const options = await getCondaSearch(this.props.token, `${value}/${this.props.provider}`)
33+
this.setState({ ...this.state, options, isLoading: false })
34+
} catch (error) {
35+
this.setState({ ...this.state, options: [], isLoading: false })
36+
}
37+
}
38+
39+
render() {
40+
const { options, isLoading, focus } = this.state
41+
return (
42+
<div className={`harvest-searchbar ${focus ? 'active' : ''}`}>
43+
<div className="search-logo">
44+
<img src={searchSvg} alt="search" />
45+
</div>
46+
<AsyncTypeahead
47+
id="conda-selector"
48+
className="harvest-search"
49+
useCache={false}
50+
options={options}
51+
placeholder={'Pick a Conda Package to harvest'}
52+
onChange={this.onChange}
53+
labelKey="id"
54+
onFocus={() => this.setState({ ...this.state, focus: true })}
55+
onBlur={() => this.setState({ ...this.state, focus: false })}
56+
clearButton
57+
highlightOnlyResult
58+
emptyLabel=""
59+
selectHintOnEnter
60+
isLoading={isLoading}
61+
onSearch={this.getOptions}
62+
/>
63+
</div>
64+
)
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) Microsoft Corporation and others. Licensed under the MIT license.
2+
// SPDX-License-Identifier: MIT
3+
4+
import React, { Component } from 'react'
5+
import PropTypes from 'prop-types'
6+
import { getCondaRevisions } from '../../../api/clearlyDefined'
7+
import Autocomplete from '../../Navigation/Ui/Autocomplete'
8+
9+
export default class CondaVersionPicker extends Component {
10+
static propTypes = {
11+
onChange: PropTypes.func,
12+
request: PropTypes.object.isRequired,
13+
defaultInputValue: PropTypes.string
14+
}
15+
16+
constructor(props) {
17+
super(props)
18+
this.state = { customValues: [], options: [] }
19+
this.onChange = this.onChange.bind(this)
20+
this.filter = this.filter.bind(this)
21+
}
22+
23+
componentDidMount() {
24+
this.getOptions('')
25+
}
26+
27+
async getOptions(value) {
28+
try {
29+
const { name, provider } = this.props.request
30+
const options = await getCondaRevisions(this.props.token, `${name}/${provider}`)
31+
this.setState({ ...this.state, options })
32+
} catch (error) {
33+
this.setState({ ...this.state, options: [] })
34+
}
35+
}
36+
37+
onChange(values) {
38+
const { onChange } = this.props
39+
if (!onChange) return
40+
let value = values.length === 0 ? null : values[0]
41+
if (!value) return onChange(value)
42+
if (value.customOption) {
43+
value = value.label
44+
this.setState({ ...this.state, customValues: [...this.state.customValues, value] })
45+
}
46+
onChange(value)
47+
}
48+
49+
filter(option, props) {
50+
if (this.props.request.revision) return true
51+
return option.toLowerCase().indexOf(props.text.toLowerCase()) !== -1
52+
}
53+
54+
render() {
55+
const { defaultInputValue } = this.props
56+
const { customValues, options } = this.state
57+
const list = customValues.concat(options)
58+
return (
59+
<Autocomplete
60+
id="conda-version-picker"
61+
options={list}
62+
defaultInputValue={defaultInputValue}
63+
placeholder={options.length === 0 ? 'Could not fetch versions, type a Conda version' : 'Pick a Conda version'}
64+
onChange={this.onChange}
65+
bodyContainer
66+
clearButton
67+
allowNew
68+
newSelectionPrefix="Version:"
69+
emptyLabel=""
70+
filterBy={this.filter}
71+
selectHintOnEnter
72+
/>
73+
)
74+
}
75+
}

0 commit comments

Comments
 (0)